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

arigo at codespeak.net arigo at codespeak.net
Sat Jul 18 15:35:02 CEST 2009


Author: arigo
Date: Sat Jul 18 15:35:01 2009
New Revision: 66355

Modified:
   pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimize.py
   pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimize.py
Log:
Add another pass, find_unique_nodes(), before doing
the intersection.  Makes the three test pass.


Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimize.py	(original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimize.py	Sat Jul 18 15:35:01 2009
@@ -25,6 +25,10 @@
 
 # ____________________________________________________________
 
+UNIQUE_UNKNOWN = '\x00'
+UNIQUE_YES     = '\x01'
+UNIQUE_NO      = '\x02'
+
 class InstanceNode(object):
     """For the first phase: InstanceNode is used to match the start and
     the end of the loop, so it contains both 'origfields' that represents
@@ -35,6 +39,7 @@
     curfields = None    # optimization; equivalent to an empty dict
     dependencies = None
     knownclsbox = None
+    unique = UNIQUE_UNKNOWN   # for find_unique_nodes()
 
     def __init__(self, escaped, fromstart=False):
         self.escaped = escaped
@@ -151,6 +156,8 @@
         """Build the list of specnodes based on the result
         computed by this PerfectSpecializationFinder.
         """
+        for box in op.args:
+            self.find_unique_nodes(self.getnode(box))
         specnodes = []
         assert len(self.inputnodes) == len(op.args)
         for i in range(len(op.args)):
@@ -159,29 +166,42 @@
             specnodes.append(self.intersect(inputnode, exitnode))
         self.specnodes = specnodes
 
+    def find_unique_nodes(self, exitnode):
+        if (exitnode.escaped or exitnode.fromstart
+            or exitnode.knownclsbox is None
+            or exitnode.unique != UNIQUE_UNKNOWN):
+            # the exitnode is not suitable for being a virtual, or we
+            # encounter it more than once when doing the recursion
+            exitnode.unique = UNIQUE_NO
+        else:
+            exitnode.unique = UNIQUE_YES
+            if exitnode.curfields is not None:
+                for subnode in exitnode.curfields.values():
+                    self.find_unique_nodes(subnode)
+
     def intersect(self, inputnode, exitnode):
         assert inputnode.fromstart
-        if exitnode.knownclsbox is None:
-            return prebuiltNotSpecNode     # no known class at exit
-        if (inputnode.knownclsbox is not None and
-            not inputnode.knownclsbox.equals(exitnode.knownclsbox)):
-            return prebuiltNotSpecNode     # mismatched known class at exit
-        #
-        # for the sequel, we know that the class is known and matches
-        if inputnode.escaped or exitnode.escaped or exitnode.fromstart:
-            if inputnode.knownclsbox is None:
-                return prebuiltNotSpecNode      # class not needed at input
-            return FixedClassSpecNode(exitnode.knownclsbox)
+        if exitnode.unique == UNIQUE_NO:
+            # give a NotSpecNode or a FixedClassSpecNode
+            if (inputnode.knownclsbox is not None and
+                exitnode.knownclsbox is not None and
+                inputnode.knownclsbox.equals(exitnode.knownclsbox)):
+                # the class is known at the end, needed at the input,
+                # and matches
+                return FixedClassSpecNode(inputnode.knownclsbox)
+            else:
+                return prebuiltNotSpecNode
         #
+        assert exitnode.unique == UNIQUE_YES
         fields = []
         d = exitnode.curfields
         if d is not None:
-            if inputnode.origfields is None:
-                inputnode.origfields = av_newdict()
             lst = d.keys()
             sort_descrs(lst)
             for ofs in lst:
                 try:
+                    if inputnode.origfields is None:
+                        raise KeyError
                     node = inputnode.origfields[ofs]
                 except KeyError:
                     # field stored at exit, but not read at input.  Must

Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimize.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimize.py	(original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimize.py	Sat Jul 18 15:35:01 2009
@@ -394,7 +394,6 @@
         assert boxp3.knownclsbox.value == self.node_vtable_adr2
 
     def test_find_nodes_new_aliasing_0(self):
-        py.test.skip("in-progress")
         ops = """
         [p1, p2]
         p3 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
@@ -405,7 +404,6 @@
         self.find_nodes(ops, 'Not, Not')
 
     def test_find_nodes_new_aliasing_1(self):
-        py.test.skip("infinite loop")
         ops = """
         [sum, p1]
         guard_class(p1, ConstClass(node_vtable))
@@ -423,11 +421,10 @@
         """
         # the issue is the cycle "p2->p2", which cannot be represented
         # with SpecNodes so far
-        self.find_nodes(ops, 'Not, Not',
+        self.find_nodes(ops, 'Not, Fixed(node_vtable)',
                         boxkinds={'sum': BoxInt, 'sum2': BoxInt})
 
     def test_find_nodes_new_aliasing_2(self):
-        py.test.skip("in-progress")
         ops = """
         [p1, p2]
         escape(p2)



More information about the Pypy-commit mailing list