[pypy-commit] pypy jit-targets: fall back on jumping to preamble if retracing fails
hakanardo
noreply at buildbot.pypy.org
Sat Dec 10 14:27:55 CET 2011
Author: Hakan Ardo <hakan at debian.org>
Branch: jit-targets
Changeset: r50343:f78f16899afb
Date: 2011-12-10 14:27 +0100
http://bitbucket.org/pypy/pypy/changeset/f78f16899afb/
Log: fall back on jumping to preamble if retracing fails
diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -209,7 +209,18 @@
try:
optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts)
except InvalidLoop:
- return None
+ # Fall back on jumping to preamble
+ target_token = label.getdescr()
+ assert isinstance(target_token, TargetToken)
+ assert target_token.exported_state
+ part.operations = [label] + \
+ [ResOperation(rop.JUMP, target_token.exported_state.original_jump_args,
+ None, descr=loop_jitcell_token)]
+ try:
+ optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts,
+ inline_short_preamble=False)
+ except InvalidLoop:
+ return None
assert part.operations[-1].getopnum() != rop.LABEL
target_token = label.getdescr()
assert isinstance(target_token, TargetToken)
diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -171,7 +171,7 @@
target_token.start_resumedescr = start_resumedescr
target_token.exported_state = ExportedState(constant_inputargs, short_boxes,
inputarg_setup_ops, self.optimizer,
- aliased_vrituals)
+ aliased_vrituals, original_jump_args)
def import_state(self, targetop):
self.did_import = False
@@ -275,7 +275,6 @@
try:
jumpargs = virtual_state.make_inputargs(values, self.optimizer)
except BadVirtualState:
- # FIXME: Produce jump to preamble instead (see test_retrace_not_matching_bridge)
raise InvalidLoop
jumpop.initarglist(jumpargs)
@@ -340,13 +339,11 @@
if not virtual_state.generalization_of(final_virtual_state, bad):
# We ended up with a virtual state that is not compatible
# and we are thus unable to jump to the start of the loop
- # XXX Is it possible to end up here? If so, consider:
- # - Fallback on having the preamble jump to itself?
- # - Would virtual_state.generate_guards make sense here?
final_virtual_state.debug_print("Bad virtual state at end of loop, ",
bad)
debug_stop('jit-log-virtualstate')
raise InvalidLoop
+
debug_stop('jit-log-virtualstate')
maxguards = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.max_retrace_guards
@@ -595,9 +592,11 @@
class ExportedState(object):
def __init__(self, constant_inputargs,
- short_boxes, inputarg_setup_ops, optimizer, aliased_vrituals):
+ short_boxes, inputarg_setup_ops, optimizer, aliased_vrituals,
+ original_jump_args):
self.constant_inputargs = constant_inputargs
self.short_boxes = short_boxes
self.inputarg_setup_ops = inputarg_setup_ops
self.optimizer = optimizer
self.aliased_vrituals = aliased_vrituals
+ self.original_jump_args = original_jump_args
diff --git a/pypy/jit/metainterp/test/test_virtual.py b/pypy/jit/metainterp/test/test_virtual.py
--- a/pypy/jit/metainterp/test/test_virtual.py
+++ b/pypy/jit/metainterp/test/test_virtual.py
@@ -820,6 +820,91 @@
return node.value
res = self.meta_interp(f, [10], repeat=10)
assert res == f(10)
+ self.check_resops(jump=2)
+
+ def test_nested_loops(self):
+ class Int(object):
+ def __init__(self, val):
+ self.val = val
+ myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'sa', 'i', 'j'])
+ bytecode = "iajb+JI"
+ def f(n):
+ pc = sa = 0
+ i = j = Int(0)
+ while pc < len(bytecode):
+ myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i, j=j)
+ op = bytecode[pc]
+ if op == 'i':
+ i = Int(0)
+ elif op == 'j':
+ j = Int(0)
+ elif op == '+':
+ sa += i.val * j.val
+ elif op == 'a':
+ i = Int(i.val + 1)
+ elif op == 'b':
+ j = Int(j.val + 1)
+ elif op == 'J':
+ if j.val < n:
+ pc -= 2
+ myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j)
+ continue
+ elif op == 'I':
+ if i.val < n:
+ pc -= 5
+ myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j)
+ continue
+ pc += 1
+ return sa
+
+ res = self.meta_interp(f, [10])
+ assert res == f(10)
+ self.check_aborted_count(0)
+ self.check_target_token_count(3)
+
+ def test_nested_loops_bridge(self):
+ class Int(object):
+ def __init__(self, val):
+ self.val = val
+ myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'sa', 'i', 'j'])
+ bytecode = "iajb+JI"
+ def f(n):
+ pc = sa = 0
+ i = j = Int(0)
+ while pc < len(bytecode):
+ myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i, j=j)
+ op = bytecode[pc]
+ if op == 'i':
+ i = Int(0)
+ elif op == 'j':
+ j = Int(0)
+ elif op == '+':
+ if i.val < n-8:
+ sa += 7
+ if j.val < n-16:
+ sa += 42
+ sa += i.val * j.val
+ elif op == 'a':
+ i = Int(i.val + 1)
+ elif op == 'b':
+ j = Int(j.val + 1)
+ elif op == 'J':
+ if j.val < n:
+ pc -= 2
+ myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j)
+ continue
+ elif op == 'I':
+ if i.val < n:
+ pc -= 5
+ myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j)
+ continue
+ pc += 1
+ return sa
+
+ res = self.meta_interp(f, [32])
+ assert res == f(32)
+ self.check_aborted_count(0)
+ self.check_target_token_count(3)
class VirtualMiscTests:
More information about the pypy-commit
mailing list