[pypy-commit] pypy jit-optimizeopt-cleanups: Force most virtuals in OptEarlyForce. This makes the heap optimizer aware of the setitems produced by foring.

hakanardo noreply at buildbot.pypy.org
Thu Sep 29 20:00:56 CEST 2011


Author: Hakan Ardo <hakan at debian.org>
Branch: jit-optimizeopt-cleanups
Changeset: r47688:c90c3e62b416
Date: 2011-09-29 20:00 +0200
http://bitbucket.org/pypy/pypy/changeset/c90c3e62b416/

Log:	Force most virtuals in OptEarlyForce. This makes the heap optimizer
	aware of the setitems produced by foring.

diff --git a/pypy/jit/metainterp/optimizeopt/earlyforce.py b/pypy/jit/metainterp/optimizeopt/earlyforce.py
--- a/pypy/jit/metainterp/optimizeopt/earlyforce.py
+++ b/pypy/jit/metainterp/optimizeopt/earlyforce.py
@@ -1,12 +1,17 @@
 from pypy.jit.metainterp.optimizeopt.optimizer import Optimization
 from pypy.jit.metainterp.optimizeopt.vstring import VAbstractStringValue
+from pypy.jit.metainterp.resoperation import rop, ResOperation
 
 class OptEarlyForce(Optimization):
     def propagate_forward(self, op):
-        for arg in op.getarglist():
-            if arg in self.optimizer.values:
-                value = self.getvalue(arg)
-                if isinstance(value, VAbstractStringValue):
+        opnum = op.getopnum()
+        if (opnum != rop.SETFIELD_GC and 
+            opnum != rop.SETARRAYITEM_GC and
+            opnum != rop.QUASIIMMUT_FIELD):
+               
+            for arg in op.getarglist():
+                if arg in self.optimizer.values:
+                    value = self.getvalue(arg)
                     value.force_box(self)
         self.emit_operation(op)
 
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
@@ -370,9 +370,6 @@
         cf.remember_field_value(structvalue, fieldvalue, op)
 
     def optimize_SETFIELD_GC(self, op):
-        if op in self.optimizer.volatile:
-            self.emit_operation(op)
-            return
         if self.has_pure_result(rop.GETFIELD_GC_PURE, [op.getarg(0)],
                                 op.getdescr()):
             os.write(2, '[bogus _immutable_field_ declaration: %s]\n' %
@@ -414,9 +411,6 @@
                      (op.getdescr().repr_of_descr()))
             raise BogusPureField
         #
-        if op in self.optimizer.volatile:
-            self.emit_operation(op)
-            return
         indexvalue = self.getvalue(op.getarg(1))
         if indexvalue.is_constant():
             arrayvalue = self.getvalue(op.getarg(0))
diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -246,10 +246,6 @@
     def emit_operation(self, op):
         self.next_optimization.propagate_forward(op)
 
-    def emit_volatile_operation(self, op):
-        self.optimizer.volatile[op] = True
-        self.emit_operation(op)
-
     # FIXME: Move some of these here?
     def getvalue(self, box):
         return self.optimizer.getvalue(box)
@@ -335,7 +331,6 @@
         self.opaque_pointers = {}
         self.replaces_guard = {}
         self.newoperations = []
-        self.volatile = {}
         self.optimizer = self
         self.optpure = None
         self.optearlyforce = None
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -652,8 +652,8 @@
         i3 = getfield_gc(p3, descr=valuedescr)
         escape(i3)
         p1 = new_with_vtable(ConstClass(node_vtable))
+        p1sub = new_with_vtable(ConstClass(node_vtable2))
         setfield_gc(p1, i1, descr=valuedescr)
-        p1sub = new_with_vtable(ConstClass(node_vtable2))
         setfield_gc(p1sub, i1, descr=valuedescr)
         setfield_gc(p1, p1sub, descr=nextdescr)
         jump(i1, p1, p2)
@@ -668,10 +668,10 @@
         p3sub = getfield_gc(p3, descr=nextdescr)
         i3 = getfield_gc(p3sub, descr=valuedescr)
         escape(i3)
+        p1 = new_with_vtable(ConstClass(node_vtable))
         p2sub = new_with_vtable(ConstClass(node_vtable2))
         setfield_gc(p2sub, i1, descr=valuedescr)
         setfield_gc(p2, p2sub, descr=nextdescr)
-        p1 = new_with_vtable(ConstClass(node_vtable))
         jump(i1, p1, p2)
         """
         # The same as test_p123_simple, but in the end the "old" p2 contains
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
@@ -825,8 +825,8 @@
         i3 = getfield_gc(p2, descr=valuedescr)
         escape(i3)
         p4 = new_with_vtable(ConstClass(node_vtable))
+        p1sub = new_with_vtable(ConstClass(node_vtable2))
         setfield_gc(p4, i1, descr=valuedescr)
-        p1sub = new_with_vtable(ConstClass(node_vtable2))
         setfield_gc(p1sub, i1, descr=valuedescr)
         setfield_gc(p4, p1sub, descr=nextdescr)
         jump(i1, p4)
@@ -865,13 +865,7 @@
         p3sub = new_with_vtable(ConstClass(node_vtable2))
         setfield_gc(p3sub, i1, descr=valuedescr)
         setfield_gc(p1, p3sub, descr=nextdescr)
-        # XXX: We get two extra operations here because the setfield
-        #      above is the result of forcing p1 and thus not
-        #      registered with the heap optimizer. I've makred tests
-        #      below with VIRTUALHEAP if they suffer from this issue
-        p3sub2 = getfield_gc(p1, descr=nextdescr)
-        guard_nonnull_class(p3sub2, ConstClass(node_vtable2)) []
-        jump(i1, p1, p3sub2)
+        jump(i1, p1, p3sub)
         """
         self.optimize_loop(ops, expected, preamble)
 
