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 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 optimize(self, ops, bridge_ops, expected, expected_loop=None, inline_short_preamble=True, jump_values=None, bridge_values=None): loop = self.parse(ops) info = self.unroll_and_optimize(loop, None, jump_values=jump_values) jitcell_token = compile.make_jitcell_token(None) mid_label_descr = TargetToken(jitcell_token) mid_label_descr.short_preamble = info.short_preamble mid_label_descr.virtual_state = info.virtual_state start_label_descr = TargetToken(jitcell_token) jitcell_token.target_tokens = [mid_label_descr, start_label_descr] loop.operations[0].setdescr(mid_label_descr) loop.operations[-1].setdescr(mid_label_descr) info.preamble.operations[0].setdescr(start_label_descr) guards = [op for op in loop.operations if op.is_guard()] assert len(guards) == 1, "more than one guard in the loop" bridge = self.parse(bridge_ops) bridge.operations[-1].setdescr(jitcell_token) self.add_guard_future_condition(bridge) trace = oparser.convert_loop_to_trace( bridge, FakeMetaInterpStaticData(self.cpu)) data = compile.BridgeCompileData( trace, self.convert_values(bridge.operations[-1].getarglist(), bridge_values), None, enable_opts=self.enable_opts, inline_short_preamble=inline_short_preamble) bridge_info, ops = self._do_optimize_loop(data) loop.check_consistency(check_descr=False) info.preamble.check_consistency(check_descr=False) bridge.operations = ([ResOperation(rop.LABEL, bridge_info.inputargs)] + ops) bridge.inputargs = bridge_info.inputargs bridge.check_consistency(check_descr=False) expected = self.parse(expected) self.assert_equal(bridge, convert_old_style_to_targets(expected, jump=True)) jump_bridge = bridge.operations[-1] jump_d = jump_bridge.getdescr() jump_args = jump_bridge.getarglist() if loop.operations[0].getdescr() is jump_d: # jump to loop label_args = loop.operations[0].getarglist() else: assert info.preamble.operations[0].getdescr() is jump_d label_args = info.preamble.operations[0].getarglist() assert len(jump_args) == len(label_args) for a, b in zip(jump_args, label_args): assert a.type == b.type
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 optimize(self, ops, bridge_ops, expected, expected_loop=None, inline_short_preamble=True, jump_values=None, bridge_values=None): loop = self.parse(ops) info = self.unroll_and_optimize(loop, None, jump_values=jump_values) jitcell_token = compile.make_jitcell_token(None) mid_label_descr = TargetToken(jitcell_token) mid_label_descr.short_preamble = info.short_preamble mid_label_descr.virtual_state = info.virtual_state start_label_descr = TargetToken(jitcell_token) jitcell_token.target_tokens = [mid_label_descr, start_label_descr] loop.operations[0].setdescr(mid_label_descr) loop.operations[-1].setdescr(mid_label_descr) info.preamble.operations[0].setdescr(start_label_descr) guards = [op for op in loop.operations if op.is_guard()] assert len(guards) == 1, "more than one guard in the loop" bridge = self.parse(bridge_ops) bridge.operations[-1].setdescr(jitcell_token) self.add_guard_future_condition(bridge) trace = oparser.convert_loop_to_trace(bridge, FakeMetaInterpStaticData(self.cpu)) data = compile.BridgeCompileData(trace, self.convert_values(bridge.operations[-1].getarglist(), bridge_values), enable_opts=self.enable_opts, inline_short_preamble=inline_short_preamble) bridge_info, ops = self._do_optimize_loop(data) loop.check_consistency(check_descr=False) info.preamble.check_consistency(check_descr=False) bridge.operations = ([ResOperation(rop.LABEL, bridge_info.inputargs)] + ops) bridge.inputargs = bridge_info.inputargs bridge.check_consistency(check_descr=False) expected = self.parse(expected) self.assert_equal(bridge, convert_old_style_to_targets(expected, jump=True)) jump_bridge = bridge.operations[-1] jump_d = jump_bridge.getdescr() jump_args = jump_bridge.getarglist() if loop.operations[0].getdescr() is jump_d: # jump to loop label_args = loop.operations[0].getarglist() else: assert info.preamble.operations[0].getdescr() is jump_d label_args = info.preamble.operations[0].getarglist() assert len(jump_args) == len(label_args) for a, b in zip(jump_args, label_args): assert a.type == b.type
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 test_compile_loop(): cpu = FakeCPU() staticdata = FakeMetaInterpStaticData() staticdata.all_descrs = LLtypeMixin.cpu.setup_descrs() staticdata.cpu = cpu staticdata.jitlog = jl.JitLogger(cpu) staticdata.jitlog.trace_id = 1 # loop = parse(''' [p1] i1 = getfield_gc_i(p1, descr=valuedescr) i2 = int_add(i1, 1) p2 = new_with_vtable(descr=nodesize) setfield_gc(p2, i2, descr=valuedescr) jump(p2) ''', namespace=LLtypeMixin.__dict__.copy()) # metainterp = FakeMetaInterp() metainterp.staticdata = staticdata metainterp.cpu = cpu metainterp.history = History() t = convert_loop_to_trace(loop, staticdata) metainterp.history.inputargs = t.inputargs metainterp.history.trace = t # greenkey = 'faked' target_token = compile_loop( metainterp, greenkey, (0, 0, 0), t.inputargs, [t._mapping[x] for x in loop.operations[-1].getarglist()], use_unroll=False) jitcell_token = target_token.targeting_jitcell_token assert jitcell_token == target_token.original_jitcell_token assert jitcell_token.target_tokens == [target_token] assert jitcell_token.number == 2 # assert len(cpu.seen) == 1 assert cpu.seen[0][2] == jitcell_token # del cpu.seen[:]
def test_compile_loop(): cpu = FakeCPU() staticdata = FakeMetaInterpStaticData() staticdata.cpu = cpu staticdata.globaldata = FakeGlobalData() staticdata.globaldata.loopnumbering = 1 # loop = parse(''' [p1] i1 = getfield_gc_i(p1, descr=valuedescr) i2 = int_add(i1, 1) p2 = new_with_vtable(descr=nodesize) setfield_gc(p2, i2, descr=valuedescr) jump(p2) ''', namespace=LLtypeMixin.__dict__.copy()) # metainterp = FakeMetaInterp() metainterp.staticdata = staticdata metainterp.cpu = cpu metainterp.history = History() t = convert_loop_to_trace(loop, staticdata) metainterp.history.inputargs = t.inputargs metainterp.history.trace = t # greenkey = 'faked' target_token = compile_loop(metainterp, greenkey, (0, 0, 0), t.inputargs, [t._mapping[x] for x in loop.operations[-1].getarglist()], None) jitcell_token = target_token.targeting_jitcell_token assert jitcell_token == target_token.original_jitcell_token assert jitcell_token.target_tokens == [target_token] assert jitcell_token.number == 1 assert staticdata.globaldata.loopnumbering == 2 # assert len(cpu.seen) == 1 assert cpu.seen[0][2] == jitcell_token # del cpu.seen[:]