[pypy-svn] pypy jit-usable_retrace: Allow a retraced loop to be passed information from the bridge causing the retrace.
hakanardo
commits-noreply at bitbucket.org
Sun Feb 20 19:10:52 CET 2011
Author: Hakan Ardo <hakan at debian.org>
Branch: jit-usable_retrace
Changeset: r42189:92b25ad0e9c0
Date: 2011-02-20 19:10 +0100
http://bitbucket.org/pypy/pypy/changeset/92b25ad0e9c0/
Log: Allow a retraced loop to be passed information from the bridge
causing the retrace.
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
@@ -621,8 +621,8 @@
return self.map[loopbox]
class OptInlineShortPreamble(Optimization):
- def __init__(self, retraced):
- self.retraced = retraced
+ def __init__(self, retrace):
+ self.retrace = retrace
self.inliner = None
@@ -638,6 +638,10 @@
# memory. This should also allow better behaviour in
# situations that the is_emittable() chain currently cant
# handle and the inlining fails unexpectedly belwo.
+ if self.retrace:
+ jump_args = op.getarglist()
+ jump_values = [self.getvalue(a) for a in jump_args]
+ self.retrace.compile(jump_values)
short = descr.short_preamble
if short:
args = op.getarglist()
@@ -683,7 +687,7 @@
if descr.failed_states:
retraced_count += len(descr.failed_states)
limit = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.retrace_limit
- if not self.retraced and retraced_count<limit:
+ if not self.retrace and retraced_count<limit:
if not descr.failed_states:
raise RetraceLoop
for failed in descr.failed_states:
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
@@ -80,19 +80,17 @@
# ____________________________________________________________
-def compile_new_loop(metainterp, old_loop_tokens, greenkey, start,
+def compile_new_loop(metainterp, old_loop_tokens, greenkey, inputargs, h_ops,
start_resumedescr, full_preamble_needed=True):
"""Try to compile a new loop by closing the current history back
to the first operation.
"""
- history = metainterp.history
loop = create_empty_loop(metainterp)
- loop.inputargs = history.inputargs
+ loop.inputargs = inputargs
for box in loop.inputargs:
assert isinstance(box, Box)
# make a copy, because optimize_loop can mutate the ops and descrs
- h_ops = history.operations
- loop.operations = [h_ops[i].clone() for i in range(start, len(h_ops))]
+ loop.operations = [h_ops[i].clone() for i in range(len(h_ops))]
metainterp_sd = metainterp.staticdata
jitdriver_sd = metainterp.jitdriver_sd
loop_token = make_loop_token(len(loop.inputargs), jitdriver_sd)
@@ -566,7 +564,7 @@
pass
-def compile_new_bridge(metainterp, old_loop_tokens, resumekey, retraced=False):
+def compile_new_bridge(metainterp, old_loop_tokens, resumekey, retrace=None):
"""Try to compile a new bridge leading from the beginning of the history
to some existing place.
"""
@@ -589,7 +587,7 @@
target_loop_token = state.optimize_bridge(metainterp_sd,
old_loop_tokens, new_loop,
inline_short_preamble,
- retraced)
+ retrace)
except InvalidLoop:
# XXX I am fairly convinced that optimize_bridge cannot actually raise
# InvalidLoop
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -1878,7 +1878,10 @@
old_loop_tokens = self.get_compiled_merge_points(greenkey)
self.history.record(rop.JUMP, live_arg_boxes[num_green_args:], None)
loop_token = compile.compile_new_loop(self, old_loop_tokens,
- greenkey, start, start_resumedescr)
+ greenkey,
+ self.history.inputargs,
+ self.history.operations[start:],
+ start_resumedescr)
if loop_token is not None: # raise if it *worked* correctly
self.set_compiled_merge_points(greenkey, old_loop_tokens)
raise GenerateMergePoint(live_arg_boxes, loop_token)
@@ -1913,14 +1916,11 @@
self.history.inputargs = original_boxes[num_green_args:]
greenkey = original_boxes[:num_green_args]
self.history.record(rop.JUMP, live_arg_boxes[num_green_args:], None)
- loop_token = compile.compile_new_loop(self, [], greenkey, start,
- start_resumedescr, False)
+ retrace = RetraceCompiler(self, greenkey,
+ original_boxes[num_green_args:],
+ self.history.operations[start:],
+ start_resumedescr, old_loop_tokens[0])
self.history.operations.pop() # remove the JUMP
- if loop_token is None:
- return
-
- if loop_token.short_preamble:
- old_loop_tokens[0].short_preamble.extend(loop_token.short_preamble)
self.history.inputargs = original_inputargs
self.history.operations = self.history.operations[:start]
@@ -1931,7 +1931,7 @@
#[loop_token],
old_loop_tokens,
self.resumekey,
- True)
+ retrace)
except RetraceLoop:
assert False
assert target_loop_token is not None
@@ -2469,3 +2469,29 @@
frame._put_back_list_of_boxes(newvalue, 0, position)
frame._put_back_list_of_boxes(newvalue, length1, position2)
frame._put_back_list_of_boxes(newvalue, length1 + length2, position3)
+
+class RetraceCompiler(object):
+ def __init__(self, metainterp, greenkey, inputargs, h_ops,
+ start_resumedescr, parent):
+ self.metainterp = metainterp
+ self.greenkey = greenkey
+ self.inputargs = inputargs
+ self.h_ops = h_ops
+ self.start_resumedescr = start_resumedescr
+ self.parent = parent
+
+ def compile(self, values):
+ assert len(values) == len(self.inputargs)
+ loop_token = compile.compile_new_loop(self.metainterp, [],
+ self.greenkey,
+ self.inputargs, self.h_ops,
+ self.start_resumedescr, False)
+ if loop_token is None:
+ return
+
+ if loop_token.short_preamble:
+ self.parent.short_preamble.extend(loop_token.short_preamble)
+
+
+
+
diff --git a/pypy/jit/metainterp/nounroll_optimize.py b/pypy/jit/metainterp/nounroll_optimize.py
--- a/pypy/jit/metainterp/nounroll_optimize.py
+++ b/pypy/jit/metainterp/nounroll_optimize.py
@@ -18,7 +18,7 @@
return None
def optimize_bridge(metainterp_sd, old_loop_tokens, bridge,
- inline_short_preamble, retraced=False):
+ inline_short_preamble, retraced=None):
debug_start("jit-optimize")
try:
return _optimize_bridge(metainterp_sd, old_loop_tokens, bridge)
diff --git a/pypy/jit/metainterp/optimize.py b/pypy/jit/metainterp/optimize.py
--- a/pypy/jit/metainterp/optimize.py
+++ b/pypy/jit/metainterp/optimize.py
@@ -23,7 +23,7 @@
# ____________________________________________________________
def optimize_bridge(metainterp_sd, old_loop_tokens, bridge,
- inline_short_preamble=True, retraced=False):
+ inline_short_preamble=True, retraced=None):
debug_start("jit-optimize")
try:
return _optimize_bridge(metainterp_sd, old_loop_tokens, bridge,
@@ -32,7 +32,7 @@
debug_stop("jit-optimize")
def _optimize_bridge(metainterp_sd, old_loop_tokens, bridge,
- inline_short_preamble, retraced=False):
+ inline_short_preamble, retraced=None):
cpu = metainterp_sd.cpu
metainterp_sd.logger_noopt.log_loop(bridge.inputargs, bridge.operations)
if old_loop_tokens:
diff --git a/pypy/jit/metainterp/optimizeopt/__init__.py b/pypy/jit/metainterp/optimizeopt/__init__.py
--- a/pypy/jit/metainterp/optimizeopt/__init__.py
+++ b/pypy/jit/metainterp/optimizeopt/__init__.py
@@ -7,7 +7,7 @@
from pypy.jit.metainterp.optimizeopt.unroll import optimize_unroll, OptInlineShortPreamble
def optimize_loop_1(metainterp_sd, loop, unroll=True,
- inline_short_preamble=True, retraced=False):
+ inline_short_preamble=True, retraced=None):
"""Optimize loop.operations to remove internal overheadish operations.
"""
opt_str = OptString()
@@ -35,7 +35,7 @@
optimizer.propagate_all_forward()
def optimize_bridge_1(metainterp_sd, bridge, inline_short_preamble=True,
- retraced=False):
+ retraced=None):
"""The same, but for a bridge. """
optimize_loop_1(metainterp_sd, bridge, False, inline_short_preamble,
retraced)
More information about the Pypy-commit
mailing list