@@ -902,9 +896,7 @@
         guard_true(i2b) []
         p3 = new_with_vtable(ConstClass(node_vtable))
         setfield_gc(p3, i2, descr=nextdescr)
-        # XXX: VIRTUALHEAP (see above)
-        i3 = getfield_gc(p3, descr=nextdescr)
-        jump(p3, i3)
+        jump(p3, i2)
         """
         self.optimize_loop(ops, expected, preamble)
 
@@ -1219,7 +1211,15 @@
         setfield_gc(p3, p30, descr=valuedescr)
         jump(i29, p30, p3)
         """
-        expected = preamble
+        expected = """
+        [i0, p1, p3]
+        i28 = int_add(i0, 1)
+        i29 = int_add(i28, 1)
+        p30 = new_with_vtable(ConstClass(node_vtable))
+        setfield_gc(p3, p30, descr=valuedescr)
+        setfield_gc(p30, i28, descr=nextdescr)
+        jump(i29, p30, p3)
+        """
         self.optimize_loop(ops, expected, preamble)
 
     def test_nonvirtual_1(self):
@@ -2408,8 +2408,8 @@
         guard_class(p2, ConstClass(node_vtable)) []
         p3 = getfield_gc(p1, descr=otherdescr)
         guard_class(p3, ConstClass(node_vtable)) []
+        p3a = new_with_vtable(ConstClass(node_vtable))
         setfield_gc(p3, p2, descr=otherdescr)
-        p3a = new_with_vtable(ConstClass(node_vtable))
         escape(p3a)
         jump(p3a)
         """
@@ -2421,9 +2421,9 @@
         # setfield_gc(p3, p2, descr=otherdescr) # p3a.other = p2a
         # p1a = new_with_vtable(ConstClass(node_vtable2))
         # p2a = new_with_vtable(ConstClass(node_vtable))
+        p3anew = new_with_vtable(ConstClass(node_vtable))
         p2 = new_with_vtable(ConstClass(node_vtable))
         setfield_gc(p3a, p2, descr=otherdescr) # p3a.other = p2a
-        p3anew = new_with_vtable(ConstClass(node_vtable))
         escape(p3anew)
         jump(p3anew)
         """
@@ -2458,9 +2458,9 @@
         p3 = getfield_gc(p1, descr=otherdescr)
         guard_class(p3, ConstClass(node_vtable)) []
         # p1a = new_with_vtable(ConstClass(node_vtable2))
+        p3a = new_with_vtable(ConstClass(node_vtable))
         p2a = new_with_vtable(ConstClass(node_vtable))
         setfield_gc(p3, p2a, descr=otherdescr)
-        p3a = new_with_vtable(ConstClass(node_vtable))
         escape(p3a)
         # setfield_gc(p1a, p2a, descr=nextdescr)
         # setfield_gc(p1a, p3a, descr=otherdescr)
@@ -2468,9 +2468,9 @@
         """
         expected = """
         [p2, p3]
+        p3a = new_with_vtable(ConstClass(node_vtable))
         p2a = new_with_vtable(ConstClass(node_vtable))
         setfield_gc(p3, p2a, descr=otherdescr)
-        p3a = new_with_vtable(ConstClass(node_vtable))
         escape(p3a)
         jump(p2a, p3a)
         """
@@ -7229,6 +7229,29 @@
         """
         self.optimize_loop(ops, expected)
 
+    def test_heap_cache_forced_virtuals(self):
+        ops = """
+        [i1, i2, p0]
+        p1 = new(descr=ssize)
+        setfield_gc(p1, i1, descr=adescr)
+        setfield_gc(p1, i2, descr=bdescr)
+        call(p0, p1, descr=writeadescr)
+        i3 = getfield_gc(p1, descr=adescr)
+        i4 = getfield_gc(p1, descr=bdescr)
+        jump(i3, i4, p0)
+        """
+        expected = """
+        [i1, i2, p0]
+        p1 = new(descr=ssize)
+        setfield_gc(p1, i1, descr=adescr)
+        call(p0, p1, descr=writeadescr)
+        i3 = getfield_gc(p1, descr=adescr)
+        setfield_gc(p1, i2, descr=bdescr)
+        jump(i3, i2, p0)
+        """
+        self.optimize_loop(ops, expected)
+
+
 class TestLLtype(OptimizeOptTest, LLtypeMixin):
     pass
 
diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py
--- a/pypy/jit/metainterp/optimizeopt/virtualize.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualize.py
@@ -138,7 +138,7 @@
                 op = ResOperation(rop.SETFIELD_GC, [box, subbox], None,
                                   descr=ofs)
 
-                optforce.emit_volatile_operation(op)
+                optforce.emit_operation(op)
 
     def _get_field_descr_list(self):
         _cached_sorted_fields = self._cached_sorted_fields
@@ -255,7 +255,7 @@
                 op = ResOperation(rop.SETARRAYITEM_GC,
                                   [box, ConstInt(index), subbox], None,
                                   descr=self.arraydescr)
-                optforce.emit_volatile_operation(op)
+                optforce.emit_operation(op)
 
     def get_args_for_fail(self, modifier):
         if self.box is None and not modifier.already_seen_virtual(self.keybox):


More information about the pypy-commit mailing list