[pypy-svn] r67743 - in pypy/branch/optimize-novaluedep/pypy/jit/metainterp: . test

arigo at codespeak.net arigo at codespeak.net
Thu Sep 17 19:01:28 CEST 2009


Author: arigo
Date: Thu Sep 17 19:01:25 2009
New Revision: 67743

Modified:
   pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizefindnode.py
   pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeopt.py
   pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeutil.py
   pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizefindnode.py
   pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizeopt.py
Log:
(arigo, cfbolz): start tracking again loops that are not efficient at all.


Modified: pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizefindnode.py
==============================================================================
--- pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizefindnode.py	(original)
+++ pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizefindnode.py	Thu Sep 17 19:01:25 2009
@@ -8,6 +8,7 @@
 from pypy.jit.metainterp.resoperation import rop
 from pypy.jit.metainterp.executor import _execute_nonspec
 from pypy.jit.metainterp.optimizeutil import av_newdict, _findall, sort_descrs
+from pypy.jit.metainterp.optimizeutil import InvalidLoop
 
 # ____________________________________________________________
 
@@ -341,9 +342,11 @@
     def intersect(self, inputnode, exitnode):
         assert inputnode.fromstart
         if inputnode.is_constant() and \
-           exitnode.is_constant() and \
-           inputnode.knownvaluebox.same_constant(exitnode.knownvaluebox):
-            return ConstantSpecNode(inputnode.knownvaluebox)
+           exitnode.is_constant():
+            if inputnode.knownvaluebox.same_constant(exitnode.knownvaluebox):
+                return ConstantSpecNode(inputnode.knownvaluebox)
+            else:
+                raise InvalidLoop
         if inputnode.escaped:
             return prebuiltNotSpecNode
         unique = exitnode.unique
@@ -387,7 +390,7 @@
         if (inputnode.knownclsbox is not None and
             not inputnode.knownclsbox.same_constant(exitnode.knownclsbox)):
             # unique match, but the class is known to be a mismatch
-            return prebuiltNotSpecNode
+            raise InvalidLoop
         #
         fields = self.compute_common_fields(inputnode.origfields,
                                             exitnode.curfields)

Modified: pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeopt.py	(original)
+++ pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeopt.py	Thu Sep 17 19:01:25 2009
@@ -8,6 +8,7 @@
 from pypy.jit.metainterp.specnode import VirtualArraySpecNode
 from pypy.jit.metainterp.specnode import VirtualStructSpecNode
 from pypy.jit.metainterp.optimizeutil import av_newdict2, _findall, sort_descrs
+from pypy.jit.metainterp.optimizeutil import InvalidLoop
 from pypy.jit.metainterp import resume, compile
 from pypy.jit.metainterp.typesystem import llhelper, oohelper
 from pypy.rlib.objectmodel import we_are_translated
@@ -484,7 +485,7 @@
         for i in range(len(op.args)):
             arg = op.args[i]
             if arg in self.values:
-                box = self.values[arg].force_box() # I think we definitely need box, at least for this but it's unclear I mean is it ok to replace box with Const(..) when we set level==CONSTANT?ah, in this direction. yes, I would expect that to be ok ah yes indeed I see it
+                box = self.values[arg].force_box()
                 if box is not arg:
                     if must_clone:
                         op = op.clone()
@@ -578,7 +579,8 @@
         if value.is_constant():
             box = value.box
             assert isinstance(box, Const)
-            assert box.same_constant(constbox)
+            if not box.same_constant(constbox):
+                raise InvalidLoop
             return
         self.emit_operation(op)
         value.make_constant(constbox)
@@ -600,6 +602,9 @@
         assert isinstance(expectedclassbox, Const)
         realclassbox = value.get_constant_class(self.cpu)
         if realclassbox is not None:
+            # the following assert should always be true for now,
+            # because invalid loops that would fail it are detected
+            # earlier, in optimizefindnode.py.
             assert realclassbox.same_constant(expectedclassbox)
             return
         self.emit_operation(op)

Modified: pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeutil.py
==============================================================================
--- pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeutil.py	(original)
+++ pypy/branch/optimize-novaluedep/pypy/jit/metainterp/optimizeutil.py	Thu Sep 17 19:01:25 2009
@@ -2,6 +2,11 @@
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.jit.metainterp import resoperation
 
+class InvalidLoop(Exception):
+    """Raised when the optimize*.py detect that the loop that
+    we are trying to build cannot possibly make sense as a
+    long-running loop (e.g. it cannot run 2 complete iterations)."""
+
 # ____________________________________________________________
 # Misc. utilities
 

Modified: pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizefindnode.py
==============================================================================
--- pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizefindnode.py	(original)
+++ pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizefindnode.py	Thu Sep 17 19:01:25 2009
@@ -10,7 +10,7 @@
                                          ConstObj, AbstractDescr)
 from pypy.jit.metainterp.optimizefindnode import PerfectSpecializationFinder
 from pypy.jit.metainterp.optimizefindnode import BridgeSpecializationFinder
-from pypy.jit.metainterp.optimizeutil import sort_descrs
+from pypy.jit.metainterp.optimizeutil import sort_descrs, InvalidLoop
 from pypy.jit.metainterp.specnode import NotSpecNode, prebuiltNotSpecNode
 from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode
 from pypy.jit.metainterp.specnode import VirtualArraySpecNode
