mirror of https://github.com/m-labs/artiq.git
Remove selective attribute writeback; always synchronize all attributes.
The reasons are: 1. Shadow memory manipulation added ~12 instructions to TTLOut.pulse (without inlining), and it's already barely fast enough. 2. More importantly, code such as self.ts[1] did not trigger attribute writeback, and there seems to be no easy way to fix that.
This commit is contained in:
parent
e41b9db787
commit
81427af506
|
@ -418,17 +418,9 @@ class LLVMIRGenerator:
|
|||
return self.llmodule
|
||||
|
||||
def emit_attribute_writeback(self):
|
||||
llobjects = []
|
||||
shadow_memory_dim = defaultdict(lambda: 0)
|
||||
llobjects = defaultdict(lambda: [])
|
||||
|
||||
for obj_id in self.object_map:
|
||||
while len(llobjects) <= obj_id:
|
||||
llobjects.append(ll.Constant(llptr, None))
|
||||
|
||||
llobject = self.llmodule.get_global("object.{}".format(obj_id))
|
||||
if llobject is not None:
|
||||
llobjects[obj_id] = llobject.bitcast(llptr)
|
||||
|
||||
obj_ref = self.object_map.retrieve(obj_id)
|
||||
if isinstance(obj_ref, (pytypes.FunctionType, pytypes.MethodType)):
|
||||
continue
|
||||
|
@ -437,19 +429,20 @@ class LLVMIRGenerator:
|
|||
else:
|
||||
typ, _ = self.type_map[type(obj_ref)]
|
||||
|
||||
if shadow_memory_dim[typ] <= obj_id:
|
||||
shadow_memory_dim[typ] = obj_id + 1
|
||||
llobject = self.llmodule.get_global("object.{}".format(obj_id))
|
||||
if llobject is not None:
|
||||
llobjects[typ].append(llobject.bitcast(llptr))
|
||||
|
||||
lldatalayout = llvm.create_target_data(self.llmodule.data_layout)
|
||||
|
||||
llrpcattrty = self.llcontext.get_identified_type("shadow.attr")
|
||||
llrpcattrty = self.llcontext.get_identified_type("attr_desc")
|
||||
llrpcattrty.elements = [lli32, llptr, llptr]
|
||||
|
||||
lldescty = self.llcontext.get_identified_type("shadow.desc")
|
||||
lldescty.elements = [llrpcattrty.as_pointer().as_pointer(), lli32, llptr]
|
||||
lldescty = self.llcontext.get_identified_type("type_desc")
|
||||
lldescty.elements = [llrpcattrty.as_pointer().as_pointer(), llptr.as_pointer()]
|
||||
|
||||
lldescs = []
|
||||
for typ in shadow_memory_dim:
|
||||
for typ in llobjects:
|
||||
if "__objectid__" not in typ.attributes:
|
||||
continue
|
||||
|
||||
|
@ -458,44 +451,25 @@ class LLVMIRGenerator:
|
|||
else:
|
||||
type_name = "instance.{}".format(typ.name)
|
||||
|
||||
shadowname = "shadow.{}".format(type_name)
|
||||
llshadow = self.llmodule.get_global(shadowname)
|
||||
if llshadow is None:
|
||||
continue
|
||||
|
||||
llshadowlen = shadow_memory_dim[typ] * len(typ.attributes)
|
||||
llshadowty = ll.ArrayType(lli8, llshadowlen)
|
||||
llshadow.gtype = llshadowty
|
||||
llshadow.type = llshadowty.as_pointer()
|
||||
llshadow.initializer = ll.Constant(llshadowty, None)
|
||||
|
||||
def llrpcattr_of_attr(name, typ):
|
||||
llty = self.llty_of_type(typ)
|
||||
if isinstance(llty, ll.PointerType):
|
||||
# Work around llvmlite bug where it is unable to get a C++
|
||||
# object for a type if it includes an identified type in a context
|
||||
# other than the default.
|
||||
size = llptr.get_abi_size(lldatalayout)
|
||||
else:
|
||||
size = llty.get_abi_size(lldatalayout)
|
||||
size = self.llty_of_type(typ).get_abi_size(lldatalayout, context=self.llcontext)
|
||||
|
||||
def rpc_tag_error(typ):
|
||||
print(typ)
|
||||
assert False
|
||||
|
||||
rpctag = b"Os"
|
||||
if not (types.is_function(typ) or types.is_method(typ)):
|
||||
rpctag += self._rpc_tag(typ, error_handler=rpc_tag_error)
|
||||
else:
|
||||
rpctag += b""
|
||||
rpctag += b":n\x00"
|
||||
if not (types.is_function(typ) or types.is_method(typ) or
|
||||
name == "__objectid__"):
|
||||
rpctag = b"Os" + self._rpc_tag(typ, error_handler=rpc_tag_error) + b":n\x00"
|
||||
llrpctag = self.llstr_of_str(rpctag)
|
||||
else:
|
||||
llrpctag = ll.Constant(llptr, None)
|
||||
|
||||
llrpcattr = ll.GlobalVariable(self.llmodule, llrpcattrty,
|
||||
name="shadow.attr.{}.{}".format(type_name, name))
|
||||
name="attr.{}.{}".format(type_name, name))
|
||||
llrpcattr.initializer = ll.Constant(llrpcattrty, [
|
||||
ll.Constant(lli32, size),
|
||||
self.llstr_of_str(rpctag),
|
||||
llrpctag,
|
||||
self.llstr_of_str(name)
|
||||
])
|
||||
llrpcattr.global_constant = True
|
||||
|
@ -509,33 +483,36 @@ class LLVMIRGenerator:
|
|||
|
||||
llrpcattraryty = ll.ArrayType(llrpcattrty.as_pointer(), len(llrpcattrs) + 1)
|
||||
llrpcattrary = ll.GlobalVariable(self.llmodule, llrpcattraryty,
|
||||
name="shadow.attrs.{}".format(type_name))
|
||||
name="attrs.{}".format(type_name))
|
||||
llrpcattrary.initializer = ll.Constant(llrpcattraryty,
|
||||
llrpcattrs + [ll.Constant(llrpcattrty.as_pointer(), None)])
|
||||
llrpcattrary.global_constant = True
|
||||
llrpcattrary.unnamed_addr = True
|
||||
llrpcattrary.linkage = 'internal'
|
||||
|
||||
llobjectaryty = ll.ArrayType(llptr, len(llobjects[typ]) + 1)
|
||||
llobjectary = ll.GlobalVariable(self.llmodule, llobjectaryty,
|
||||
name="objects.{}".format(type_name))
|
||||
llobjectary.initializer = ll.Constant(llobjectaryty,
|
||||
llobjects[typ] + [ll.Constant(llptr, None)])
|
||||
llobjectary.linkage = 'internal'
|
||||
|
||||
lldesc = ll.GlobalVariable(self.llmodule, lldescty,
|
||||
name="shadow.desc.{}".format(type_name))
|
||||
name="desc.{}".format(type_name))
|
||||
lldesc.initializer = ll.Constant(lldescty, [
|
||||
llrpcattrary.bitcast(llrpcattrty.as_pointer().as_pointer()),
|
||||
ll.Constant(lli32, shadow_memory_dim[typ]),
|
||||
llshadow.bitcast(llptr)
|
||||
llobjectary.bitcast(llptr.as_pointer())
|
||||
])
|
||||
lldesc.global_constant = True
|
||||
lldesc.linkage = 'internal'
|
||||
lldescs.append(lldesc)
|
||||
|
||||
llglobaldescty = ll.ArrayType(lldescty.as_pointer(), len(lldescs) + 1)
|
||||
llglobaldesc = ll.GlobalVariable(self.llmodule, llglobaldescty, name="shadow")
|
||||
llglobaldesc = ll.GlobalVariable(self.llmodule, llglobaldescty,
|
||||
name="typeinfo")
|
||||
llglobaldesc.initializer = ll.Constant(llglobaldescty,
|
||||
lldescs + [ll.Constant(lldescty.as_pointer(), None)])
|
||||
|
||||
llobjectaryty = ll.ArrayType(llptr, len(llobjects))
|
||||
llobjectary = ll.GlobalVariable(self.llmodule, llobjectaryty, name="objects")
|
||||
llobjectary.initializer = ll.Constant(llobjectaryty, llobjects)
|
||||
|
||||
def process_function(self, func):
|
||||
try:
|
||||
self.llfunction = self.llmodule.get_global(func.name)
|
||||
|
@ -695,34 +672,6 @@ class LLVMIRGenerator:
|
|||
|
||||
def process_SetAttr(self, insn):
|
||||
assert builtins.is_allocated(insn.object().type)
|
||||
|
||||
object_type = insn.object().type.find()
|
||||
value_type = insn.value().type.find()
|
||||
if "__objectid__" in object_type.attributes and \
|
||||
not (types.is_function(value_type) or types.is_method(value_type)):
|
||||
llidptr = self.llbuilder.gep(self.map(insn.object()),
|
||||
[self.llindex(0), self.llindex(0)])
|
||||
llid = self.llbuilder.load(llidptr, name="shadow.id")
|
||||
llattrcount = ll.Constant(lli32, len(object_type.attributes))
|
||||
llshadowpos = self.llbuilder.add(
|
||||
self.llbuilder.mul(llid, llattrcount),
|
||||
ll.Constant(lli32, self.attr_index(insn)))
|
||||
|
||||
if types.is_constructor(object_type):
|
||||
shadowname = "shadow.class.{}".format(object_type.name)
|
||||
else:
|
||||
shadowname = "shadow.instance.{}".format(object_type.name)
|
||||
|
||||
llshadow = self.llmodule.get_global(shadowname)
|
||||
if llshadow is None:
|
||||
llshadowty = ll.ArrayType(lli8, 0)
|
||||
llshadow = ll.GlobalVariable(self.llmodule, llshadowty, shadowname)
|
||||
llshadow.linkage = 'internal'
|
||||
|
||||
llshadowptr = self.llbuilder.gep(llshadow, [self.llindex(0), llshadowpos],
|
||||
name="shadow.ptr")
|
||||
self.llbuilder.store(ll.Constant(lli8, 1), llshadowptr)
|
||||
|
||||
llptr = self.llbuilder.gep(self.map(insn.object()),
|
||||
[self.llindex(0), self.llindex(self.attr_index(insn))],
|
||||
name=insn.name)
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
double round(double x);
|
||||
|
||||
void ksupport_abort(void);
|
||||
static void attribute_writeback(void *, void *);
|
||||
static void attribute_writeback(void *);
|
||||
|
||||
int64_t now;
|
||||
|
||||
|
@ -247,16 +247,15 @@ int main(void)
|
|||
mailbox_send(&load_reply);
|
||||
while(1);
|
||||
}
|
||||
|
||||
void *__bss_start = dyld_lookup("__bss_start", request->library_info);
|
||||
void *_end = dyld_lookup("_end", request->library_info);
|
||||
memset(__bss_start, 0, _end - __bss_start);
|
||||
}
|
||||
|
||||
if(request->run_kernel) {
|
||||
void (*kernel_run)() = request->library_info->init;
|
||||
void *__bss_start = dyld_lookup("__bss_start", request->library_info);
|
||||
void *_end = dyld_lookup("_end", request->library_info);
|
||||
void *shadow = dyld_lookup("shadow", request->library_info);
|
||||
void *objects = dyld_lookup("objects", request->library_info);
|
||||
|
||||
memset(__bss_start, 0, _end - __bss_start);
|
||||
void *typeinfo = dyld_lookup("typeinfo", request->library_info);
|
||||
|
||||
mailbox_send_and_wait(&load_reply);
|
||||
|
||||
|
@ -264,7 +263,7 @@ int main(void)
|
|||
kernel_run();
|
||||
now_save(now);
|
||||
|
||||
attribute_writeback(shadow, objects);
|
||||
attribute_writeback(typeinfo);
|
||||
|
||||
struct msg_base finished_reply;
|
||||
finished_reply.type = MESSAGE_TYPE_FINISHED;
|
||||
|
@ -405,40 +404,36 @@ int recv_rpc(void *slot) {
|
|||
}
|
||||
}
|
||||
|
||||
struct shadow_attr {
|
||||
struct attr_desc {
|
||||
uint32_t size;
|
||||
const char *tag;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct shadow_desc {
|
||||
struct shadow_attr **attributes;
|
||||
uint32_t object_count;
|
||||
uint8_t *shadow;
|
||||
struct type_desc {
|
||||
struct attr_desc **attributes;
|
||||
void **objects;
|
||||
};
|
||||
|
||||
void attribute_writeback(void *udescs, void *uobjects) {
|
||||
struct shadow_desc **descs = (struct shadow_desc **)udescs;
|
||||
void **objects = (void **)uobjects;
|
||||
|
||||
while(*descs) {
|
||||
struct shadow_desc *desc = *descs++;
|
||||
void attribute_writeback(void *utypes) {
|
||||
struct type_desc **types = (struct type_desc **)utypes;
|
||||
while(*types) {
|
||||
struct type_desc *type = *types++;
|
||||
|
||||
size_t attr_count = 0;
|
||||
for(struct shadow_attr **attr = desc->attributes; *attr; attr++)
|
||||
for(struct attr_desc **attr = type->attributes; *attr; attr++)
|
||||
attr_count++;
|
||||
|
||||
for(int object_id = 0; object_id < desc->object_count; object_id++) {
|
||||
uint8_t *shadow = &desc->shadow[object_id * attr_count];
|
||||
void *object = objects[object_id];
|
||||
|
||||
if(object == NULL) continue;
|
||||
void **objects = type->objects;
|
||||
while(*objects) {
|
||||
void *object = *objects++;
|
||||
|
||||
size_t offset = 0;
|
||||
for(int attr_index = 0; attr_index < attr_count; attr_index++) {
|
||||
struct shadow_attr *attr = desc->attributes[attr_index];
|
||||
struct attr_desc **attrs = type->attributes;
|
||||
while(*attrs) {
|
||||
struct attr_desc *attr = *attrs++;
|
||||
|
||||
if(shadow[attr_index]) {
|
||||
if(attr->tag) {
|
||||
uintptr_t value = (uintptr_t)object + offset;
|
||||
send_rpc(0, attr->tag, &object, &attr->name, value);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue