[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