Skip to content

Commit 81427af

Browse files
author
whitequark
committedJan 2, 2016
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.
1 parent e41b9db commit 81427af

File tree

2 files changed

+51
-107
lines changed

2 files changed

+51
-107
lines changed
 

Diff for: ‎artiq/compiler/transforms/llvm_ir_generator.py

+28-79
Original file line numberDiff line numberDiff line change
@@ -418,17 +418,9 @@ def process(self, functions, attribute_writeback):
418418
return self.llmodule
419419

420420
def emit_attribute_writeback(self):
421-
llobjects = []
422-
shadow_memory_dim = defaultdict(lambda: 0)
421+
llobjects = defaultdict(lambda: [])
423422

424423
for obj_id in self.object_map:
425-
while len(llobjects) <= obj_id:
426-
llobjects.append(ll.Constant(llptr, None))
427-
428-
llobject = self.llmodule.get_global("object.{}".format(obj_id))
429-
if llobject is not None:
430-
llobjects[obj_id] = llobject.bitcast(llptr)
431-
432424
obj_ref = self.object_map.retrieve(obj_id)
433425
if isinstance(obj_ref, (pytypes.FunctionType, pytypes.MethodType)):
434426
continue
@@ -437,19 +429,20 @@ def emit_attribute_writeback(self):
437429
else:
438430
typ, _ = self.type_map[type(obj_ref)]
439431

440-
if shadow_memory_dim[typ] <= obj_id:
441-
shadow_memory_dim[typ] = obj_id + 1
432+
llobject = self.llmodule.get_global("object.{}".format(obj_id))
433+
if llobject is not None:
434+
llobjects[typ].append(llobject.bitcast(llptr))
442435

443436
lldatalayout = llvm.create_target_data(self.llmodule.data_layout)
444437

445-
llrpcattrty = self.llcontext.get_identified_type("shadow.attr")
438+
llrpcattrty = self.llcontext.get_identified_type("attr_desc")
446439
llrpcattrty.elements = [lli32, llptr, llptr]
447440

448-
lldescty = self.llcontext.get_identified_type("shadow.desc")
449-
lldescty.elements = [llrpcattrty.as_pointer().as_pointer(), lli32, llptr]
441+
lldescty = self.llcontext.get_identified_type("type_desc")
442+
lldescty.elements = [llrpcattrty.as_pointer().as_pointer(), llptr.as_pointer()]
450443

451444
lldescs = []
452-
for typ in shadow_memory_dim:
445+
for typ in llobjects:
453446
if "__objectid__" not in typ.attributes:
454447
continue
455448

@@ -458,44 +451,25 @@ def emit_attribute_writeback(self):
458451
else:
459452
type_name = "instance.{}".format(typ.name)
460453

461-
shadowname = "shadow.{}".format(type_name)
462-
llshadow = self.llmodule.get_global(shadowname)
463-
if llshadow is None:
464-
continue
465-
466-
llshadowlen = shadow_memory_dim[typ] * len(typ.attributes)
467-
llshadowty = ll.ArrayType(lli8, llshadowlen)
468-
llshadow.gtype = llshadowty
469-
llshadow.type = llshadowty.as_pointer()
470-
llshadow.initializer = ll.Constant(llshadowty, None)
471-
472454
def llrpcattr_of_attr(name, typ):
473-
llty = self.llty_of_type(typ)
474-
if isinstance(llty, ll.PointerType):
475-
# Work around llvmlite bug where it is unable to get a C++
476-
# object for a type if it includes an identified type in a context
477-
# other than the default.
478-
size = llptr.get_abi_size(lldatalayout)
479-
else:
480-
size = llty.get_abi_size(lldatalayout)
455+
size = self.llty_of_type(typ).get_abi_size(lldatalayout, context=self.llcontext)
481456

482457
def rpc_tag_error(typ):
483458
print(typ)
484459
assert False
485460

486-
rpctag = b"Os"
487-
if not (types.is_function(typ) or types.is_method(typ)):
488-
rpctag += self._rpc_tag(typ, error_handler=rpc_tag_error)
461+
if not (types.is_function(typ) or types.is_method(typ) or
462+
name == "__objectid__"):
463+
rpctag = b"Os" + self._rpc_tag(typ, error_handler=rpc_tag_error) + b":n\x00"
464+
llrpctag = self.llstr_of_str(rpctag)
489465
else:
490-
rpctag += b""
491-
rpctag += b":n\x00"
492-
llrpctag = self.llstr_of_str(rpctag)
466+
llrpctag = ll.Constant(llptr, None)
493467

494468
llrpcattr = ll.GlobalVariable(self.llmodule, llrpcattrty,
495-
name="shadow.attr.{}.{}".format(type_name, name))
469+
name="attr.{}.{}".format(type_name, name))
496470
llrpcattr.initializer = ll.Constant(llrpcattrty, [
497471
ll.Constant(lli32, size),
498-
self.llstr_of_str(rpctag),
472+
llrpctag,
499473
self.llstr_of_str(name)
500474
])
501475
llrpcattr.global_constant = True
@@ -509,33 +483,36 @@ def rpc_tag_error(typ):
509483

510484
llrpcattraryty = ll.ArrayType(llrpcattrty.as_pointer(), len(llrpcattrs) + 1)
511485
llrpcattrary = ll.GlobalVariable(self.llmodule, llrpcattraryty,
512-
name="shadow.attrs.{}".format(type_name))
486+
name="attrs.{}".format(type_name))
513487
llrpcattrary.initializer = ll.Constant(llrpcattraryty,
514488
llrpcattrs + [ll.Constant(llrpcattrty.as_pointer(), None)])
515489
llrpcattrary.global_constant = True
516490
llrpcattrary.unnamed_addr = True
517491
llrpcattrary.linkage = 'internal'
518492

493+
llobjectaryty = ll.ArrayType(llptr, len(llobjects[typ]) + 1)
494+
llobjectary = ll.GlobalVariable(self.llmodule, llobjectaryty,
495+
name="objects.{}".format(type_name))
496+
llobjectary.initializer = ll.Constant(llobjectaryty,
497+
llobjects[typ] + [ll.Constant(llptr, None)])
498+
llobjectary.linkage = 'internal'
499+
519500
lldesc = ll.GlobalVariable(self.llmodule, lldescty,
520-
name="shadow.desc.{}".format(type_name))
501+
name="desc.{}".format(type_name))
521502
lldesc.initializer = ll.Constant(lldescty, [
522503
llrpcattrary.bitcast(llrpcattrty.as_pointer().as_pointer()),
523-
ll.Constant(lli32, shadow_memory_dim[typ]),
524-
llshadow.bitcast(llptr)
504+
llobjectary.bitcast(llptr.as_pointer())
525505
])
526506
lldesc.global_constant = True
527507
lldesc.linkage = 'internal'
528508
lldescs.append(lldesc)
529509

530510
llglobaldescty = ll.ArrayType(lldescty.as_pointer(), len(lldescs) + 1)
531-
llglobaldesc = ll.GlobalVariable(self.llmodule, llglobaldescty, name="shadow")
511+
llglobaldesc = ll.GlobalVariable(self.llmodule, llglobaldescty,
512+
name="typeinfo")
532513
llglobaldesc.initializer = ll.Constant(llglobaldescty,
533514
lldescs + [ll.Constant(lldescty.as_pointer(), None)])
534515

535-
llobjectaryty = ll.ArrayType(llptr, len(llobjects))
536-
llobjectary = ll.GlobalVariable(self.llmodule, llobjectaryty, name="objects")
537-
llobjectary.initializer = ll.Constant(llobjectaryty, llobjects)
538-
539516
def process_function(self, func):
540517
try:
541518
self.llfunction = self.llmodule.get_global(func.name)
@@ -695,34 +672,6 @@ def process_GetAttr(self, insn):
695672

696673
def process_SetAttr(self, insn):
697674
assert builtins.is_allocated(insn.object().type)
698-
699-
object_type = insn.object().type.find()
700-
value_type = insn.value().type.find()
701-
if "__objectid__" in object_type.attributes and \
702-
not (types.is_function(value_type) or types.is_method(value_type)):
703-
llidptr = self.llbuilder.gep(self.map(insn.object()),
704-
[self.llindex(0), self.llindex(0)])
705-
llid = self.llbuilder.load(llidptr, name="shadow.id")
706-
llattrcount = ll.Constant(lli32, len(object_type.attributes))
707-
llshadowpos = self.llbuilder.add(
708-
self.llbuilder.mul(llid, llattrcount),
709-
ll.Constant(lli32, self.attr_index(insn)))
710-
711-
if types.is_constructor(object_type):
712-
shadowname = "shadow.class.{}".format(object_type.name)
713-
else:
714-
shadowname = "shadow.instance.{}".format(object_type.name)
715-
716-
llshadow = self.llmodule.get_global(shadowname)
717-
if llshadow is None:
718-
llshadowty = ll.ArrayType(lli8, 0)
719-
llshadow = ll.GlobalVariable(self.llmodule, llshadowty, shadowname)
720-
llshadow.linkage = 'internal'
721-
722-
llshadowptr = self.llbuilder.gep(llshadow, [self.llindex(0), llshadowpos],
723-
name="shadow.ptr")
724-
self.llbuilder.store(ll.Constant(lli8, 1), llshadowptr)
725-
726675
llptr = self.llbuilder.gep(self.map(insn.object()),
727676
[self.llindex(0), self.llindex(self.attr_index(insn))],
728677
name=insn.name)

