[pypy-svn] r66498 - in pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp: . test

arigo at codespeak.net arigo at codespeak.net
Wed Jul 22 09:36:58 CEST 2009


Author: arigo
Date: Wed Jul 22 09:36:56 2009
New Revision: 66498

Modified:
   pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py
   pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/resoperation.py
   pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py
Log:
Start handling the fail() operations attached to guards.


Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py	(original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py	Wed Jul 22 09:36:56 2009
@@ -3,7 +3,7 @@
 from pypy.jit.metainterp.resoperation import rop, ResOperation
 from pypy.jit.metainterp.specnode import SpecNode
 from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode
-from pypy.jit.metainterp.optimizeutil import av_newdict, _findall
+from pypy.jit.metainterp.optimizeutil import av_newdict, _findall, sort_descrs
 from pypy.rlib.objectmodel import we_are_translated
 
 
@@ -36,6 +36,10 @@
     def force_box(self):
         return self.box
 
+    def get_args_for_fail(self, list):
+        if not self.is_constant():
+            list.append(self.box)
+
     def is_constant(self):
         return self.level == LEVEL_CONSTANT
 
@@ -114,6 +118,15 @@
                 newoperations.append(op)
         return self.box
 
+    def get_args_for_fail(self, list):
+        if self.box is not None:
+            InstanceValue.get_args_for_fail(self, list)
+        else:
+            lst = self._fields.keys()
+            sort_descrs(lst)
+            for ofs in lst:
+                self._fields[ofs].get_args_for_fail(list)
+
 
 class __extend__(SpecNode):
     def setup_virtual_node(self, optimizer, box, newinputargs):
@@ -217,6 +230,7 @@
         self.loop.operations = self.newoperations
 
     def emit_operation(self, op, must_clone=True):
+        op1 = op
         for i in range(len(op.args)):
             arg = op.args[i]
             if arg in self.values:
@@ -226,9 +240,32 @@
                         op = op.clone()
                         must_clone = False
                     op.args[i] = box
-        self.newoperations.append(op)
-        if op.can_raise():
+        if op.is_guard():
+            self.clone_guard(op, op1)
+        elif op.can_raise():
             self.exception_might_have_happened = True
+        self.newoperations.append(op)
+
+    def clone_guard(self, op2, op1):
+        assert len(op1.suboperations) == 1
+        op_fail = op1.suboperations[0]
+        assert op_fail.opnum == rop.FAIL
+        #
+        newboxes = []
+        for box in op_fail.args:
+            try:
+                value = self.values[box]
+            except KeyError:
+                newboxes.append(box)
+            else:
+                value.get_args_for_fail(newboxes)
+        # NB. we mutate op_fail in-place above.  That's bad.  Hopefully
+        # it does not really matter because no-one is going to look again
+        # at its unoptimized version.  We cannot really clone it because of
+        # how the rest works (e.g. it is returned by cpu.execute_operations()).
+        op_fail.args = newboxes
+        op2.suboperations = op1.suboperations
+        op1.optimized = op2
 
     def optimize_default(self, op):
         if op.is_always_pure():
@@ -250,9 +287,10 @@
         for i in range(len(specnodes)):
             value = self.getvalue(op.args[i])
             specnodes[i].teardown_virtual_node(self, value, exitargs)
-        op = op.clone()
-        op.args = exitargs
-        self.emit_operation(op, must_clone=False)
+        op2 = op.clone()
+        op2.args = exitargs
+        op2.jump_target = op.jump_target
+        self.emit_operation(op2, must_clone=False)
 
     def optimize_guard(self, op):
         value = self.getvalue(op.args[0])
@@ -263,14 +301,15 @@
 
     def optimize_GUARD_VALUE(self, op):
         assert isinstance(op.args[1], Const)
+        assert op.args[0].getint() == op.args[1].getint()
         self.optimize_guard(op)
 
     def optimize_GUARD_TRUE(self, op):
-        assert op.args[0].getint()
+        assert op.args[0].getint() == 1
         self.optimize_guard(op)
 
     def optimize_GUARD_FALSE(self, op):
-        assert not op.args[0].getint()
+        assert op.args[0].getint() == 0
         self.optimize_guard(op)
 
     def optimize_GUARD_CLASS(self, op):

Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/resoperation.py	(original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/resoperation.py	Wed Jul 22 09:36:56 2009
@@ -34,9 +34,7 @@
         self.descr = descr
 
     def clone(self):
-        res = ResOperation(self.opnum, self.args, self.result, self.descr)
-        res.jump_target = self.jump_target
-        return res
+        return ResOperation(self.opnum, self.args, self.result, self.descr)
 
     def __repr__(self):
         return self.repr()

Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py	(original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py	Wed Jul 22 09:36:56 2009
@@ -480,7 +480,7 @@
         # the 'expected' is sub-optimal, but it should be done by another later
         # optimization step.  See test_find_nodes_default_field() for why.
         self.optimize_loop(ops, 'Virtual(node_vtable, valuedescr=Not)',
-                           expected)
+                           expected, i0=0)
 
     def test_virtual_3(self):
         ops = """
@@ -570,6 +570,27 @@
         self.optimize_loop(ops, 'Not', expected, i1=5,
                            boxkinds={'myptr': self.nodebox.value})
 
+    def test_expand_fail_arguments(self):
+        ops = """
+        [i1, i2, i3, p3]
+        p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+        p2 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+        setfield_gc(p1, 1, descr=valuedescr)
+        setfield_gc(p1, p2, descr=nextdescr)
+        setfield_gc(p2, i2, descr=valuedescr)
+        setfield_gc(p2, p3, descr=nextdescr)
+        guard_true(i1)
+            fail(p1, i3)
+        jump(i2, i1, i3, p3)
+        """
+        expected = """
+        [i1, i2, i3, p3]
+        guard_true(i1)
+            fail(i2, p3, i3)
+        jump(i2, 1, i3, p3)
+        """
+        self.optimize_loop(ops, 'Not, Not, Not, Not', expected, i1=1)
+
 
 class TestLLtype(BaseTestOptimizeOpt, LLtypeMixin):
     pass



More information about the Pypy-commit mailing list