Author: Hakan Ardo <ha...@debian.org> Branch: jit-targets Changeset: r48708:505538a47fdb Date: 2011-11-03 18:20 +0100 http://bitbucket.org/pypy/pypy/changeset/505538a47fdb/
Log: introduce targets that can be placed somewhere in a trace that can be used jump targets diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py --- a/pypy/jit/backend/llgraph/llimpl.py +++ b/pypy/jit/backend/llgraph/llimpl.py @@ -339,12 +339,16 @@ assert isinstance(type, str) and len(type) == 1 op.args.append(Descr(ofs, type, arg_types=arg_types)) -def compile_add_loop_token(loop, descr): +def compile_add_loop_token(loop, descr, clt): if we_are_translated(): raise ValueError("CALL_ASSEMBLER not supported") loop = _from_opaque(loop) op = loop.operations[-1] op.descr = weakref.ref(descr) + if op.opnum == rop.TARGET: + descr.compiled_loop_token = clt + descr.target_opindex = len(loop.operations) + descr.target_arguments = op.args def compile_add_var(loop, intvar): loop = _from_opaque(loop) @@ -380,13 +384,17 @@ _variables.append(v) return r -def compile_add_jump_target(loop, loop_target): +def compile_add_jump_target(loop, loop_target, target_opindex, target_inputargs): loop = _from_opaque(loop) loop_target = _from_opaque(loop_target) + if not target_inputargs: + target_inputargs = loop_target.inputargs op = loop.operations[-1] op.jump_target = loop_target + op.jump_target_opindex = target_opindex + op.jump_target_inputargs = target_inputargs assert op.opnum == rop.JUMP - assert len(op.args) == len(loop_target.inputargs) + assert len(op.args) == len(target_inputargs) if loop_target == loop: log.info("compiling new loop") else: @@ -520,10 +528,11 @@ self.opindex += 1 continue if op.opnum == rop.JUMP: - assert len(op.jump_target.inputargs) == len(args) - self.env = dict(zip(op.jump_target.inputargs, args)) + inputargs = op.jump_target_inputargs + assert len(inputargs) == len(args) + self.env = dict(zip(inputargs, args)) self.loop = op.jump_target - self.opindex = 0 + self.opindex = op.jump_target_opindex _stats.exec_jumps += 1 elif op.opnum == rop.FINISH: if self.verbose: @@ -616,6 +625,9 @@ # return _op_default_implementation + def op_target(self, _, *args): + pass + def op_debug_merge_point(self, _, *args): from pypy.jit.metainterp.warmspot import get_stats try: diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -136,7 +136,7 @@ clt = original_loop_token.compiled_loop_token clt.loop_and_bridges.append(c) clt.compiling_a_bridge() - self._compile_loop_or_bridge(c, inputargs, operations) + self._compile_loop_or_bridge(c, inputargs, operations, clt) old, oldindex = faildescr._compiled_fail llimpl.compile_redirect_fail(old, oldindex, c) @@ -151,14 +151,16 @@ clt.loop_and_bridges = [c] clt.compiled_version = c looptoken.compiled_loop_token = clt - self._compile_loop_or_bridge(c, inputargs, operations) + looptoken.target_opindex = 0 + looptoken.target_arguments = None + self._compile_loop_or_bridge(c, inputargs, operations, clt) def free_loop_and_bridges(self, compiled_loop_token): for c in compiled_loop_token.loop_and_bridges: llimpl.mark_as_free(c) model.AbstractCPU.free_loop_and_bridges(self, compiled_loop_token) - def _compile_loop_or_bridge(self, c, inputargs, operations): + def _compile_loop_or_bridge(self, c, inputargs, operations, clt): var2index = {} for box in inputargs: if isinstance(box, history.BoxInt): @@ -170,19 +172,19 @@ var2index[box] = llimpl.compile_start_float_var(c) else: raise Exception("box is: %r" % (box,)) - self._compile_operations(c, operations, var2index) + self._compile_operations(c, operations, var2index, clt) return c - def _compile_operations(self, c, operations, var2index): + def _compile_operations(self, c, operations, var2index, clt): for op in operations: llimpl.compile_add(c, op.getopnum()) descr = op.getdescr() if isinstance(descr, Descr): llimpl.compile_add_descr(c, descr.ofs, descr.typeinfo, descr.arg_types) - if (isinstance(descr, history.LoopToken) and - op.getopnum() != rop.JUMP): - llimpl.compile_add_loop_token(c, descr) + if isinstance(descr, history.LoopToken): + if op.getopnum() != rop.JUMP: + llimpl.compile_add_loop_token(c, descr, clt) if self.is_oo and isinstance(descr, (OODescr, MethDescr)): # hack hack, not rpython c._obj.externalobj.operations[-1].setdescr(descr) @@ -238,7 +240,8 @@ targettoken = op.getdescr() assert isinstance(targettoken, history.LoopToken) compiled_version = targettoken.compiled_loop_token.compiled_version - llimpl.compile_add_jump_target(c, compiled_version) + opindex = targettoken.target_opindex + llimpl.compile_add_jump_target(c, compiled_version, opindex, targettoken.target_arguments) elif op.getopnum() == rop.FINISH: faildescr = op.getdescr() index = self.get_fail_descr_number(faildescr) diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2965,7 +2965,48 @@ fail = self.cpu.execute_token(looptoken) assert fail.identifier == excdescr.identifier + def test_compile_loop_with_target(self): + i0 = BoxInt() + i1 = BoxInt() + i2 = BoxInt() + i3 = BoxInt() + looptoken = LoopToken() + targettoken = LoopToken() + faildescr = BasicFailDescr(2) + operations = [ + ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1), + ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2), + ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr), + ResOperation(rop.TARGET, [i1], None, descr=targettoken), + ResOperation(rop.INT_GE, [i1, ConstInt(0)], i3), + ResOperation(rop.GUARD_TRUE, [i3], None, descr=BasicFailDescr(3)), + ResOperation(rop.JUMP, [i1], None, descr=looptoken), + ] + inputargs = [i0] + operations[2].setfailargs([i1]) + operations[5].setfailargs([i1]) + self.cpu.compile_loop(inputargs, operations, looptoken) + self.cpu.set_future_value_int(0, 2) + fail = self.cpu.execute_token(looptoken) + assert fail.identifier == 2 + res = self.cpu.get_latest_value_int(0) + assert res == 10 + + inputargs = [i0] + operations = [ + ResOperation(rop.INT_SUB, [i0, ConstInt(20)], i2), + ResOperation(rop.JUMP, [i2], None, descr=targettoken), + ] + self.cpu.compile_bridge(faildescr, inputargs, operations, looptoken) + + self.cpu.set_future_value_int(0, 2) + fail = self.cpu.execute_token(looptoken) + assert fail.identifier == 3 + res = self.cpu.get_latest_value_int(0) + assert res == -10 + + class OOtypeBackendTest(BaseBackendTest): type_system = 'ootype' diff --git a/pypy/jit/metainterp/executor.py b/pypy/jit/metainterp/executor.py --- a/pypy/jit/metainterp/executor.py +++ b/pypy/jit/metainterp/executor.py @@ -342,6 +342,7 @@ rop.SETARRAYITEM_RAW, rop.CALL_RELEASE_GIL, rop.QUASIIMMUT_FIELD, + rop.TARGET, ): # list of opcodes never executed by pyjitpl continue raise AssertionError("missing %r" % (key,)) diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -366,6 +366,8 @@ 'FINISH/*d', '_FINAL_LAST', + 'TARGET/*d', + '_GUARD_FIRST', '_GUARD_FOLDABLE_FIRST', 'GUARD_TRUE/1d', _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit