def unroll_and_optimize(self, loop, call_pure_results=None, jump_values=None): self.add_guard_future_condition(loop) jump_op = loop.operations[-1] assert jump_op.getopnum() == rop.JUMP celltoken = JitCellToken() runtime_boxes = self.pack_into_boxes(jump_op, jump_values) jump_op.setdescr(celltoken) call_pure_results = self._convert_call_pure_results(call_pure_results) t = convert_loop_to_trace(loop, self.metainterp_sd) preamble_data = compile.PreambleCompileData( t, runtime_boxes, call_pure_results, enable_opts=self.enable_opts) start_state, preamble_ops = preamble_data.optimize_trace( self.metainterp_sd, None, {}) preamble_data.forget_optimization_info() loop_data = compile.UnrolledLoopData(preamble_data.trace, celltoken, start_state, call_pure_results, enable_opts=self.enable_opts) loop_info, ops = loop_data.optimize_trace(self.metainterp_sd, None, {}) preamble = TreeLoop('preamble') preamble.inputargs = start_state.renamed_inputargs start_label = ResOperation(rop.LABEL, start_state.renamed_inputargs) preamble.operations = ([start_label] + preamble_ops + loop_info.extra_same_as + [loop_info.label_op]) loop.inputargs = loop_info.label_op.getarglist()[:] loop.operations = [loop_info.label_op] + ops return Info(preamble, loop_info.target_token.short_preamble, start_state.virtual_state)
def send_bridge_to_backend(jitdriver_sd, metainterp_sd, faildescr, inputargs, operations, original_loop_token): if not we_are_translated(): show_procedures(metainterp_sd) seen = dict.fromkeys(inputargs) TreeLoop.check_consistency_of_branch(operations, seen) if metainterp_sd.warmrunnerdesc is not None: hooks = metainterp_sd.warmrunnerdesc.hooks debug_info = JitDebugInfo( jitdriver_sd, metainterp_sd.logger_ops, original_loop_token, operations, "bridge", fail_descr=faildescr ) hooks.before_compile_bridge(debug_info) else: hooks = None debug_info = None operations = get_deep_immutable_oplist(operations) metainterp_sd.profiler.start_backend() debug_start("jit-backend") try: asminfo = do_compile_bridge(metainterp_sd, faildescr, inputargs, operations, original_loop_token) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() if hooks is not None: debug_info.asminfo = asminfo hooks.after_compile_bridge(debug_info) if not we_are_translated(): metainterp_sd.stats.compiled() metainterp_sd.log("compiled new bridge") # if asminfo is not None: ops_offset = asminfo.ops_offset else: ops_offset = None metainterp_sd.logger_ops.log_bridge(inputargs, operations, None, faildescr, ops_offset)
def unroll_and_optimize(self, loop, call_pure_results=None, jump_values=None): self.add_guard_future_condition(loop) jump_op = loop.operations[-1] assert jump_op.getopnum() == rop.JUMP celltoken = JitCellToken() runtime_boxes = self.pack_into_boxes(jump_op, jump_values) jump_op.setdescr(celltoken) #start_label = ResOperation(rop.LABEL, loop.inputargs, # descr=jump_op.getdescr()) #end_label = jump_op.copy_and_change(opnum=rop.LABEL) call_pure_results = self._convert_call_pure_results(call_pure_results) t = convert_loop_to_trace(loop, FakeMetaInterpStaticData(self.cpu)) preamble_data = compile.LoopCompileData(t, runtime_boxes, call_pure_results) start_state, preamble_ops = self._do_optimize_loop(preamble_data) preamble_data.forget_optimization_info() loop_data = compile.UnrolledLoopData(preamble_data.trace, celltoken, start_state, call_pure_results) loop_info, ops = self._do_optimize_loop(loop_data) preamble = TreeLoop('preamble') preamble.inputargs = start_state.renamed_inputargs start_label = ResOperation(rop.LABEL, start_state.renamed_inputargs) preamble.operations = ([start_label] + preamble_ops + loop_info.extra_same_as + [loop_info.label_op]) loop.inputargs = loop_info.label_op.getarglist()[:] loop.operations = [loop_info.label_op] + ops return Info(preamble, loop_info.target_token.short_preamble, start_state.virtual_state)
def unroll_and_optimize(self, loop, call_pure_results=None): self.add_guard_future_condition(loop) jump_op = loop.operations[-1] assert jump_op.getopnum() == rop.JUMP ops = loop.operations[:-1] jump_op.setdescr(JitCellToken()) start_label = ResOperation(rop.LABEL, loop.inputargs, jump_op.getdescr()) end_label = jump_op.copy_and_change(opnum=rop.LABEL) call_pure_results = self._convert_call_pure_results(call_pure_results) preamble_data = compile.LoopCompileData(start_label, end_label, ops, call_pure_results) start_state, preamble_ops = self._do_optimize_loop(preamble_data) preamble_data.forget_optimization_info() loop_data = compile.UnrolledLoopData(start_label, jump_op, ops, start_state, call_pure_results) loop_info, ops = self._do_optimize_loop(loop_data) preamble = TreeLoop('preamble') preamble.inputargs = start_state.renamed_inputargs start_label = ResOperation(rop.LABEL, start_state.renamed_inputargs) preamble.operations = ([start_label] + preamble_ops + loop_info.extra_same_as + [loop_info.label_op]) loop.inputargs = loop_info.label_op.getarglist()[:] loop.operations = [loop_info.label_op] + ops return Info(preamble, loop_info.target_token.short_preamble, start_state.virtual_state)
def build_short_preamble(self): label_op = ResOperation(rop.LABEL, self.short_inputargs[:]) jump_op = ResOperation(rop.JUMP, self.short_preamble_jump[:]) if not we_are_translated(): TreeLoop.check_consistency_of(self.short_inputargs, self.short + [jump_op], check_descr=False) return [label_op] + self.short + [jump_op]
def convert_old_style_to_targets(loop, jump): newloop = TreeLoop(loop.name) newloop.inputargs = loop.inputargs newloop.operations = [ResOperation(rop.LABEL, loop.inputargs, None, descr=FakeDescr())] + \ loop.operations if not jump: assert newloop.operations[-1].getopnum() == rop.JUMP newloop.operations[-1] = ResOperation(rop.LABEL, newloop.operations[-1].getarglist(), None, descr=FakeDescr()) return newloop
def send_bridge_to_backend(jitdriver_sd, metainterp_sd, faildescr, inputargs, operations, original_loop_token, memo): forget_optimization_info(operations) forget_optimization_info(inputargs) if not we_are_translated(): show_procedures(metainterp_sd) seen = dict.fromkeys(inputargs) TreeLoop.check_consistency_of_branch(operations, seen) debug_info = None hooks = None if metainterp_sd.warmrunnerdesc is not None: hooks = metainterp_sd.warmrunnerdesc.hooks if hooks.are_hooks_enabled(): debug_info = JitDebugInfo(jitdriver_sd, metainterp_sd.logger_ops, original_loop_token, operations, 'bridge', fail_descr=faildescr) hooks.before_compile_bridge(debug_info) else: hooks = None operations = get_deep_immutable_oplist(operations) metainterp_sd.profiler.start_backend() debug_start("jit-backend") log = have_debug_prints() or jl.jitlog_enabled() try: asminfo = do_compile_bridge(metainterp_sd, faildescr, inputargs, operations, original_loop_token, log, memo) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() if hooks is not None: debug_info.asminfo = asminfo hooks.after_compile_bridge(debug_info) if not we_are_translated(): metainterp_sd.stats.compiled() metainterp_sd.log("compiled new bridge") # if asminfo is not None: ops_offset = asminfo.ops_offset else: ops_offset = None metainterp_sd.logger_ops.log_bridge(inputargs, operations, None, faildescr, ops_offset, memo=memo) # #if metainterp_sd.warmrunnerdesc is not None: # for tests # metainterp_sd.warmrunnerdesc.memory_manager.keep_loop_alive( # original_loop_token) return asminfo
def unroll_and_optimize(self, loop, call_pure_results=None): self.add_guard_future_condition(loop) 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 token = JitCellToken() preamble.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(token))] + \ operations + \ [ResOperation(rop.LABEL, jump_args, None, descr=token)] start_state = self._do_optimize_loop(preamble, call_pure_results, export_state=True) assert preamble.operations[-1].getopnum() == rop.LABEL inliner = Inliner(inputargs, jump_args) 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, start_state, export_state=False) 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(self, ops): loop = self.parse(ops) self.add_guard_future_condition(loop) operations = loop.operations jumpop = operations[-1] assert jumpop.getopnum() == rop.JUMP inputargs = loop.inputargs preamble = TreeLoop('preamble') trace = oparser.convert_loop_to_trace(loop, self.metainterp_sd) compile_data = PreambleCompileData( trace, inputargs, enable_opts=self.enable_opts) start_state, newops = compile_data.optimize_trace( self.metainterp_sd, None, {}) preamble.operations = newops preamble.inputargs = start_state.renamed_inputargs return start_state, loop, preamble
def send_bridge_to_backend(jitdriver_sd, metainterp_sd, faildescr, inputargs, operations, original_loop_token, memo): forget_optimization_info(operations) forget_optimization_info(inputargs) if not we_are_translated(): show_procedures(metainterp_sd) seen = dict.fromkeys(inputargs) TreeLoop.check_consistency_of_branch(operations, seen) if metainterp_sd.warmrunnerdesc is not None: hooks = metainterp_sd.warmrunnerdesc.hooks debug_info = JitDebugInfo(jitdriver_sd, metainterp_sd.logger_ops, original_loop_token, operations, 'bridge', fail_descr=faildescr) hooks.before_compile_bridge(debug_info) else: hooks = None debug_info = None operations = get_deep_immutable_oplist(operations) metainterp_sd.profiler.start_backend() debug_start("jit-backend") log = have_debug_prints() or jl.jitlog_enabled() try: asminfo = do_compile_bridge(metainterp_sd, faildescr, inputargs, operations, original_loop_token, log, memo) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() if hooks is not None: debug_info.asminfo = asminfo hooks.after_compile_bridge(debug_info) if not we_are_translated(): metainterp_sd.stats.compiled() metainterp_sd.log("compiled new bridge") # if asminfo is not None: ops_offset = asminfo.ops_offset else: ops_offset = None metainterp_sd.logger_ops.log_bridge(inputargs, operations, None, faildescr, ops_offset, memo=memo) # #if metainterp_sd.warmrunnerdesc is not None: # for tests # metainterp_sd.warmrunnerdesc.memory_manager.keep_loop_alive( # original_loop_token) return asminfo
def unroll_and_optimize(self, loop, call_pure_results=None): self.add_guard_future_condition(loop) 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 token = JitCellToken() preamble.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(token))] + \ operations + \ [ResOperation(rop.LABEL, jump_args, None, descr=token)] start_state = self._do_optimize_loop(preamble, call_pure_results, export_state=True) assert preamble.operations[-1].getopnum() == rop.LABEL inliner = Inliner(inputargs, jump_args) 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, start_state, export_state=False) 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(self, ops): loop = self.parse(ops) self.add_guard_future_condition(loop) operations = loop.operations jumpop = operations[-1] assert jumpop.getopnum() == rop.JUMP inputargs = loop.inputargs jump_args = jumpop.getarglist()[:] operations = operations[:-1] preamble = TreeLoop('preamble') token = JitCellToken() trace = oparser.convert_loop_to_trace(loop, FakeMetaInterpStaticData(self.cpu)) compile_data = LoopCompileData(trace, inputargs) start_state, newops = self._do_optimize_loop(compile_data) preamble.operations = newops preamble.inputargs = start_state.renamed_inputargs return start_state, loop, preamble
def build_random_loop(self, cpu, builder_factory, r, startvars, allow_delay): loop = TreeLoop('test_random_function') loop.inputargs = startvars[:] loop.operations = [] loop._jitcelltoken = JitCellToken() builder = builder_factory(cpu, loop, startvars[:]) if allow_delay: needs_a_label = True else: self.insert_label(loop, 0, r) needs_a_label = False self.generate_ops(builder, r, loop, startvars, needs_a_label=needs_a_label) self.builder = builder self.loop = loop dump(loop) cpu.compile_loop(loop.inputargs, loop.operations, loop._jitcelltoken) if self.output: builder.print_loop(self.output)
def optimize(self, ops): loop = self.parse(ops, postprocess=self.postprocess) self.add_guard_future_condition(loop) operations = loop.operations jumpop = operations[-1] assert jumpop.getopnum() == rop.JUMP inputargs = loop.inputargs jump_args = jumpop.getarglist()[:] operations = operations[:-1] preamble = TreeLoop('preamble') token = JitCellToken() start_label = ResOperation(rop.LABEL, inputargs, descr=TargetToken(token)) stop_label = ResOperation(rop.LABEL, jump_args, descr=token) compile_data = LoopCompileData(start_label, stop_label, operations) start_state, newops = self._do_optimize_loop(compile_data) preamble.operations = newops preamble.inputargs = start_state.renamed_inputargs return start_state, loop, preamble
def send_bridge_to_backend(jitdriver_sd, metainterp_sd, faildescr, inputargs, operations, original_loop_token): if not we_are_translated(): show_procedures(metainterp_sd) seen = dict.fromkeys(inputargs) TreeLoop.check_consistency_of_branch(operations, seen) if metainterp_sd.warmrunnerdesc is not None: hooks = metainterp_sd.warmrunnerdesc.hooks debug_info = JitDebugInfo(jitdriver_sd, metainterp_sd.logger_ops, original_loop_token, operations, 'bridge', fail_descr=faildescr) hooks.before_compile_bridge(debug_info) else: hooks = None debug_info = None operations = get_deep_immutable_oplist(operations) metainterp_sd.profiler.start_backend() debug_start("jit-backend") try: asminfo = do_compile_bridge(metainterp_sd, faildescr, inputargs, operations, original_loop_token) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() if hooks is not None: debug_info.asminfo = asminfo hooks.after_compile_bridge(debug_info) if not we_are_translated(): metainterp_sd.stats.compiled() metainterp_sd.log("compiled new bridge") # if asminfo is not None: ops_offset = asminfo.ops_offset else: ops_offset = None metainterp_sd.logger_ops.log_bridge(inputargs, operations, None, faildescr, ops_offset)
def xxx_test_random_snapshot(self, lst): inputargs, ops = lst t = Trace(inputargs, metainterp_sd) for op in ops: newop = FakeOp(t.record_op(op.getopnum(), op.getarglist())) newop.orig_op = op if newop.is_guard(): resume.capture_resumedata(op.framestack, None, [], t) op.position = newop.get_position() inpargs, l, iter = self.unpack(t) loop1 = TreeLoop("loop1") loop1.inputargs = inputargs loop1.operations = ops loop2 = TreeLoop("loop2") loop2.inputargs = inpargs loop2.operations = l BaseTest.assert_equal(loop1, loop2)
def create_empty_loop(metainterp, name_prefix=''): name = metainterp.staticdata.stats.name_for_new_loop() loop = TreeLoop(name_prefix + name) loop.call_pure_results = metainterp.call_pure_results return loop
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 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 = [] state = None 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.add_guard_future_condition(part) state = self._do_optimize_loop(part, None, state, export_state=True) 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
def create_empty_loop(metainterp, name_prefix=''): name = metainterp.staticdata.stats.name_for_new_loop() loop = TreeLoop(name_prefix + name) return loop
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 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 = [] state = None 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.add_guard_future_condition(part) state = self._do_optimize_loop(part, None, state, export_state=True) 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