[pypy-svn] r63431 - in pypy/branch/pyjitpl5-loop/pypy/jit: backend/llgraph metainterp

arigo at codespeak.net arigo at codespeak.net
Mon Mar 30 12:05:30 CEST 2009


Author: arigo
Date: Mon Mar 30 12:05:28 2009
New Revision: 63431

Modified:
   pypy/branch/pyjitpl5-loop/pypy/jit/backend/llgraph/runner.py
   pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/compile.py
   pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/history.py
   pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/optimize.py
   pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/resoperation.py
Log:
Check this in for now.  I am going to look more at the pyjitpl5-simplify
branch instead.


Modified: pypy/branch/pyjitpl5-loop/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-loop/pypy/jit/backend/llgraph/runner.py	(original)
+++ pypy/branch/pyjitpl5-loop/pypy/jit/backend/llgraph/runner.py	Mon Mar 30 12:05:28 2009
@@ -98,6 +98,20 @@
         return c
 
     def _get_loop_args(self, c, loop):
+        var2index = self._get_loop_args(c, loop)
+        self._compile_branch(c, loop.operations, var2index, rop.JUMP)
+
+    def compile_bridge(self, fail_op, bridge):
+        """Like compile_loop, but produce the bridge operations going from
+        the guard that precedes the given FAIL operation.  It should patch
+        the conditional jump on this guard to now execute the given bridge.
+        """
+        c = llimpl.compile_restart(fail_op._fail_position)
+        bridge._compiled_version = c
+        var2index = self._get_loop_args(c, bridge)
+        self._compile_branch(c, bridge.operations, var2index, rop.JUMP)
+
+    def _get_loop_args(self, c, loop):
         var2index = {}
         for box in loop.inputargs:
             if isinstance(box, history.BoxInt):

Modified: pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/compile.py	(original)
+++ pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/compile.py	Mon Mar 30 12:05:28 2009
@@ -113,7 +113,7 @@
     loop.operations = history.operations
     loop.operations[-1].jump_target = loop
     mark_keys_in_loop(loop, loop.operations)
-    send_loop_to_backend(metainterp, loop, True)
+    send_loop_to_backend(metainterp, loop)
     metainterp.stats.loops.append(loop)
     old_loops.append(loop)
     return loop
@@ -126,14 +126,11 @@
     if op.opnum == rop.FAIL:
         op.key.loop = loop
 
-def send_loop_to_backend(metainterp, loop, is_loop):
-    metainterp.cpu.compile_operations(loop)
+def send_loop_to_backend(metainterp, loop):
+    metainterp.cpu.compile_loop(loop)
     metainterp.stats.compiled_count += 1
     if not we_are_translated():
-        if is_loop:
-            log.info("compiling new loop")
-        else:
-            log.info("compiling new bridge")
+        log.info("compiling new loop")
 
 # ____________________________________________________________
 
@@ -153,3 +150,8 @@
     mark_keys_in_loop(source_loop, guard_op.suboperations)
     send_loop_to_backend(metainterp, source_loop, False)
     return target_loop
+
+def send_bridge_to_backend(metainterp, bridge):
+    xxx
+    if not we_are_translated():
+        log.info("compiling new bridge")

Modified: pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/history.py	(original)
+++ pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/history.py	Mon Mar 30 12:05:28 2009
@@ -338,7 +338,7 @@
         # self.inputargs = list of distinct Boxes
         # self.operations = list of ResOperations
         #   ops of the kind 'guard_xxx' contain a further list of operations,
-        #   which may itself contain 'guard_xxx' and so on, making a tree.
+        #   which must end with a FAIL.
 
     def _all_operations(self, omit_fails=False):
         "NOT_RPYTHON"

Modified: pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/optimize.py	(original)
+++ pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/optimize.py	Mon Mar 30 12:05:28 2009
@@ -209,18 +209,6 @@
     perfect_specializer.optimize_loop()
     return None
 
-def optimize_bridge(options, old_loops, history, cpu=None):
-    if not options.specialize:         # for tests only
-        return old_loops[0]
-
-    perfect_specializer = PerfectSpecializer(history, options, cpu)
-    perfect_specializer.find_nodes()
-    for old_loop in old_loops:
-        if perfect_specializer.match(old_loop):
-            perfect_specializer.adapt_for_match(old_loop)
-            perfect_specializer.optimize_loop()
-            return old_loop
-    return None     # no loop matches
 
 class PerfectSpecializer(object):
     _allow_automatic_node_creation = False
@@ -507,7 +495,7 @@
         assert len(op.suboperations) == 1
         op_fail = op.suboperations[0]
         assert op_fail.opnum == rop.FAIL
-        old_boxes = op.suboperations[0].args
+        old_boxes = op_fail.args
         unoptboxes = []
         for box in old_boxes:
             if isinstance(box, Const):
