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

fijal at codespeak.net fijal at codespeak.net
Mon May 25 00:37:21 CEST 2009


Author: fijal
Date: Mon May 25 00:37:16 2009
New Revision: 65389

Modified:
   pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
   pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
implement setfield/getfield optimization for fields marked as virtuals


Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py	Mon May 25 00:37:16 2009
@@ -13,6 +13,7 @@
         self.cls = None
         self.cleanfields = {}
         self.dirtyfields = {}
+        self.virtualized = False
 
     def __repr__(self):
         flags = ''
@@ -20,7 +21,7 @@
         #if self.startbox:          flags += 's'
         if self.const:             flags += 'c'
         #if self.virtual:           flags += 'v'
-        #if self.virtualized:       flags += 'V'
+        if self.virtualized:       flags += 'V'
         return "<InstanceNode %s (%s)>" % (self.source, flags)
 
 class Specializer(object):
@@ -62,7 +63,7 @@
                 if is_pure:
                     box = op.result
                     assert box is not None
-                    self.nodes[box] = InstanceNode(box.constbox(), const=True)
+                    self.nodes[box] = self.getnode(box.constbox())
                     continue
             else:
                 if op.is_guard():
@@ -73,7 +74,7 @@
                     self.getnode(box)
             box = op.result
             if box is not None:
-                self.nodes[box] = InstanceNode(box)
+                self.nodes[box] = self.getnode(box)
 
     def new_arguments(self, op):
         newboxes = []
@@ -90,9 +91,15 @@
         op_fail.args = self.new_arguments(op_fail)
         # modification in place. Reason for this is explained in mirror
         # in optimize.py
-        op.suboperations = [op_fail]
+        op.suboperations = []
+        for node, field in self.additional_stores:
+            op.suboperations.append(ResOperation(rop.SETFIELD_GC,
+               [node.source, node.cleanfields[field].source], None, field))
+        op.suboperations.append(op_fail)
+        op.args = self.new_arguments(op)
 
     def optimize_operations(self):
+        self.additional_stores = []
         newoperations = []
         for op in self.loop.operations:
             newop = op
@@ -141,7 +148,36 @@
 
 class SimpleVirtualizableOpt(object):
     def optimize_guard_nonvirtualized(self, op, spec):
-        xxx
+        instnode = spec.getnode(op.args[0])
+        instnode.virtualized = True
+        instnode.vdesc = op.descr
+        return None
+
+    def optimize_getfield_gc(self, op, spec):
+        instnode = spec.getnode(op.args[0])
+        if not instnode.virtualized:
+            return op
+        field = op.descr
+        if field not in instnode.vdesc.virtuals:
+            return op
+        node = instnode.cleanfields.get(field, None)
+        if node is not None:
+            spec.nodes[op.result] = node
+            return None
+        instnode.cleanfields[field] = spec.getnode(op.result)
+        return op
+
+    def optimize_setfield_gc(self, op, spec):
+        instnode = spec.getnode(op.args[0])
+        if not instnode.virtualized:
+            return op
+        field = op.descr
+        if field not in instnode.vdesc.virtuals:
+            return op
+        instnode.cleanfields[field] = spec.getnode(op.args[1])
+        # we never set it here
+        spec.additional_stores.append((instnode, field))
+        return None
 
 specializer = Specializer([])
 

Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py	Mon May 25 00:37:16 2009
@@ -10,9 +10,36 @@
 
 from pypy.jit.metainterp.optimize2 import (optimize_loop,
      ConsecutiveGuardClassRemoval, Specializer, SimpleVirtualizableOpt)
-from pypy.jit.metainterp.test.test_optimize import equaloplists, ANY
+from pypy.jit.metainterp.test.test_optimize import ANY
 
 from pypy.jit.metainterp.test.oparser import parse
+from pypy.jit.metainterp.virtualizable import VirtualizableDesc
+
+def equaloplists(oplist1, oplist2):
+    #saved = Box._extended_display
+    #try:
+    #    Box._extended_display = False
+    print '-'*20, 'Comparing lists', '-'*20
+    for op1, op2 in zip(oplist1, oplist2):
+        txt1 = str(op1)
+        txt2 = str(op2)
+        while txt1 or txt2:
+            print '%-39s| %s' % (txt1[:39], txt2[:39])
+            txt1 = txt1[39:]
+            txt2 = txt2[39:]
+        assert op1.opnum == op2.opnum
+        assert len(op1.args) == len(op2.args)
+        for x, y in zip(op1.args, op2.args):
+            assert x == y or y == x     # for ANY object :-(
+        assert op1.result == op2.result
+        assert op1.descr == op2.descr
+        if op1.suboperations or op2.suboperations:
+            equaloplists(op1.suboperations, op2.suboperations)
+    assert len(oplist1) == len(oplist2)
+    print '-'*57
+    #finally:
+    #    Box._extended_display = saved
+    return True
 
 class LLtypeMixin(object):
 
@@ -29,9 +56,13 @@
     nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
     nodedescr = cpu.fielddescrof(NODE, 'value')
 
-    XY = lltype.GcStruct('XY', ('field', lltype.Signed),
-                         hints= {'virtualizable2': True})
-    field_desc = cpu.fielddescrof(XY, 'field')
+    XY = lltype.GcStruct('XY', ('inst_field', lltype.Signed),
+                         ('inst_other_field', lltype.Signed),
+                         hints= {'virtualizable2': True,
+                                 'virtuals': ('field',)})
+    field_desc = cpu.fielddescrof(XY, 'inst_field')
+    other_field_desc = cpu.fielddescrof(XY, 'inst_other_field')
+    vdesc = VirtualizableDesc(cpu, XY, XY)
 
     namespace = locals()
 
@@ -89,10 +120,9 @@
                           expected)
 
     def test_basic_virtualizable(self):
-        py.test.skip("xxx")
         pre_op = """
         [p0]
-        guard_nonvirtualized(p0)
+        guard_nonvirtualized(p0, descr=vdesc)
             fail()
         i1 = getfield_gc(p0, descr=field_desc)
         i2 = getfield_gc(p0, descr=field_desc)
@@ -105,6 +135,31 @@
         """
         self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
                           expected)
+
+    def test_virtualizable_setfield_rebuild_ops(self):
+        pre_op = """
+        [p0]
+        guard_nonvirtualized(p0, descr=vdesc)
+            fail()
+        i1 = getfield_gc(p0, descr=field_desc)
+        i2 = getfield_gc(p0, descr=other_field_desc)
+        setfield_gc(p0, i2, descr=field_desc)
+        # ^^^ this should be gone
+        i3 = getfield_gc(p0, descr=field_desc)
+        # ^^^ this one as well
+        guard_true(i3)
+            fail()
+        """
+        expected = """
+        [p0]
+        i1 = getfield_gc(p0, descr=field_desc)
+        i2 = getfield_gc(p0, descr=other_field_desc)
+        guard_true(i2)
+            setfield_gc(p0, i2, descr=field_desc)
+            fail()
+        """
+        self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
+                          expected)
         
 
     def test_remove_consecutive_guard_value_constfold(self):



More information about the Pypy-commit mailing list