[pypy-commit] pypy jit-short_from_state: cache constant setfields across loop boundaries

hakanardo noreply at buildbot.pypy.org
Tue Aug 9 17:13:12 CEST 2011


Author: Hakan Ardo <hakan at debian.org>
Branch: jit-short_from_state
Changeset: r46397:ade2411fa731
Date: 2011-08-06 14:51 +0200
http://bitbucket.org/pypy/pypy/changeset/ade2411fa731/

Log:	cache constant setfields across loop boundaries

diff --git a/pypy/jit/metainterp/optimizeopt/heap.py b/pypy/jit/metainterp/optimizeopt/heap.py
--- a/pypy/jit/metainterp/optimizeopt/heap.py
+++ b/pypy/jit/metainterp/optimizeopt/heap.py
@@ -134,6 +134,10 @@
             if structvalue in self._cached_fields:
                 if op.getopnum() == rop.SETFIELD_GC:
                     result = op.getarg(1)
+                    if isinstance(result, Const):
+                        newresult = result.clonebox()
+                        shortboxes.alias(newresult, result)
+                        result = newresult
                     getop = ResOperation(rop.GETFIELD_GC, [op.getarg(0)],
                                          result, op.getdescr())
                     getop = shortboxes.add_potential(getop)
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -6903,6 +6903,30 @@
         """
         self.optimize_loop(ops, expected)
 
+    def test_cache_constant_setfield(self):
+        ops = """
+        [p5]
+        i10 = getfield_gc(p5, descr=valuedescr)
+        call(i10, descr=nonwritedescr) 
+        setfield_gc(p5, 1, descr=valuedescr)
+        jump(p5)
+        """
+        preamble = """
+        [p5]
+        i10 = getfield_gc(p5, descr=valuedescr)
+        call(i10, descr=nonwritedescr) 
+        setfield_gc(p5, 1, descr=valuedescr)
+        jump(p5, 1)
+        """
+        expected = """
+        [p5, i10]
+        call(i10, descr=nonwritedescr) 
+        setfield_gc(p5, 1, descr=valuedescr)
+        jump(p5, 1)
+        """
+        
+        self.optimize_loop(ops, expected, preamble)
+        
 class TestLLtype(OptimizeOptTest, LLtypeMixin):
     pass
         
diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -494,7 +494,7 @@
 
         short_op = self.short_boxes.producer(box)
         newresult = self.add_op_to_short(short_op, short, short_seen)
-        
+
         short_jumpargs.append(short_op.result)
         inputargs.append(box)
         box = newresult
diff --git a/pypy/jit/metainterp/optimizeopt/virtualstate.py b/pypy/jit/metainterp/optimizeopt/virtualstate.py
--- a/pypy/jit/metainterp/optimizeopt/virtualstate.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualstate.py
@@ -457,12 +457,12 @@
     def __init__(self, optimizer, surviving_boxes):
         self.potential_ops = {}
         self.duplicates = {}
+        self.aliases = {}
         self.optimizer = optimizer
         for box in surviving_boxes:
             self.potential_ops[box] = None
         optimizer.produce_potential_short_preamble_ops(self)
 
-        self.aliases = {}
         self.short_boxes = {}
 
         for box in self.potential_ops.keys():
@@ -518,7 +518,8 @@
         return box in self.short_boxes
 
     def alias(self, newbox, oldbox):
-        self.short_boxes[newbox] = self.short_boxes[oldbox]
+        if not isinstance(oldbox, Const):
+            self.short_boxes[newbox] = self.short_boxes[oldbox]
         self.aliases[newbox] = oldbox
         
     def original(self, box):
diff --git a/pypy/jit/metainterp/test/test_virtualstate.py b/pypy/jit/metainterp/test/test_virtualstate.py
--- a/pypy/jit/metainterp/test/test_virtualstate.py
+++ b/pypy/jit/metainterp/test/test_virtualstate.py
@@ -533,7 +533,7 @@
         i2 = getarrayitem_gc(p1, 10, descr=arraydescr)
         call(i2, descr=nonwritedescr)
         i3 = arraylen_gc(p1, descr=arraydescr) # Should be killed by backend
-        jump(p0, i2)
+        jump(p0, i2, p1)
         """
         self.optimize_bridge(loop, loop, expected)
         bridge = """
@@ -548,7 +548,7 @@
         i2 = getarrayitem_gc(p1, 15, descr=arraydescr)
         i3 = arraylen_gc(p1, descr=arraydescr) # Should be killed by backend        
         i4 = getarrayitem_gc(p1, 10, descr=arraydescr)
-        jump(p0, i4)
+        jump(p0, i4, p1)
         """        
         self.optimize_bridge(loop, bridge, expected)
         bridge = """
@@ -565,7 +565,7 @@
         i4 = int_ge(i3, 11)
         guard_true(i4) []
         i5 = getarrayitem_gc(p1, 10, descr=arraydescr)
-        jump(p0, i5)
+        jump(p0, i5, p1)
         """        
         self.optimize_bridge(loop, bridge, expected)
         bridge = """
@@ -581,7 +581,7 @@
         i4 = int_ge(i3, 11)
         guard_true(i4) []
         i5 = getarrayitem_gc(p1, 10, descr=arraydescr)
-        jump(p0, i5)
+        jump(p0, i5, p1)
         """        
         self.optimize_bridge(loop, bridge, expected, p0=self.myptr)
 
@@ -611,6 +611,37 @@
         """
         self.optimize_bridge(loop, bridge, expected, p0=self.myptr)
 
+    def test_cache_constant_setfield(self):
+        loop = """
+        [p5]
+        i10 = getfield_gc(p5, descr=valuedescr)
+        call(i10, descr=nonwritedescr) 
+        setfield_gc(p5, 1, descr=valuedescr)
+        jump(p5)
+        """
+        bridge = """
+        [p0]
+        jump(p0)
+        """
+        expected = """
+        [p0]
+        guard_nonnull(p0) []
+        i10 = getfield_gc(p0, descr=valuedescr)
+        jump(p0, i10)
+        """
+        self.optimize_bridge(loop, bridge, expected, p0=self.myptr)        
+        bridge = """
+        [p0]
+        setfield_gc(p0, 7, descr=valuedescr)
+        jump(p0)
+        """
+        expected = """
+        [p0]
+        setfield_gc(p0, 7, descr=valuedescr)
+        jump(p0, 7)
+        """
+        self.optimize_bridge(loop, bridge, expected, p0=self.myptr)        
+        
 
 class TestLLtypeGuards(BaseTestGenerateGuards, LLtypeMixin):
     pass
diff --git a/pypy/module/pypyjit/test_pypy_c/test_call.py b/pypy/module/pypyjit/test_pypy_c/test_call.py
--- a/pypy/module/pypyjit/test_pypy_c/test_call.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_call.py
@@ -187,7 +187,7 @@
             guard_no_overflow(descr=...)
             i18 = force_token()
             --TICK--
-            jump(p0, p1, p2, p3, p4, i8, p7, i17, p8, i9, p10, p11, p12, descr=<Loop0>)
+            jump(p0, p1, p2, p3, p4, i8, p7, i17, p8, i9, i17, p10, p11, p12, descr=<Loop0>)
         """)
 
     def test_default_and_kw(self):


More information about the pypy-commit mailing list