[pypy-svn] r65660 - in pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test

antocuni at codespeak.net antocuni at codespeak.net
Mon Jun 8 15:39:34 CEST 2009


Author: antocuni
Date: Mon Jun  8 15:39:28 2009
New Revision: 65660

Added:
   pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/specnode3.py
      - copied, changed from r65653, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/specnode.py
Modified:
   pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
   pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py
Log:
implement last step of perfect specialization.


Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py	Mon Jun  8 15:39:28 2009
@@ -2,7 +2,7 @@
 from pypy.jit.metainterp.resoperation import rop, ResOperation
 from pypy.jit.metainterp.history import Const, Box, AbstractValue
 from pypy.jit.metainterp.optimize import av_eq, av_hash, sort_descrs
-from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode, \
+from pypy.jit.metainterp.specnode3 import VirtualInstanceSpecNode, \
      NotSpecNode, FixedClassSpecNode
 
    
@@ -116,6 +116,29 @@
                 return specnode
         return NotSpecNode()
 
+    def newinputargs(self):
+        if self.loop.inputargs is not None:
+            # closing a loop
+            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])
+            return self.expanded_version_of(self.loop.inputargs)
+        else:
+            # making a bridge
+            return None
+
+    def expanded_version_of(self, boxlist):
+        newboxlist = []
+        assert len(boxlist) == len(self.specnodes)
+        for i in range(len(boxlist)):
+            box = boxlist[i]
+            specnode = self.specnodes[i]
+            specnode.expand_boxlist(self.nodes[box], newboxlist)
+        return newboxlist
+
+
+
 class LoopOptimizer(object):
 
     def __init__(self, optlist):
@@ -147,6 +170,8 @@
             return val
 
     def setval(self, box):
+        if box is None:
+            return
         assert box not in self.values
         assert not isinstance(box, Const)
         self.values[box] = self.newval(box)
@@ -154,12 +179,17 @@
     def optimize_loop(self, loop):
         self._init(loop)
         self.spec.find_nodes()
-        self.optimize_operations()
+        self.spec.intersect_input_and_output()
+        newinputargs = self.spec.newinputargs()
+        newoperations = self.optimize_operations(newinputargs)
 
-    def optimize_operations(self):
-        for box in self.loop.inputargs:
-            self.setval(box) #  startbox=True)
+        self.loop.specnodes = self.spec.specnodes
+        self.loop.inputargs = newinputargs
+        self.loop.operations = newoperations
 
+    def optimize_operations(self, newinputargs):
+        for box in newinputargs:
+            self.setval(box) #  startbox=True)
         newoperations = []
         for op in self.loop.operations:
             newop = op
@@ -171,8 +201,8 @@
             if newop is not None:
                 self.setval(newop.result)
                 newoperations.append(newop)
-        print "Length of the loop:", len(newoperations)
-        self.loop.operations = newoperations
+        #print "Length of the loop:", len(newoperations)
+        return newoperations
 
     def new_arguments(self, op):
         newboxes = []
@@ -274,7 +304,7 @@
         if func:
             func(self, spec, op)
 
-    def interesect_nodes(self, a, b, nodes):
+    def intersect_nodes(self, spec, a, b, nodes):
         return None
 
 
@@ -318,6 +348,7 @@
 class OptimizeVirtuals(AbstractOptimization):
 
     def init_node(self, node):
+        node.virtual = False
         node.known_class = None
         node.origfields = r_dict(av_eq, av_hash)
         node.curfields = r_dict(av_eq, av_hash)
@@ -394,6 +425,51 @@
 ##                                             b.cursize)
         return VirtualInstanceSpecNode(known_class_box, fields)
 