@@ -417,9 +417,9 @@
         p2 = new_with_vtable(ConstClass(node_vtable2))
         jump(p2)
         """
-        # this must give 'Not', not 'Virtual', because optimizeopt.py would
-        # remove the guard_class for a virtual.
-        self.find_nodes(ops, 'Not')
+        # this is not a valid loop at all, because of the mismatch
+        # between the produced and the consumed class.
+        py.test.raises(InvalidLoop, self.find_nodes, ops, None)
 
     def test_find_nodes_new_aliasing_mismatch(self):
         ops = """
@@ -431,6 +431,8 @@
         p2 = new_with_vtable(ConstClass(node_vtable2))
         jump(p2, p2)
         """
+        # this is also not really a valid loop, but it's not detected
+        # because p2 is passed more than once in the jump().
         self.find_nodes(ops, 'Not, Not')
 
     def test_find_nodes_new_escapes(self):
@@ -517,14 +519,14 @@
         ops = """
         [p0]
         i0 = getfield_gc(p0, descr=valuedescr)
-        guard_value(i0, 0)
+        guard_value(i0, 5)
           fail()
         p1 = new_with_vtable(ConstClass(node_vtable))
         # the field 'value' has its default value of 0
         jump(p1)
         """
         # The answer must contain the 'value' field, because otherwise
-        # we might get incorrect results: when tracing, maybe i0 was not 0.
+        # we might get incorrect results: when tracing, i0 was 5.
         self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Not)')
 
     def test_find_nodes_nonvirtual_guard_class(self):
@@ -721,6 +723,15 @@
         """
         self.find_nodes(ops, 'Constant(myptr)')
 
+    def test_find_nodes_guard_value_constant_mismatch(self):
+        ops = """
+        [p1]
+        guard_value(p1, ConstPtr(myptr2))
+            fail()
+        jump(ConstPtr(myptr))
+        """
+        py.test.raises(InvalidLoop, self.find_nodes, ops, None)
+
     def test_find_nodes_guard_value_escaping_constant(self):
         ops = """
         [p1]
@@ -889,19 +900,6 @@
         """
         self.find_nodes(ops, 'Virtual(node_vtable, valuedescr=Not)')
 
-    def test_bug_2(self):
-        py.test.skip("fix me")
-        ops = """
-        [p1]
-        i1 = ooisnull(p1)
-        guard_true(i1)
-            fail()
-        #
-        p2 = new_with_vtable(ConstClass(node_vtable))
-        jump(p2)
-        """
-        self.find_nodes(ops, 'Not',
-                        i1=1)
     # ------------------------------
     # Bridge tests
 

Modified: pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizeopt.py	(original)
+++ pypy/branch/optimize-novaluedep/pypy/jit/metainterp/test/test_optimizeopt.py	Thu Sep 17 19:01:25 2009
@@ -7,6 +7,7 @@
                                                             BaseTest)
 from pypy.jit.metainterp.optimizefindnode import PerfectSpecializationFinder
 from pypy.jit.metainterp.optimizeopt import optimize_loop_1
+from pypy.jit.metainterp.optimizeutil import InvalidLoop
 from pypy.jit.metainterp.history import AbstractDescr, ConstInt
 from pypy.jit.metainterp import resume, executor, compile
 from pypy.jit.metainterp.resoperation import rop, opname
@@ -221,22 +222,26 @@
 
     def test_remove_consecutive_guard_value_constfold(self):
         ops = """
-        [i0]
+        []
+        i0 = escape()
         guard_value(i0, 0)
           fail()
         i1 = int_add(i0, 1)
         guard_value(i1, 1)
           fail()
         i2 = int_add(i1, 2)
-        jump(i2)
+        escape(i2)
+        jump()
         """
         expected = """
-        [i0]
+        []
+        i0 = escape()
         guard_value(i0, 0)
-            fail()
-        jump(3)
+          fail()
+        escape(3)
+        jump()
         """
-        self.optimize_loop(ops, 'Not', expected)
+        self.optimize_loop(ops, '', expected)
 
     def test_remove_guard_value_if_constant(self):
         ops = """
@@ -1238,6 +1243,33 @@
         self.optimize_loop(ops, 'Not, VArray(arraydescr2, Not)',
                            expected)
 
+    def test_invalid_loop_1(self):
+        ops = """
+        [p1]
+        i1 = ooisnull(p1)
+        guard_true(i1)
+            fail()
+        #
+        p2 = new_with_vtable(ConstClass(node_vtable))
+        jump(p2)
+        """
+        py.test.raises(InvalidLoop, self.optimize_loop,
+                       ops, 'Virtual(node_vtable)', None)
+
+    def test_invalid_loop_2(self):
+        py.test.skip("this would fail if we had Fixed again in the specnodes")
+        ops = """
+        [p1]
+        guard_class(p1, ConstClass(node_vtable2))
+            fail()
+        #
+        p2 = new_with_vtable(ConstClass(node_vtable))
+        escape(p2)      # prevent it from staying Virtual
+        jump(p2)
+        """
+        py.test.raises(InvalidLoop, self.optimize_loop,
+                       ops, '...', None)
+
     # ----------
 
     def make_fail_descr(self):



More information about the Pypy-commit mailing list