@@ -547,8 +535,10 @@
 #                 rebuild_ops.append(op1)
 #         # end of code for dirtyfields support
 
+        op_fail = op_fail.clone()
         op_fail.args = unoptboxes
         rebuild_ops.append(op_fail)
+        op = op.clone()
         op.suboperations = rebuild_ops
         return op
 
@@ -622,6 +612,7 @@
                     if arg in self.nodes:
                         assert not self.nodes[arg].virtual
                 #self.cleanup_field_caches(newoperations)
+                op = op.clone()
                 op.args = args
                 newoperations.append(op)
                 break
@@ -746,6 +737,7 @@
                     self.nodes[box] = instnode
                     continue
             # default handling of arguments and return value
+            op = op.clone()
             op.args = self.new_arguments(op)
             if op.is_always_pure():
                 for box in op.args:
@@ -806,25 +798,58 @@
                 return False
         return True
 
-    def match(self, old_loop):
-        jump_op = self.history.operations[-1]
-        assert jump_op.opnum == rop.JUMP
-        assert len(old_loop.specnodes) == len(jump_op.args)
-        for i in range(len(old_loop.specnodes)):
-            old_specnode = old_loop.specnodes[i]
-            new_instnode = self.getnode(jump_op.args[i])
-            if not old_specnode.matches(new_instnode):
-                return False
-        return True
+    def _patch(self, origargs, newargs):
+        i = 0
+        res = []
+        for arg in newargs:
+            if arg is None:
+                res.append(origargs[i])
+                i += 1
+            else:
+                res.append(arg)
+        return res
 
-    def adapt_for_match(self, old_loop):
-        jump_op = self.history.operations[-1]
-        assert jump_op.opnum == rop.JUMP
-        self.specnodes = old_loop.specnodes
-        for i in range(len(old_loop.specnodes)):
-            old_specnode = old_loop.specnodes[i]
-            new_instnode = self.getnode(jump_op.args[i])
-            old_specnode.adapt_to(new_instnode)
+    def _patch_loop(self, operations, inpargs, rebuild_ops, loop):
+        for op in operations:
+            if op.is_guard():
+                if op.suboperations[-1].opnum == rop.FAIL:
+                    op.suboperations = (op.suboperations[:-1] + rebuild_ops +
+                                        [op.suboperations[-1]])
+                else:
+                    self._patch_loop(op.suboperations, inpargs, rebuild_ops,
+                                     loop)
+        jump = operations[-1]
+        if jump.opnum == rop.JUMP and jump.jump_target is loop:
+            jump.args = self._patch(jump.args, inpargs)
+
+    def update_loop(self, offsets, loop):
+        j = 0
+        new_inputargs = []
+        prev_ofs = 0
+        rebuild_ops = []
+        memo = {}
+        for i in range(len(offsets)):
+            for specnode, descr, parentnode, rel_ofs, node in offsets[i]:
+                while parentnode.source != loop.inputargs[j]:
+                    j += 1
+                ofs = j + rel_ofs + 1
+                new_inputargs.extend([None] * (ofs - prev_ofs))
+                prev_ofs = ofs
+                boxlist = []
+                specnode.expand_boxlist(node, boxlist)
+                new_inputargs.extend(boxlist)
+                box = self.prepare_rebuild_ops(node, rebuild_ops, memo)
+                if (parentnode.cls and
+                    isinstance(parentnode.cls.source, FixedList)):
+                    rebuild_ops.append(ResOperation(rop.SETARRAYITEM_GC,
+                      [parentnode.source, descr, box], None,
+                      parentnode.cls.source.arraydescr))
+                else:
+                    rebuild_ops.append(ResOperation(rop.SETFIELD_GC,
+                      [parentnode.source, box], None, descr))
+        new_inputargs.extend([None] * (len(loop.inputargs) - prev_ofs))
+        loop.inputargs = self._patch(loop.inputargs, new_inputargs)
+        self._patch_loop(loop.operations, new_inputargs, rebuild_ops, loop)
 
 def get_in_list(dict, boxes_or_consts):
     result = []

Modified: pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/resoperation.py	(original)
+++ pypy/branch/pyjitpl5-loop/pypy/jit/metainterp/resoperation.py	Mon Mar 30 12:05:28 2009
@@ -32,13 +32,10 @@
         self.descr = descr
 
     def clone(self):
-        "NOT_RPYTHON"     # for tests only
         res = ResOperation(self.opnum, self.args, self.result, self.descr)
         res.jump_target = self.jump_target
         res.key = self.key
         res.vdesc = self.vdesc
-        if self.suboperations is not None:
-            res.suboperations = [op.clone() for op in self.suboperations]
         return res
 
     def __repr__(self):



More information about the Pypy-commit mailing list