+    # ---------------------------------------
+
+    def jump(self, opt, op):
+        args = opt.spec.expanded_version_of(op.args)
+        for arg in args:
+            if arg in opt.spec.nodes:
+                assert not opt.spec.nodes[arg].virtual
+        #self.cleanup_field_caches(newoperations)
+        op = op.clone()
+        op.args = args
+        return op
+
+    def guard_class(self, opt, op):
+        node = opt.spec.getnode(op.args[0])
+        if node.known_class is not None:
+            assert op.args[1].equals(node.known_class.source)
+            return None
+        return op
+
+    def new_with_vtable(self, opt, op):
+        node = opt.spec.getnode(op.result)
+        if not node.escaped:
+            node.virtual = True
+            assert node.known_class is not None
+            return None
+        return op
+
+    def getfield_gc(self, opt, op):
+        node = opt.spec.getnode(op.args[0])
+        descr = op.descr
+        assert isinstance(descr, AbstractValue)
+        if node.virtual:
+            assert descr in node.curfields
+            return None
+        return op
+
+    def setfield_gc(self, opt, op):
+        node = opt.spec.getnode(op.args[0])
+        valuenode = opt.spec.getnode(op.args[1])
+        descr = op.descr
+        if node.virtual:
+            node.curfields[descr] = valuenode
+            return None
+        return op
+
 
 # -------------------------------------------------------------------
 

Copied: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/specnode3.py (from r65653, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/specnode.py)
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/specnode.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/specnode3.py	Mon Jun  8 15:39:28 2009
@@ -57,15 +57,15 @@
 
 class FixedClassSpecNode(SpecNode):
     def __init__(self, known_class):
-        self.known_class = known_class
+        self.known_class = known_class.constbox()
 
     def mutate_nodes(self, instnode):
-        from pypy.jit.metainterp.optimize import InstanceNode
+        from pypy.jit.metainterp.optimize3 import InstanceNode
         
-        if instnode.cls is None:
-            instnode.cls = InstanceNode(self.known_class, const=True)
+        if instnode.known_class is None:
+            instnode.known_class = InstanceNode(self.known_class)
         else:
-            assert instnode.cls.source.equals(self.known_class)
+            assert instnode.known_class.source.equals(self.known_class)
 
     def equals(self, other):
         if type(other) is not FixedClassSpecNode:

Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py	Mon Jun  8 15:39:28 2009
@@ -11,7 +11,7 @@
 from pypy.jit.metainterp.optimize3 import AbstractOptimization
 from pypy.jit.metainterp.optimize3 import optimize_loop, LoopOptimizer,\
      LoopSpecializer, OptimizeGuards, OptimizeVirtuals
-from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode, \
+from pypy.jit.metainterp.specnode3 import VirtualInstanceSpecNode, \
      NotSpecNode
 from pypy.jit.metainterp.test.test_optimize import equaloplists, ANY
 from pypy.jit.metainterp.test.oparser import parse
@@ -123,8 +123,12 @@
             ops = """
             []
             i1 = %s(3, 2)
+            jump()
             """ % op.lower()
-            expected = "[]"
+            expected = """
+            []
+            jump()
+            """
             self.assert_equal(self.optimize(ops), expected)
 
     def test_constfold_guard(self):
@@ -133,9 +137,11 @@
         i0 = int_add(0, 0)
         guard_value(i0, 0)
           fail(i0)
+        jump()
         """
         expected = """
         []
+        jump()
         """
         loop = self.optimize(ops, [])
         self.assert_equal(loop, expected)
@@ -147,11 +153,13 @@
           fail()
         guard_class(p0, ConstClass(node_vtable))
           fail()
+        jump(p0)
         """
         expected = """
         [p0]
         guard_class(p0, ConstClass(node_vtable))
           fail()
+        jump(p0)
         """
         loop = self.optimize(ops, [OptimizeGuards()])
         self.assert_equal(loop, expected)
@@ -166,11 +174,13 @@
         guard_value(i1, 1)
           fail()
         i2 = int_add(i1, 2)
+        jump(i0)
         """
         expected = """
         [i0]
         guard_value(i0, 0)
             fail()
+        jump(0)
         """
         loop = self.parse(ops)
         # cheat
@@ -241,7 +251,17 @@
         assert spec_n.fields[0][0] == self.valuedescr
         assert isinstance(spec_n.fields[0][1], NotSpecNode)
 
-
+    def test_virtual_simple_optimize_loop(self):
+        loop = self._get_virtual_simple_loop()
+        opt = LoopOptimizer([OptimizeVirtuals()])
+        opt.optimize_loop(loop)
+        expected = """
+        [i0, i1]
+        i2 = int_sub(i1, 1)
+        i3 = int_add(i0, i1)
+        jump(i3, i2)
+        """
+        self.assert_equal(loop, expected)
 
 
 class TestLLtype(LLtypeMixin, BaseTestOptimize3):



More information about the Pypy-commit mailing list