[pypy-svn] r63257 - in pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp: . test

arigo at codespeak.net arigo at codespeak.net
Mon Mar 23 21:22:58 CET 2009


Author: arigo
Date: Mon Mar 23 21:22:55 2009
New Revision: 63257

Modified:
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/optimize.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py
   pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py
Log:
Make optimize.py pass again (first step).


Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py	Mon Mar 23 21:22:55 2009
@@ -5,7 +5,7 @@
 from pypy.conftest import option
 
 from pypy.jit.metainterp.resoperation import ResOperation, rop
-from pypy.jit.metainterp.history import Loop, log, Box
+from pypy.jit.metainterp.history import TreeLoop, log, Box
 from pypy.jit.metainterp import optimize
 
 
@@ -101,7 +101,7 @@
         name = 'Loop'
     else:
         name = 'Loop #%d' % len(metainterp.stats.loops)
-    return Loop(name)
+    return TreeLoop(name)
 
 # ____________________________________________________________
 
@@ -114,13 +114,14 @@
     loop.inputargs = history.inputargs
     loop.operations = history.operations
     close_loop(loop, endliveboxes)
-    #old_loop = optimize.optimize_loop(metainterp.options, old_loops, loop,
-    #                                  metainterp.cpu)
-    #if old_loop is not None:
-    #    return old_loop
+    old_loop = optimize.optimize_loop(metainterp.options, old_loops, loop,
+                                      metainterp.cpu)
+    if old_loop is not None:
+        return old_loop
     mark_keys_in_loop(loop, loop.operations)
     send_loop_to_backend(metainterp, loop)
     metainterp.stats.loops.append(loop)
+    metainterp.stats.compiled_count += 1
     old_loops.append(loop)
     return loop
 
@@ -164,4 +165,5 @@
     guard_op.suboperations = history.operations
     mark_keys_in_loop(source_loop, guard_op.suboperations)
     send_loop_to_backend(metainterp, source_loop)
+    metainterp.stats.compiled_count += 1
     return target_loop

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py	Mon Mar 23 21:22:55 2009
@@ -324,11 +324,11 @@
 
 # ____________________________________________________________
 
-# The Loop class contains a loop or a generalized loop, i.e. a tree
+# The TreeLoop class contains a loop or a generalized loop, i.e. a tree
 # of operations.  Each branch ends in a jump which can go either to
-# the top of the same loop, or to another loop.
+# the top of the same loop, or to another TreeLoop.
 
-class Loop(object):
+class TreeLoop(object):
     inputargs = None
     specnodes = None
     operations = None
@@ -340,18 +340,16 @@
         #   ops of the kind 'guard_xxx' contain a further list of operations,
         #   which may itself contain 'guard_xxx' and so on, making a tree.
 
-    def _all_operations(self):
+    def _all_operations(self, omit_fails=False):
         "NOT_RPYTHON"
-        oplist = list(self.operations)
-        for op in oplist:
-            if op.is_guard():
-                oplist += op.suboperations
-        return oplist
+        result = []
+        _list_all_operations(result, self.operations, omit_fails)
+        return result
 
     def summary(self, adding_insns={}):    # for debugging
         "NOT_RPYTHON"
         insns = adding_insns.copy()
-        for op in self._all_operations():
+        for op in self._all_operations(omit_fails=True):
             opname = op.getopname()
             insns[opname] = insns.get(opname, 0) + 1
         return insns
@@ -392,11 +390,19 @@
                 seen[box] = True
         assert operations[-1].is_final()
         if operations[-1].opnum == rop.JUMP:
-            assert isinstance(operations[-1].jump_target, Loop)
+            assert isinstance(operations[-1].jump_target, TreeLoop)
 
     def __repr__(self):
         return '<%s>' % (self.name,)
 
+def _list_all_operations(result, operations, omit_fails=True):
+    if omit_fails and operations[-1].opnum == rop.FAIL:
+        return
+    result.extend(operations)
+    for op in operations:
+        if op.is_guard():
+            _list_all_operations(result, op.suboperations, omit_fails)
+
 # ____________________________________________________________
 
 
@@ -442,6 +448,7 @@
 
     def __init__(self):
         self.loops = []
+        self.compiled_count = 0
 
     def get_all_loops(self):
         return self.loops
