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

fijal at codespeak.net fijal at codespeak.net
Mon May 25 04:31:47 CEST 2009


Author: fijal
Date: Mon May 25 04:31:44 2009
New Revision: 65398

Modified:
   pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
   pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
move constant folding of guards into specializer


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 04:31:44 2009
@@ -4,6 +4,9 @@
 from pypy.jit.metainterp.resoperation import rop, ResOperation, opname
 from pypy.jit.metainterp.history import Const, Box
 
+class VirtualizedListAccessedWithVariableArg(Exception):
+    pass
+
 class InstanceNode(object):
     def __init__(self, source, const=False):
         self.source = source
@@ -14,6 +17,7 @@
         self.cleanfields = {}
         self.dirtyfields = {}
         self.virtualized = False
+        self.possibly_virtualized_list = False
 
     def __repr__(self):
         flags = ''
@@ -86,6 +90,11 @@
         return newboxes
 
     def optimize_guard(self, op):
+        for arg in op.args:
+            if not self.getnode(arg).const:
+                break
+        else:
+            return None
         assert len(op.suboperations) == 1
         op_fail = op.suboperations[0]
         op_fail.args = self.new_arguments(op_fail)
@@ -95,11 +104,16 @@
         for (node, field), fieldnode in self.additional_stores.iteritems():
             op.suboperations.append(ResOperation(rop.SETFIELD_GC,
                [node.source, node.cleanfields[field].source], None, field))
+        for (node, field), (fieldnode, descr) in self.additional_setarrayitems.iteritems():
+            op.suboperations.append(ResOperation(rop.SETARRAYITEM_GC,
+            [node.source, field, node.cleanfields[field].source], None, descr))
         op.suboperations.append(op_fail)
         op.args = self.new_arguments(op)
+        return op
 
     def optimize_operations(self):
         self.additional_stores = {}
+        self.additional_setarrayitems = {}
         newoperations = []
         for op in self.loop.operations:
             newop = op
@@ -110,13 +124,14 @@
             if newop is None:
                 continue
             if op.is_guard():
-                self.optimize_guard(op)
-                newoperations.append(op)
+                op = self.optimize_guard(op)
+                if op is not None:
+                    newoperations.append(op)
                 continue
             # default handler
             op = op.clone()
             op.args = self.new_arguments(op)
-            if op.is_always_pure():
+            if op.is_always_pure() or op.is_guard():
                 for box in op.args:
                     if isinstance(box, Box):
                         break
@@ -164,7 +179,9 @@
         if node is not None:
             spec.nodes[op.result] = node
             return None
-        instnode.cleanfields[field] = spec.getnode(op.result)
+        node = spec.getnode(op.result)
+        node.possibly_virtualized_list = True
+        instnode.cleanfields[field] = node
         return op
 
     def optimize_setfield_gc(self, op, spec):
@@ -180,6 +197,35 @@
         spec.additional_stores[instnode, field] = node
         return None
 
+    def optimize_getarrayitem_gc(self, op, spec):
+        instnode = spec.getnode(op.args[0])
+        if not instnode.possibly_virtualized_list:
+            return op
+        if not spec.getnode(op.args[1]).const:
+            raise VirtualizedListAccessedWithVariableArg()
+        field = spec.getnode(op.args[1]).source
+        node = instnode.cleanfields.get(field, None)
+        if node is not None:
+            spec.nodes[op.result] = node
+            return None
+        node = spec.getnode(op.result)
+        instnode.cleanfields[field] = node
+        return op
+        
+
+    def optimize_setarrayitem_gc(self, op, spec):
+        instnode = spec.getnode(op.args[0])
+        if not instnode.possibly_virtualized_list:
+            return op
+        fieldnode = spec.getnode(op.args[1])
+        if not fieldnode.const:
+            raise VirtualizedListAccessedWithVariableArg()
+        node = spec.getnode(op.args[2])
+        field = fieldnode.source
+        instnode.cleanfields[field] = node
+        spec.additional_setarrayitems[instnode, field] = (node, op.descr)
+        return None
+
 specializer = Specializer([SimpleVirtualizableOpt(),
                            ConsecutiveGuardClassRemoval()])
 
