def schedule(self, loop, packs, vec_reg_size=16, prepend_invariant=False, overwrite_funcs=None): cm = GenericCostModel(self.cpu, 0) cm.profitable = lambda: True pairs = [] for pack in packs: for i in range(len(pack.operations) - 1): o1 = pack.operations[i] o2 = pack.operations[i + 1] pair = Pair(o1, o2) pairs.append(pair) packset = FakePackSet(pairs) state = VecScheduleState(loop.graph, packset, self.cpu, cm) for name, overwrite in (overwrite_funcs or {}).items(): setattr(state, name, overwrite) renamer = Renamer() metainterp_sd = FakeMetaInterpStaticData(self.cpu) jitdriver_sd = FakeJitDriverStaticData() opt = VectorizingOptimizer(metainterp_sd, jitdriver_sd, 0) opt.packset = packset opt.combine_packset() opt.schedule(state) # works for now. might be the wrong class? # wrap label + operations + jump it in tree loop otherwise loop = state.graph.loop if prepend_invariant: loop.operations = loop.prefix + loop.operations return loop
def clone(self): renamer = Renamer() label = copy_resop(self.label) prefix = [] for op in self.prefix: newop = copy_resop(op) renamer.rename(newop) if not newop.returns_void(): renamer.start_renaming(op, newop) prefix.append(newop) prefix_label = None if self.prefix_label: prefix_label = copy_resop(self.prefix_label) renamer.rename(prefix_label) oplist = [] for op in self.operations: newop = copy_resop(op) renamer.rename(newop) if not newop.returns_void(): renamer.start_renaming(op, newop) oplist.append(newop) jump = copy_resop(self.jump) renamer.rename(jump) loop = VectorLoop(copy_resop(self.label), oplist, jump) loop.prefix = prefix loop.prefix_label = prefix_label return loop
def eliminate_guards(self, loop): self.renamer = Renamer() for i, op in enumerate(loop.operations): op = loop.operations[i] if op.is_guard(): if i in self.guards: # either a stronger guard has been saved # or it should not be emitted guard = self.guards[i] # this guard is implied or marked as not emitted (= None) self.strength_reduced += 1 if guard is None: continue guard.emit_operations(self) continue else: self.emit_operation(op) continue if not op.returns_void(): index_var = self.index_vars.get(op, None) if index_var: if not index_var.is_identity(): var = index_var.emit_operations(self, op) self.renamer.start_renaming(op, var) continue self.emit_operation(op) self.renamer.rename(loop.jump) # loop.operations = self._newoperations[:]
def __init__(self, graph): self.renamer = Renamer() self.graph = graph self.oplist = [] self.worklist = [] self.invariant_oplist = [] self.invariant_vector_vars = [] self.seen = {}
def __init__(self, cpu, graph): self.cpu = cpu self.renamer = Renamer() self.graph = graph self.oplist = [] self.worklist = [] self.invariant_oplist = [] self.invariant_vector_vars = [] self.seen = {} self.delayed = []
def unroll_loop_iterations(self, loop, unroll_count): """ Unroll the loop X times. unroll_count + 1 = unroll_factor """ numops = len(loop.operations) renamer = Renamer() operations = loop.operations unrolled = [] prohibit_opnums = (rop.GUARD_FUTURE_CONDITION, rop.GUARD_NOT_INVALIDATED) orig_jump_args = loop.jump.getarglist()[:] # it is assumed that #label_args == #jump_args label_arg_count = len(orig_jump_args) for u in range(unroll_count): # fill the map with the renaming boxes. keys are boxes from the label for i in range(label_arg_count): la = loop.label.getarg(i) ja = loop.jump.getarg(i) ja = renamer.rename_box(ja) if la != ja: renamer.start_renaming(la, ja) # for i, op in enumerate(operations): if op.getopnum() in prohibit_opnums: continue # do not unroll this operation twice copied_op = copy_resop(op) if not copied_op.returns_void(): # every result assigns a new box, thus creates an entry # to the rename map. renamer.start_renaming(op, copied_op) # args = copied_op.getarglist() for a, arg in enumerate(args): value = renamer.rename_box(arg) copied_op.setarg(a, value) # not only the arguments, but also the fail args need # to be adjusted. rd_snapshot stores the live variables # that are needed to resume. if copied_op.is_guard(): self.copy_guard_descr(renamer, copied_op) # unrolled.append(copied_op) # the jump arguments have been changed # if label(iX) ... jump(i(X+1)) is called, at the next unrolled loop # must look like this: label(i(X+1)) ... jump(i(X+2)) args = loop.jump.getarglist() for i, arg in enumerate(args): value = renamer.rename_box(arg) loop.jump.setarg(i, value) # loop.operations = operations + unrolled
def unroll_loop_iterations(self, loop, unroll_count, align_unroll_once=False): """ Unroll the loop `unroll_count` times. There can be an additional unroll step if alignment might benefit """ numops = len(loop.operations) renamer = Renamer() operations = loop.operations orig_jump_args = loop.jump.getarglist()[:] prohibit_opnums = (rop.GUARD_FUTURE_CONDITION, rop.GUARD_NOT_INVALIDATED, rop.DEBUG_MERGE_POINT) unrolled = [] if align_unroll_once: unroll_count += 1 # it is assumed that #label_args == #jump_args label_arg_count = len(orig_jump_args) label = loop.label jump = loop.jump new_label = loop.label for u in range(unroll_count): # fill the map with the renaming boxes. keys are boxes from the label for i in range(label_arg_count): la = label.getarg(i) ja = jump.getarg(i) ja = renamer.rename_box(ja) if la != ja: renamer.start_renaming(la, ja) # for i, op in enumerate(operations): if op.getopnum() in prohibit_opnums: continue # do not unroll this operation twice copied_op = copy_resop(op) if not copied_op.returns_void(): # every result assigns a new box, thus creates an entry # to the rename map. renamer.start_renaming(op, copied_op) # args = copied_op.getarglist() for a, arg in enumerate(args): value = renamer.rename_box(arg) copied_op.setarg(a, value) # not only the arguments, but also the fail args need # to be adjusted. rd_snapshot stores the live variables # that are needed to resume. if copied_op.is_guard(): self.copy_guard_descr(renamer, copied_op) # unrolled.append(copied_op) # if align_unroll_once and u == 0: descr = label.getdescr() args = label.getarglist()[:] new_label = ResOperation(rop.LABEL, args, descr) renamer.rename(new_label) # # the jump arguments have been changed # if label(iX) ... jump(i(X+1)) is called, at the next unrolled loop # must look like this: label(i(X+1)) ... jump(i(X+2)) args = loop.jump.getarglist() for i, arg in enumerate(args): value = renamer.rename_box(arg) loop.jump.setarg(i, value) # loop.label = new_label if align_unroll_once: loop.align_operations = operations loop.operations = unrolled else: loop.operations = operations + unrolled