@@ -452,9 +459,6 @@
             opname = op.getopname()
             insns[opname] = insns.get(opname, 0) + 1
         if expected is not None:
-            # 'fail' operations may be omitted from 'expected'
-            if 'fail' in insns:
-                expected.setdefault('fail', insns['fail'])
             assert insns == expected
         for insn, expected_count in check.items():
             assert insns.get(insn, 0) == expected_count
@@ -465,9 +469,6 @@
         for loop in self.loops:
             insns = loop.summary(adding_insns=insns)
         if expected is not None:
-            # 'fail' operations may be omitted from 'expected'
-            if 'fail' in insns:
-                expected.setdefault('fail', insns['fail'])
             assert insns == expected
         for insn, expected_count in check.items():
             assert insns.get(insn, 0) == expected_count

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/optimize.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/optimize.py	Mon Mar 23 21:22:55 2009
@@ -279,17 +279,13 @@
     def find_nodes(self):
         # Steps (1) and (2)
         self.first_escaping_op = True
-        # only catch can have consts
-        for box in self.loop.operations[0].args:
-            self.nodes[box] = InstanceNode(box, escaped=False, startbox=True,
-                                           const=isinstance(box, Const))
+        for box in self.loop.inputargs:
+            self.nodes[box] = InstanceNode(box, escaped=False, startbox=True)
         for op in self.loop.operations:
             #print '| ' + op.repr()
             opnum = op.opnum
-            if (opnum == rop.MERGE_POINT or
-                opnum == rop.CATCH or
-                opnum == rop.JUMP):
-                continue
+            if opnum == rop.JUMP:
+                break
             elif opnum == rop.NEW_WITH_VTABLE:
                 box = op.result
                 instnode = InstanceNode(box, escaped=False)
@@ -392,15 +388,15 @@
                 self.nodes[box] = InstanceNode(box, escaped=True)
 
     def recursively_find_escaping_values(self):
-        assert self.loop.operations[0].opnum == rop.MERGE_POINT
         end_args = self.loop.operations[-1].args
+        assert len(self.loop.inputargs) == len(end_args)
         memo = {}
         for i in range(len(end_args)):
             end_box = end_args[i]
             if isinstance(end_box, Box):
                 self.nodes[end_box].escape_if_startbox(memo)
         for i in range(len(end_args)):
-            box = self.loop.operations[0].args[i]
+            box = self.loop.inputargs[i]
             other_box = end_args[i]
             if isinstance(other_box, Box):
                 self.nodes[box].add_to_dependency_graph(self.nodes[other_box],
@@ -418,13 +414,11 @@
     def intersect_input_and_output(self):
         # Step (3)
         self.recursively_find_escaping_values()
-        mp = self.loop.operations[0]
         jump = self.loop.operations[-1]
-        assert mp.opnum == rop.MERGE_POINT
         assert jump.opnum == rop.JUMP
         specnodes = []
-        for i in range(len(mp.args)):
-            enternode = self.nodes[mp.args[i]]
+        for i in range(len(self.loop.inputargs)):
+            enternode = self.nodes[self.loop.inputargs[i]]
             leavenode = self.getnode(jump.args[i])
             specnodes.append(enternode.intersect(leavenode, self.nodes))
         self.specnodes = specnodes
@@ -439,7 +433,7 @@
             specnode.expand_boxlist(self.nodes[box], newboxlist, oplist)
         return newboxlist
 
-    def prepare_rebuild_ops(self, instnode, liveboxes, rebuild_ops, memo):
+    def prepare_rebuild_ops(self, instnode, rebuild_ops, memo):
         box = instnode.source
         if not isinstance(box, Box):
             return box
@@ -465,8 +459,7 @@
             rebuild_ops.append(op)
             memo[box] = newbox
             for ofs, node in instnode.curfields.items():
-                fieldbox = self.prepare_rebuild_ops(node, liveboxes,
-                                                    rebuild_ops, memo)
+                fieldbox = self.prepare_rebuild_ops(node, rebuild_ops, memo)
                 if isinstance(ld, FixedList):
                     op = ResOperation(rop.SETARRAYITEM_GC,
                                       [newbox, ofs, fieldbox],
@@ -477,12 +470,10 @@
                                       None, descr=ofs)
                 rebuild_ops.append(op)
             return newbox
-        liveboxes.append(box)
         memo[box] = box
         if instnode.virtualized:
             for ofs, node in instnode.curfields.items():
-                fieldbox = self.prepare_rebuild_ops(node, liveboxes,
-                                                    rebuild_ops, memo)
+                fieldbox = self.prepare_rebuild_ops(node, rebuild_ops, memo)
                 if instnode.cls and isinstance(instnode.cls.source, FixedList):
                     ld = instnode.cls.source
                     assert isinstance(ld, FixedList)
@@ -498,36 +489,33 @@
 
     def optimize_guard(self, op):
         # Make a list of operations to run to rebuild the unoptimized objects.
-        # The ops assume that the Boxes in 'liveboxes' have been reloaded.
-        liveboxes = []
         rebuild_ops = []
         memo = {}
-        old_boxes = op.liveboxes
-        op = op.clone()
+        assert len(op.suboperations) == 1
+        op_fail = op.suboperations[0]
+        assert op_fail.opnum == rop.FAIL
+        old_boxes = op.suboperations[0].args
         unoptboxes = []
         for box in old_boxes:
             if isinstance(box, Const):
                 unoptboxes.append(box)
                 continue
             unoptboxes.append(self.prepare_rebuild_ops(self.nodes[box],
-                                                       liveboxes, rebuild_ops,
-                                                       memo))
+                                                       rebuild_ops, memo))
         # XXX sloooooow!
         for node in self.nodes.values():
             if node.virtualized:
