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

antocuni at codespeak.net antocuni at codespeak.net
Mon Jun 8 12:16:11 CEST 2009


Author: antocuni
Date: Mon Jun  8 12:16:06 2009
New Revision: 65659

Modified:
   pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
   pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py
Log:
a bit of refactoring, and a new test:

  - remove TrackClass and put its contents again into OptimizeVirtuals and
    OptimizeGuards: the reason is that node.known_class is really needed by
    OptimizeVirtuals, so it makes more sense to just put the code there

  - add a new hook for the optimizations to do the intersection between nodes.
    So far, only OptimizeVirtuals implements it, but doing a subset of what
    the original optimize.InstanceNode.intersect does

  - add test_virtual_simple_intersect_input_and_output, and implement the
    corresponding LoopSpecializer method to make the test passing



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 12:16:06 2009
@@ -1,9 +1,11 @@
 from pypy.rlib.objectmodel import r_dict
 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
-
+from pypy.jit.metainterp.optimize import av_eq, av_hash, sort_descrs
+from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode, \
+     NotSpecNode, FixedClassSpecNode
 
+   
 class InstanceNode(object):
     def __init__(self, source, escaped=True):
         self.source = source
@@ -16,6 +18,7 @@
         #if self.virtual:           flags += 'v'
         #if self.virtualized:       flags += 'V'
         return "<InstanceNode %s (%s)>" % (self.source, flags)
+        
 
 
 class InstanceValue(object):
@@ -90,6 +93,28 @@
             for arg in op.suboperations[0].args:
                 self.getnode(arg)
 
+    def recursively_find_escaping_values(self):
+        pass # for now
+
+    def intersect_input_and_output(self):
+        # Step (3)
+        self.recursively_find_escaping_values()
+        jump = self.loop.operations[-1]
+        assert jump.opnum == rop.JUMP
+        specnodes = []
+        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))
+            specnodes.append(self.intersect_nodes(enternode, leavenode, self.nodes))
+        self.specnodes = specnodes
+
+    def intersect_nodes(self, a, b, nodes):
+        for opt in self.optlist:
+            specnode = opt.intersect_nodes(self, a, b, nodes)
+            if specnode is not None:
+                return specnode
+        return NotSpecNode()
 
 class LoopOptimizer(object):
 
@@ -249,6 +274,9 @@
         if func:
             func(self, spec, op)
 
+    def interesect_nodes(self, a, b, nodes):
+        return None
+
 
     # hooks for LoopOptimizer
     # -------------------------
@@ -264,23 +292,7 @@
         return op
 
 
-class TrackClass(AbstractOptimization):
-
-    def init_node(self, node):
-        node.known_class = None
-
-    def find_nodes_new_with_vtable(self, spec, op):
-        box = op.result
-        node = spec.newnode(box, escaped=False)
-        node.known_class = spec.newnode(op.args[0])
-        spec.nodes[box] = node
-
-    def find_nodes_guard_class(self, spec, op):
-        node = spec.getnode(op.args[0])
-        if node.known_class is None:
-            node.known_class = spec.newnode(op.args[1])
-
-    # -----------------------------
+class OptimizeGuards(AbstractOptimization):
 
     def init_value(self, val):
         val.cls = None
@@ -293,9 +305,6 @@
         val.cls = opt.newval(op.args[1].constbox())
         return op
 
-
-class OptimizeGuards(AbstractOptimization):
-
     def guard_value(self, opt, op):
         val = opt.getval(op.args[0])
         assert isinstance(op.args[1], Const)
@@ -309,9 +318,21 @@
 class OptimizeVirtuals(AbstractOptimization):
 
     def init_node(self, node):
+        node.known_class = None
         node.origfields = r_dict(av_eq, av_hash)
         node.curfields = r_dict(av_eq, av_hash)
 
+    def find_nodes_new_with_vtable(self, spec, op):
+        box = op.result
+        node = spec.newnode(box, escaped=False)
+        node.known_class = spec.newnode(op.args[0])
+        spec.nodes[box] = node
+
+    def find_nodes_guard_class(self, spec, op):
+        node = spec.getnode(op.args[0])
+        if node.known_class is None:
+            node.known_class = spec.newnode(op.args[1])
+
     def find_nodes_setfield_gc(self, spec, op):
         instnode = spec.getnode(op.args[0])
         fielddescr = op.descr
