diff --git a/artiq/compiler/transforms/llvm_ir_generator.py b/artiq/compiler/transforms/llvm_ir_generator.py index d853bad65..b2c67875e 100644 --- a/artiq/compiler/transforms/llvm_ir_generator.py +++ b/artiq/compiler/transforms/llvm_ir_generator.py @@ -450,7 +450,7 @@ class LLVMIRGenerator: lldatalayout = llvm.create_target_data(self.llmodule.data_layout) llrpcattrty = self.llcontext.get_identified_type("A") - llrpcattrty.elements = [lli32, lli32, llptr, llptr] + llrpcattrty.elements = [lli32, llptr, llptr] lldescty = self.llcontext.get_identified_type("D") lldescty.elements = [llrpcattrty.as_pointer().as_pointer(), llptr.as_pointer()] @@ -465,12 +465,7 @@ class LLVMIRGenerator: else: type_name = "I.{}".format(typ.name) - def llrpcattr_of_attr(name, typ): - size = self.llty_of_type(typ). \ - get_abi_size(lldatalayout, context=self.llcontext) - alignment = self.llty_of_type(typ). \ - get_abi_alignment(lldatalayout, context=self.llcontext) - + def llrpcattr_of_attr(offset, name, typ): def rpc_tag_error(typ): print(typ) assert False @@ -483,8 +478,7 @@ class LLVMIRGenerator: llrpctag = ll.Constant(llptr, None) llrpcattrinit = ll.Constant(llrpcattrty, [ - ll.Constant(lli32, size), - ll.Constant(lli32, alignment), + ll.Constant(lli32, offset), llrpctag, self.llstr_of_str(name) ]) @@ -501,8 +495,27 @@ class LLVMIRGenerator: return llrpcattr - llrpcattrs = [llrpcattr_of_attr(attr, typ.attributes[attr]) - for attr in typ.attributes] + offset = 0 + llrpcattrs = [] + for attr in typ.attributes: + attrtyp = typ.attributes[attr] + size = self.llty_of_type(attrtyp). \ + get_abi_size(lldatalayout, context=self.llcontext) + alignment = self.llty_of_type(attrtyp). \ + get_abi_alignment(lldatalayout, context=self.llcontext) + + if offset % alignment != 0: + offset += alignment - (offset % alignment) + + if types.is_instance(typ) and attr not in typ.constant_attributes: + llrpcattrs.append(llrpcattr_of_attr(offset, attr, attrtyp)) + + offset += size + + if len(llrpcattrs) == 1: + # Don't bother serializing objects that only have __objectid__ + # since there's nothing to writeback anyway. + continue llrpcattraryty = ll.ArrayType(llrpcattrty.as_pointer(), len(llrpcattrs) + 1) llrpcattrary = ll.GlobalVariable(self.llmodule, llrpcattraryty, diff --git a/artiq/runtime/ksupport.c b/artiq/runtime/ksupport.c index 54f9213f7..a3421c528 100644 --- a/artiq/runtime/ksupport.c +++ b/artiq/runtime/ksupport.c @@ -411,8 +411,7 @@ int recv_rpc(void *slot) { } struct attr_desc { - uint32_t size; - uint32_t alignment; + uint32_t offset; const char *tag; const char *name; }; @@ -435,20 +434,14 @@ void attribute_writeback(void *utypes) { while(*objects) { void *object = *objects++; - size_t offset = 0; struct attr_desc **attrs = type->attributes; while(*attrs) { struct attr_desc *attr = *attrs++; - if(offset % attr->alignment != 0) - offset += attr->alignment - (offset % attr->alignment); - if(attr->tag) { - uintptr_t value = (uintptr_t)object + offset; + uintptr_t value = (uintptr_t)object + attr->offset; send_rpc(0, attr->tag, &object, &attr->name, value); } - - offset += attr->size; } } }