-                self.prepare_rebuild_ops(node, liveboxes, rebuild_ops, memo)
+                self.prepare_rebuild_ops(node, rebuild_ops, memo)
 
         # start of code for dirtyfields support
         for node in self.nodes.values():
             for ofs, subnode in node.dirtyfields.items():
                 box = node.source
                 if box not in memo and isinstance(box, Box):
-                    liveboxes.append(box)
                     memo[box] = box
                 #index = (rev_boxes[box] << FLAG_SHIFT) | FLAG_BOXES_FROM_FRAME
                 fieldbox = subnode.source
                 if fieldbox not in memo and isinstance(fieldbox, Box):
-                    liveboxes.append(fieldbox)
                     memo[fieldbox] = fieldbox
                 #fieldindex = ((rev_boxes[fieldbox] << FLAG_SHIFT) |
                 #              FLAG_BOXES_FROM_FRAME)
@@ -546,15 +534,9 @@
                 rebuild_ops.append(op1)
         # end of code for dirtyfields support
 
-        if not we_are_translated():
-            for box in liveboxes:
-                assert isinstance(box, Box)
-            assert len(dict.fromkeys(liveboxes)) == len(liveboxes)
-
-        op.args = self.new_arguments(op)
-        op.liveboxes = liveboxes
-        op.rebuild_ops = rebuild_ops
-        op.unoptboxes = unoptboxes
+        op_fail.args = unoptboxes
+        rebuild_ops.append(op_fail)
+        op.suboperations = rebuild_ops
         return op
 
     def new_arguments(self, op):
@@ -567,11 +549,6 @@
             newboxes.append(box)
         return newboxes
 
-    def replace_arguments(self, op):
-        op = op.clone()
-        op.args = self.new_arguments(op)
-        return op
-
     def optimize_getfield(self, instnode, ofs, box):
         assert isinstance(ofs, AbstractValue)
         if instnode.virtual:
@@ -604,32 +581,26 @@
     def optimize_loop(self):
         newoperations = []
         exception_might_have_happened = False
-        mp = self.loop.operations[0]
-        if mp.opnum == rop.MERGE_POINT:
-            assert len(mp.args) == len(self.specnodes)
-            for i in range(len(self.specnodes)):
-                box = mp.args[i]
-                self.specnodes[i].mutate_nodes(self.nodes[box])
-        else:
-            assert mp.opnum == rop.CATCH
-            for box in mp.args:
-                self.nodes[box].cls = None
-                assert not self.nodes[box].virtual
+        assert len(self.loop.inputargs) == len(self.specnodes)
+        for i in range(len(self.specnodes)):
+            box = self.loop.inputargs[i]
+            self.specnodes[i].mutate_nodes(self.nodes[box])
+        newinputargs = self.expanded_version_of(self.loop.inputargs, None)
+
+##        assert mp.opnum == rop.CATCH
+##        for box in mp.args:
+##            self.nodes[box].cls = None
+##            assert not self.nodes[box].virtual
 
         for op in self.loop.operations:
             opnum = op.opnum