@@ -337,6 +358,42 @@
             instnode.origfields[fielddescr] = fieldnode
         spec.nodes[resbox] = fieldnode
 
+    def intersect_nodes(self, spec, a, b, nodes):
+        if not b.known_class:
+            return NotSpecNode()
+        if a.known_class:
+            if not a.known_class.source.equals(b.known_class.source):
+                #raise CancelInefficientLoop
+                return NotSpecNode()
+            known_class_box = a.known_class.source
+        else:
+            known_class_box = b.known_class.source
+        if b.escaped:
+            if a.known_class is None:
+                return NotSpecNode()
+##             if isinstance(known_class_box, FixedList):
+##                 return NotSpecNode()
+            return FixedClassSpecNode(known_class_box)
+        
+        assert a is not b
+        fields = []
+        d = b.curfields
+        lst = d.keys()
+        sort_descrs(lst)
+        for ofs in lst:
+            node = d[ofs]
+            if ofs not in a.origfields:
+                box = node.source.clonebox()
+                a.origfields[ofs] = InstanceNode(box, escaped=False)
+                a.origfields[ofs].known_class = node.known_class
+                nodes[box] = a.origfields[ofs]
+            specnode = spec.intersect_nodes(a.origfields[ofs], node, nodes)
+            fields.append((ofs, specnode))
+##         if isinstance(known_class_box, FixedList):
+##             return VirtualFixedListSpecNode(known_class_box, fields,
+##                                             b.cursize)
+        return VirtualInstanceSpecNode(known_class_box, fields)
+
 
 # -------------------------------------------------------------------
 

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 12:16:06 2009
@@ -10,7 +10,9 @@
 
 from pypy.jit.metainterp.optimize3 import AbstractOptimization
 from pypy.jit.metainterp.optimize3 import optimize_loop, LoopOptimizer,\
-     LoopSpecializer, OptimizeGuards, OptimizeVirtuals, TrackClass
+     LoopSpecializer, OptimizeGuards, OptimizeVirtuals
+from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode, \
+     NotSpecNode
 from pypy.jit.metainterp.test.test_optimize import equaloplists, ANY
 from pypy.jit.metainterp.test.oparser import parse
 
@@ -151,7 +153,7 @@
         guard_class(p0, ConstClass(node_vtable))
           fail()
         """
-        loop = self.optimize(ops, [TrackClass()])
+        loop = self.optimize(ops, [OptimizeGuards()])
         self.assert_equal(loop, expected)
 
 
@@ -203,7 +205,7 @@
 
     def test_virtual_simple_find_nodes(self):
         loop = self._get_virtual_simple_loop()
-        spec = LoopSpecializer([TrackClass(), OptimizeVirtuals()])
+        spec = LoopSpecializer([OptimizeVirtuals()])
         spec._init(loop)
         spec.find_nodes()
 
@@ -224,6 +226,21 @@
         assert len(spec.nodes[p1].origfields) == 0
         assert spec.nodes[p1].curfields[self.valuedescr] is spec.nodes[i2]
 
+    def test_virtual_simple_intersect_input_and_output(self):
+        loop = self._get_virtual_simple_loop()
+        spec = LoopSpecializer([OptimizeVirtuals()])
+        spec._init(loop)
+        spec.find_nodes()
+        spec.intersect_input_and_output()
+        
+        assert len(spec.specnodes) == 2
+        spec_sum, spec_n = spec.specnodes
+        assert isinstance(spec_sum, NotSpecNode)
+        assert isinstance(spec_n, VirtualInstanceSpecNode)
+        assert spec_n.known_class.value == self.node_vtable_adr
+        assert spec_n.fields[0][0] == self.valuedescr
+        assert isinstance(spec_n.fields[0][1], NotSpecNode)
+
 
 
 



More information about the Pypy-commit mailing list