def unroll_and_optimize(self, loop, call_pure_results=None): operations = loop.operations jumpop = operations[-1] assert jumpop.getopnum() == rop.JUMP inputargs = loop.inputargs jump_args = jumpop.getarglist()[:] operations = operations[:-1] cloned_operations = [op.clone() for op in operations] preamble = TreeLoop('preamble') preamble.inputargs = inputargs preamble.resume_at_jump_descr = FakeDescrWithSnapshot() token = JitCellToken() preamble.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(token))] + \ operations + \ [ResOperation(rop.LABEL, jump_args, None, descr=token)] self._do_optimize_loop(preamble, call_pure_results) assert preamble.operations[-1].getopnum() == rop.LABEL inliner = Inliner(inputargs, jump_args) loop.resume_at_jump_descr = preamble.resume_at_jump_descr loop.operations = [preamble.operations[-1]] + \ [inliner.inline_op(op, clone=False) for op in cloned_operations] + \ [ResOperation(rop.JUMP, [inliner.inline_arg(a) for a in jump_args], None, descr=token)] #[inliner.inline_op(jumpop)] assert loop.operations[-1].getopnum() == rop.JUMP assert loop.operations[0].getopnum() == rop.LABEL loop.inputargs = loop.operations[0].getarglist() self._do_optimize_loop(loop, call_pure_results) extra_same_as = [] while loop.operations[0].getopnum() != rop.LABEL: extra_same_as.append(loop.operations[0]) del loop.operations[0] # Hack to prevent random order of same_as ops extra_same_as.sort( key=lambda op: str(preamble.operations).find(str(op.getarg(0)))) for op in extra_same_as: preamble.operations.insert(-1, op) return preamble
def unroll_and_optimize(self, loop, call_pure_results=None): operations = loop.operations jumpop = operations[-1] assert jumpop.getopnum() == rop.JUMP inputargs = loop.inputargs jump_args = jumpop.getarglist()[:] operations = operations[:-1] cloned_operations = [op.clone() for op in operations] preamble = TreeLoop('preamble') preamble.inputargs = inputargs preamble.resume_at_jump_descr = FakeDescrWithSnapshot() token = JitCellToken() preamble.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(token))] + \ operations + \ [ResOperation(rop.LABEL, jump_args, None, descr=token)] self._do_optimize_loop(preamble, call_pure_results) assert preamble.operations[-1].getopnum() == rop.LABEL inliner = Inliner(inputargs, jump_args) loop.resume_at_jump_descr = preamble.resume_at_jump_descr loop.operations = [preamble.operations[-1]] + \ [inliner.inline_op(op, clone=False) for op in cloned_operations] + \ [ResOperation(rop.JUMP, [inliner.inline_arg(a) for a in jump_args], None, descr=token)] #[inliner.inline_op(jumpop)] assert loop.operations[-1].getopnum() == rop.JUMP assert loop.operations[0].getopnum() == rop.LABEL loop.inputargs = loop.operations[0].getarglist() self._do_optimize_loop(loop, call_pure_results) extra_same_as = [] while loop.operations[0].getopnum() != rop.LABEL: extra_same_as.append(loop.operations[0]) del loop.operations[0] # Hack to prevent random order of same_as ops extra_same_as.sort(key=lambda op: str(preamble.operations).find(str(op.getarg(0)))) for op in extra_same_as: preamble.operations.insert(-1, op) return preamble
def optimize_loop(self, ops, expected, expected_shorts=None): loop = self.parse(ops) if expected != "crash!": expected = self.parse(expected) part = TreeLoop('part') part.inputargs = loop.inputargs part.resume_at_jump_descr = FakeDescrWithSnapshot() token = loop.original_jitcell_token optimized = TreeLoop('optimized') optimized.inputargs = loop.inputargs optimized.operations = [] labels = [i for i, op in enumerate(loop.operations) \ if op.getopnum()==rop.LABEL] prv = 0 last_label = [] for nxt in labels + [len(loop.operations)]: assert prv != nxt operations = last_label + loop.operations[prv:nxt] if nxt < len(loop.operations): label = loop.operations[nxt] assert label.getopnum() == rop.LABEL if label.getdescr() is None: label.setdescr(token) operations.append(label) part.operations = operations self._do_optimize_loop(part, None) if part.operations[-1].getopnum() == rop.LABEL: last_label = [part.operations.pop()] else: last_label = [] optimized.operations.extend(part.operations) prv = nxt + 1 # print print "Optimized:" if optimized.operations: print '\n'.join([str(o) for o in optimized.operations]) else: print 'Failed!' print shorts = [op.getdescr().short_preamble for op in optimized.operations if op.getopnum() == rop.LABEL] if expected_shorts: for short in shorts: print print "Short preamble:" print '\n'.join([str(o) for o in short]) assert expected != "crash!", "should have raised an exception" self.assert_equal(optimized, expected) if expected_shorts: assert len(shorts) == len(expected_shorts) for short, expected_short in zip(shorts, expected_shorts): expected_short = self.parse(expected_short) short_preamble = TreeLoop('short preamble') assert short[0].getopnum() == rop.LABEL short_preamble.inputargs = short[0].getarglist() short_preamble.operations = short self.assert_equal(short_preamble, expected_short, text_right='expected short preamble') return optimized