-            if opnum == rop.MERGE_POINT:
-                args = self.expanded_version_of(op.args, None)
-                op = ResOperation(rop.MERGE_POINT, args, None)
-                newoperations.append(op)
-                continue
-            elif opnum == rop.JUMP:
+            if opnum == rop.JUMP:
                 args = self.expanded_version_of(op.args, newoperations)
                 for arg in args:
                     if arg in self.nodes:
                         assert not self.nodes[arg].virtual
                 self.cleanup_field_caches(newoperations)
-                op = ResOperation(rop.JUMP, args, None)
+                op.args = args
                 newoperations.append(op)
                 continue
             elif opnum == rop.GUARD_NO_EXCEPTION:
@@ -753,7 +724,7 @@
                     self.nodes[box] = instnode
                     continue
             # default handling of arguments and return value
-            op = self.replace_arguments(op)
+            op.args = self.new_arguments(op)
             if op.is_always_pure():
                 for box in op.args:
                     if isinstance(box, Box):
@@ -779,7 +750,8 @@
                 self.nodes[box] = instnode
             newoperations.append(op)
 
-        newoperations[0].specnodes = self.specnodes
+        self.loop.specnodes = self.specnodes
+        self.loop.inputargs = newinputargs
         self.loop.operations = newoperations
 
     def cleanup_field_caches(self, newoperations):
@@ -817,6 +789,7 @@
     def match(self, old_operations):
         old_mp = old_operations[0]
         jump_op = self.loop.operations[-1]
+        assert old_op.opnum == rop.MERGE_POINT
         assert jump_op.opnum == rop.JUMP
         assert len(old_mp.specnodes) == len(jump_op.args)
         for i in range(len(old_mp.specnodes)):
@@ -829,6 +802,8 @@
     def adapt_for_match(self, old_operations):
         old_mp = old_operations[0]
         jump_op = self.loop.operations[-1]
+        assert old_op.opnum == rop.MERGE_POINT
+        assert jump_op.opnum == rop.JUMP
         self.specnodes = old_mp.specnodes
         for i in range(len(old_mp.specnodes)):
             old_specnode = old_mp.specnodes[i]

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py	Mon Mar 23 21:22:55 2009
@@ -887,12 +887,10 @@
     def get_residual_args(self, loop, args):
         if loop.specnodes is None:     # it is None only for tests
             return args
-        assert 0, "XXX fix me"
-        # ---
-        assert len(mp.specnodes) == len(args)
+        assert len(loop.specnodes) == len(args)
         expanded_args = []
-        for i in range(len(mp.specnodes)):
-            specnode = mp.specnodes[i]
+        for i in range(len(loop.specnodes)):
+            specnode = loop.specnodes[i]
             specnode.extract_runtime_data(self.cpu, args[i], expanded_args)
         return expanded_args
 

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py	Mon Mar 23 21:22:55 2009
@@ -29,9 +29,11 @@
     def check_loops(self, expected=None, **check):
         get_stats().check_loops(expected=expected, **check)
     def check_loop_count(self, count):
+        assert get_stats().compiled_count == count
+    def check_tree_loop_count(self, count):
         assert len(get_stats().loops) == count
     def check_loop_count_at_most(self, count):
-        assert len(get_stats().loops) <= count
+        assert get_stats().compiled_count <= count
     def check_jumps(self, maxcount):
         assert get_stats().exec_jumps <= maxcount
 

Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py	(original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py	Mon Mar 23 21:22:55 2009
@@ -321,10 +321,9 @@
         expected = f(100, 5)
         res = self.meta_interp(f, [100, 5], policy=StopAtXPolicy(externfn))
         assert res == expected
-        
-        loops = get_stats().loops
-        assert loops[0].operations[0].opnum == rop.MERGE_POINT
-        assert loops[1].operations[0].opnum == rop.CATCH
+
+        self.check_loop_count(2)
+        self.check_tree_loop_count(1)
 
     def test_example(self):
         myjitdriver = JitDriver(greens = ['i'],



More information about the Pypy-commit mailing list