[pypy-commit] pypy jit-targets: introduce targets that can be placed somewhere in a trace that can be used jump targets
hakanardo
noreply at buildbot.pypy.org
Thu Nov 3 18:21:09 CET 2011
Author: Hakan Ardo <hakan at 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',
More information about the pypy-commit
mailing list