Diff for: ‎artiq/runtime/ksupport.c

+23-28
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
double round(double x);
2121

2222
void ksupport_abort(void);
23-
static void attribute_writeback(void *, void *);
23+
static void attribute_writeback(void *);
2424

2525
int64_t now;
2626

@@ -247,24 +247,23 @@ int main(void)
247247
mailbox_send(&load_reply);
248248
while(1);
249249
}
250-
}
251250

252-
if(request->run_kernel) {
253-
void (*kernel_run)() = request->library_info->init;
254251
void *__bss_start = dyld_lookup("__bss_start", request->library_info);
255252
void *_end = dyld_lookup("_end", request->library_info);
256-
void *shadow = dyld_lookup("shadow", request->library_info);
257-
void *objects = dyld_lookup("objects", request->library_info);
258-
259253
memset(__bss_start, 0, _end - __bss_start);
254+
}
255+
256+
if(request->run_kernel) {
257+
void (*kernel_run)() = request->library_info->init;
258+
void *typeinfo = dyld_lookup("typeinfo", request->library_info);
260259

261260
mailbox_send_and_wait(&load_reply);
262261

263262
now = now_init();
264263
kernel_run();
265264
now_save(now);
266265

267-
attribute_writeback(shadow, objects);
266+
attribute_writeback(typeinfo);
268267

269268
struct msg_base finished_reply;
270269
finished_reply.type = MESSAGE_TYPE_FINISHED;
@@ -405,40 +404,36 @@ int recv_rpc(void *slot) {
405404
}
406405
}
407406

408-
struct shadow_attr {
407+
struct attr_desc {
409408
uint32_t size;
410409
const char *tag;
411410
const char *name;
412411
};
413412

414-
struct shadow_desc {
415-
struct shadow_attr **attributes;
416-
uint32_t object_count;
417-
uint8_t *shadow;
413+
struct type_desc {
414+
struct attr_desc **attributes;
415+
void **objects;
418416
};
419417

420-
void attribute_writeback(void *udescs, void *uobjects) {
421-
struct shadow_desc **descs = (struct shadow_desc **)udescs;
422-
void **objects = (void **)uobjects;
423-
424-
while(*descs) {
425-
struct shadow_desc *desc = *descs++;
418+
void attribute_writeback(void *utypes) {
419+
struct type_desc **types = (struct type_desc **)utypes;
420+
while(*types) {
421+
struct type_desc *type = *types++;
426422

427423
size_t attr_count = 0;
428-
for(struct shadow_attr **attr = desc->attributes; *attr; attr++)
424+
for(struct attr_desc **attr = type->attributes; *attr; attr++)
429425
attr_count++;
430426

431-
for(int object_id = 0; object_id < desc->object_count; object_id++) {
432-
uint8_t *shadow = &desc->shadow[object_id * attr_count];
433-
void *object = objects[object_id];
434-
435-
if(object == NULL) continue;
427+
void **objects = type->objects;
428+
while(*objects) {
429+
void *object = *objects++;
436430

437431
size_t offset = 0;
438-
for(int attr_index = 0; attr_index < attr_count; attr_index++) {
439-
struct shadow_attr *attr = desc->attributes[attr_index];
432+
struct attr_desc **attrs = type->attributes;
433+
while(*attrs) {
434+
struct attr_desc *attr = *attrs++;
440435

441-
if(shadow[attr_index]) {
436+
if(attr->tag) {
442437
uintptr_t value = (uintptr_t)object + offset;
443438
send_rpc(0, attr->tag, &object, &attr->name, value);
444439
}

0 commit comments

Comments
 (0)
Please sign in to comment.