[pypy-svn] r79436 - in pypy/branch/jit-unroll-loops/pypy/jit: backend/llgraph metainterp metainterp/optimizeopt

hakanardo at codespeak.net hakanardo at codespeak.net
Tue Nov 23 21:15:42 CET 2010


Author: hakanardo
Date: Tue Nov 23 21:15:26 2010
New Revision: 79436

Modified:
   pypy/branch/jit-unroll-loops/pypy/jit/backend/llgraph/llimpl.py
   pypy/branch/jit-unroll-loops/pypy/jit/backend/llgraph/runner.py
   pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/optimizer.py
   pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/unroll.py
   pypy/branch/jit-unroll-loops/pypy/jit/metainterp/resoperation.py
Log:
Allow guards in the short inlined preamble by connecting them to jump to the original preamble on failure already when they are first emitted. What would it take to add this feature in the other backends aswell?

Modified: pypy/branch/jit-unroll-loops/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/jit-unroll-loops/pypy/jit/backend/llgraph/llimpl.py	(original)
+++ pypy/branch/jit-unroll-loops/pypy/jit/backend/llgraph/llimpl.py	Tue Nov 23 21:15:26 2010
@@ -365,6 +365,13 @@
     else:
         log.info("compiling new bridge")
 
+def compile_add_guard_jump_target(loop, loop_target):
+    loop = _from_opaque(loop)
+    loop_target = _from_opaque(loop_target)
+    op = loop.operations[-1]
+    assert op.is_guard()
+    op.jump_target = loop_target
+
 def compile_add_fail(loop, fail_index):
     loop = _from_opaque(loop)
     index = len(loop.operations)-1

Modified: pypy/branch/jit-unroll-loops/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/jit-unroll-loops/pypy/jit/backend/llgraph/runner.py	(original)
+++ pypy/branch/jit-unroll-loops/pypy/jit/backend/llgraph/runner.py	Tue Nov 23 21:15:26 2010
@@ -191,6 +191,12 @@
                         llimpl.compile_add_fail_arg(c, var2index[box])
                     else:
                         llimpl.compile_add_fail_arg(c, -1)
+                token = op.getjumptarget()
+                if token:
+                    assert isinstance(token, history.LoopToken)
+                    compiled_version = token._llgraph_compiled_version
+                    llimpl.compile_add_guard_jump_target(c, compiled_version)
+                        
             x = op.result
             if x is not None:
                 if isinstance(x, history.BoxInt):

Modified: pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/optimizer.py
==============================================================================
--- pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/optimizer.py	(original)
+++ pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/optimizer.py	Tue Nov 23 21:15:26 2010
@@ -419,6 +419,8 @@
 
     def store_final_boxes_in_guard(self, op):
         ###pendingfields = self.heap_op_optimizer.force_lazy_setfields_for_guard()
+        if op.getjumptarget():
+            return op
         descr = op.getdescr()
         assert isinstance(descr, compile.ResumeGuardDescr)
         modifier = resume.ResumeDataVirtualAdder(descr, self.resumedata_memo)

Modified: pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/unroll.py
==============================================================================
--- pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/unroll.py	(original)
+++ pypy/branch/jit-unroll-loops/pypy/jit/metainterp/optimizeopt/unroll.py	Tue Nov 23 21:15:26 2010
@@ -55,6 +55,7 @@
 
             short = self.create_short_preamble(loop.preamble.operations,
                                                loop.preamble.inputargs,
+                                               loop.preamble.token,
                                                loop.operations,
                                                loop.inputargs,
                                                loop.token)
@@ -72,6 +73,8 @@
                 assert isinstance(loop.preamble.token, LoopToken)
                 loop.preamble.token.short_preamble = short_loop
 
+                
+
                 # Clone ops and boxes to get private versions and forget the
                 # values to allow them to be freed
                 boxmap = {}
@@ -90,6 +93,13 @@
                             a = boxmap[a]
                         args.append(a)
                     op.initarglist(args)