@@ -200,3 +246,4 @@
     optimize_bridge = staticmethod(optimize_bridge)
 
 
+

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 04:31:44 2009
@@ -56,11 +56,16 @@
     nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
     nodedescr = cpu.fielddescrof(NODE, 'value')
 
+    TP = lltype.GcArray(lltype.Signed)
+
     XY = lltype.GcStruct('XY', ('inst_field', lltype.Signed),
                          ('inst_other_field', lltype.Signed),
+                         ('inst_list', lltype.Ptr(TP)),
                          hints= {'virtualizable2': True,
-                                 'virtuals': ('field',)})
+                                 'virtuals': ('field','list')})
     field_desc = cpu.fielddescrof(XY, 'inst_field')
+    array_descr = cpu.arraydescrof(TP)
+    list_desc = cpu.fielddescrof(XY, 'inst_list')
     other_field_desc = cpu.fielddescrof(XY, 'inst_other_field')
     vdesc = VirtualizableDesc(cpu, XY, XY)
 
@@ -85,7 +90,10 @@
 class BaseTestOptimize2(object):
 
     def optimize(self, lst, optimizations_enabled=[]):
-        loop = parse(lst, self.cpu, self.namespace)
+        if not isinstance(lst, TreeLoop):
+            loop = parse(lst, self.cpu, self.namespace)
+        else:
+            loop = lst
         optimize_loop(None, [], loop, self.cpu,
                       spec=Specializer(optimizations_enabled))
         return loop.operations
@@ -160,7 +168,67 @@
         """
         self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
                           expected)
-        
+
+    def test_const_guard_value(self):
+        pre_op = """
+        []
+        guard_value(0, 0)
+            fail()
+        """
+        expected = "[]"
+        self.assert_equal(self.optimize(pre_op, []), expected)
+
+    def test_virtualized_list_on_virtualizable(self):
+        pre_op = """
+        [p0]
+        guard_nonvirtualized(p0, vdesc=vdesc)
+            fail()
+        p1 = getfield_gc(p0, descr=list_desc)
+        setarrayitem_gc(p1, 0, 1, descr=array_descr)
+        i1 = getarrayitem_gc(p1, 0)
+        i2 = int_add(i1, i1)
+        i3 = int_is_true(i2)
+        guard_true(i3)
+            fail()
+        """
+        pre_op = parse(pre_op, self.cpu, self.namespace)
+        # cheat
+        pre_op.operations[-2].result.value = 1
+        expected = """
+        [p0]
+        p1 = getfield_gc(p0, descr=list_desc)
+        """
+        self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
+                          expected)        
+
+
+    def test_virtualized_list_on_virtualizable_2(self):
+        pre_op = """
+        [p0, i0]
+        guard_nonvirtualized(p0, vdesc=vdesc)
+            fail()
+        p1 = getfield_gc(p0, descr=list_desc)
+        setarrayitem_gc(p1, 0, i0, descr=array_descr)
+        i1 = getarrayitem_gc(p1, 0)
+        i2 = int_add(i1, i1)
+        i3 = int_is_true(i2)
+        guard_true(i3)
+            fail()
+        """
+        pre_op = parse(pre_op, self.cpu, self.namespace)
+        # cheat
+        pre_op.operations[-2].result.value = 1
+        expected = """
+        [p0, i0]
+        p1 = getfield_gc(p0, descr=list_desc)
+        i2 = int_add(i0, i0)
+        i3 = int_is_true(i2)
+        guard_true(i3)
+            setarrayitem_gc(p1, 0, i0, descr=array_descr)
+            fail()
+        """
+        self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
+                          expected)        
 
     def test_remove_consecutive_guard_value_constfold(self):
         py.test.skip("not yet")



More information about the Pypy-commit mailing list