+                    if op.is_guard():
+                        args = []
+                        for a in op.getfailargs():
+                            if not isinstance(a, Const):
+                                a = boxmap[a]
+                            args.append(a)
+                        op.setfailargs(args)
                     box = op.result
                     if box:
                         newbox = box.clonebox()
@@ -195,7 +205,7 @@
         except KeyError:
             return False
 
-    def create_short_preamble(self, preamble, preambleargs,
+    def create_short_preamble(self, preamble, preambleargs, preamble_token,
                               loop, inputargs, token):
         #return None # Dissable
 
@@ -203,17 +213,18 @@
         short_preamble = []
         loop_i = preamble_i = 0
         while preamble_i < len(preamble)-1:
-            if self.sameop(preamble[preamble_i], loop[loop_i]) \
+            op = preamble[preamble_i]
+            if self.sameop(op, loop[loop_i]) \
                and loop_i < len(loop)-1:
                 loop_i += 1
             else:
-                if not state.safe_to_move(preamble[preamble_i]):
+                if not state.safe_to_move(op):
                     debug_print("create_short_preamble failed due to",
-                                "unsafe op:", preamble[preamble_i].getopnum(),
+                                "unsafe op:", op.getopnum(),
                                 "at position: ", preamble_i)
                     return None
-                short_preamble.append(preamble[preamble_i])
-            state.update(preamble[preamble_i])
+                short_preamble.append(op)
+            state.update(op)
             preamble_i += 1
 
 
@@ -247,10 +258,7 @@
         jmp.setdescr(token)
         short_preamble.append(jmp)
 
-        # FIXME: Turn guards into conditional jumps to the preamble
-
-        # Check that boxes used as arguemts are produced. Might not be
-        # needed, but let's play it safe.
+        # Check that boxes used as arguemts are produced.
         seen = {}
         for box in preambleargs:
             seen[box] = True
@@ -263,6 +271,14 @@
             if op.result:
                 seen[op.result] = True
         
+        # Turn guards into conditional jumps to the preamble
+        for i in range(len(short_preamble)):
+            op = short_preamble[i]
+            if op.is_guard():
+                op = op.clone()
+                op.setfailargs(preambleargs)
+                op.setjumptarget(preamble_token)
+                short_preamble[i] = op
 
         return short_preamble
 
@@ -276,7 +292,7 @@
     # to preamble
     def safe_to_move(self, op):
         opnum = op.getopnum()
-        if op.is_always_pure():
+        if op.is_always_pure() or op.is_foldable_guard():
             return True
         elif opnum == rop.JUMP:
             return True
@@ -329,6 +345,10 @@
             newop = op.clone()
             args = newop.getarglist()
             newop.initarglist([self.inline_arg(a) for a in args])
+
+            if op.is_guard():
+                args = newop.getfailargs()
+                newop.setfailargs([self.inline_arg(a) for a in args])
             
             if newop.result:
                 old_result = newop.result

Modified: pypy/branch/jit-unroll-loops/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/jit-unroll-loops/pypy/jit/metainterp/resoperation.py	(original)
+++ pypy/branch/jit-unroll-loops/pypy/jit/metainterp/resoperation.py	Tue Nov 23 21:15:26 2010
@@ -198,6 +198,7 @@
 class GuardResOp(ResOpWithDescr):
 
     _fail_args = None
+    _jump_target = None
 
     def getfailargs(self):
         return self._fail_args
@@ -205,14 +206,22 @@
     def setfailargs(self, fail_args):
         self._fail_args = fail_args
 
+    def getjumptarget(self):
+        return self._jump_target
+
+    def setjumptarget(self, jump_target):
+        self._jump_target = jump_target
+
     def copy_and_change(self, opnum, args=None, result=None, descr=None):
         newop = AbstractResOp.copy_and_change(self, opnum, args, result, descr)
         newop.setfailargs(self.getfailargs())
+        newop.setjumptarget(self.getjumptarget())
         return newop
 
     def clone(self):
         newop = AbstractResOp.clone(self)
         newop.setfailargs(self.getfailargs())
+        newop.setjumptarget(self.getjumptarget())        
         return newop
 
 



More information about the Pypy-commit mailing list