[pypy-svn] pypy jit-short-preamble: chain lazy setfields following a getfield

hakanardo commits-noreply at bitbucket.org
Fri Jan 14 08:36:47 CET 2011


Author: Hakan Ardo <hakan at debian.org>
Branch: jit-short-preamble
Changeset: r40655:a6dbb0663618
Date: 2011-01-14 08:36 +0100
http://bitbucket.org/pypy/pypy/changeset/a6dbb0663618/

Log:	chain lazy setfields following a getfield

diff --git a/pypy/jit/metainterp/test/test_optimizeopt.py b/pypy/jit/metainterp/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/test/test_optimizeopt.py
@@ -4609,6 +4609,26 @@
         """
         self.optimize_loop(ops, expected, preamble)
 
+    def test_let_getfield_kill_chained_setfields(self):
+        ops = """
+        [p0]
+        p1 = getfield_gc(p0, descr=valuedescr)
+        setfield_gc(p0, p0, descr=valuedescr)        
+        setfield_gc(p0, p1, descr=valuedescr)
+        setfield_gc(p0, p1, descr=valuedescr)
+        jump(p0)
+        """
+        preamble = """
+        [p0]
+        p1 = getfield_gc(p0, descr=valuedescr)
+        jump(p0)
+        """
+        expected = """
+        [p0]
+        jump(p0)
+        """
+        self.optimize_loop(ops, expected, preamble)
+
     def test_inputargs_added_by_forcing_jumpargs(self):
         # FXIME: Can this occur?
         ops = """

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
@@ -17,6 +17,7 @@
     def __init__(self):
         # cached fields:  {descr: {OptValue_instance: OptValue_fieldvalue}}
         self.cached_fields = {}
+        self.known_heap_fields = {}
         # cached array items:  {descr: CachedArrayItems}
         self.cached_arrayitems = {}
         # lazily written setfields (at most one per descr):  {descr: op}
@@ -41,6 +42,13 @@
                 newd[value.get_reconstructed(optimizer, valuemap)] = \
                                        fieldvalue.get_reconstructed(optimizer, valuemap)
             
+        for descr, d in self.known_heap_fields.items():
+            newd = {}
+            new.known_heap_fields[descr] = newd
+            for value, fieldvalue in d.items():
+                newd[value.get_reconstructed(optimizer, valuemap)] = \
+                                       fieldvalue.get_reconstructed(optimizer, valuemap)
+            
         new.cached_arrayitems = {}
         for descr, d in self.cached_arrayitems.items():
             newd = {}
@@ -62,6 +70,7 @@
 
     def clean_caches(self):
         self.cached_fields.clear()
+        self.known_heap_fields.clear()
         self.cached_arrayitems.clear()
 
     def cache_field_value(self, descr, value, fieldvalue, write=False):
@@ -166,6 +175,7 @@
                     self.force_lazy_setfield(fielddescr)
                     try:
                         del self.cached_fields[fielddescr]
+                        del self.known_heap_fields[fielddescr]
                     except KeyError:
                         pass
                 for arraydescr in effectinfo.write_descrs_arrays:
@@ -202,9 +212,16 @@
         except KeyError:
             return
         del self.lazy_setfields[descr]
-        ###self.optimizer._emit_operation(op)
+        value = self.getvalue(op.getarg(0))
+        fieldvalue = self.getvalue(op.getarg(1))
+        try:
+            heapvalue = self.known_heap_fields[op.getdescr()][value]
+            if fieldvalue is heapvalue:
+                return
+        except KeyError:
+            pass
         self.next_optimization.propagate_forward(op)
-        #
+
         # hackish: reverse the order of the last two operations if it makes
         # sense to avoid a situation like "int_eq/setfield_gc/guard_true",
         # which the backend (at least the x86 backend) does not handle well.
@@ -272,10 +289,13 @@
         # default case: produce the operation
         value.ensure_nonnull()
         ###self.optimizer.optimize_default(op)
-        self.emit_operation(op) # FIXME: These might need constant propagation?
+        self.emit_operation(op)
         # then remember the result of reading the field
         fieldvalue = self.getvalue(op.result)
         self.cache_field_value(op.getdescr(), value, fieldvalue)
+        # keep track of what's on the heap
+        d = self.known_heap_fields.setdefault(op.getdescr(), {})
+        d[value] = fieldvalue
 
     def optimize_SETFIELD_GC(self, op):
         value = self.getvalue(op.getarg(0))
@@ -295,7 +315,7 @@
             self.make_equal_to(op.result, fieldvalue)
             return
         ###self.optimizer.optimize_default(op)
-        self.emit_operation(op) # FIXME: These might need constant propagation?
+        self.emit_operation(op)
         fieldvalue = self.getvalue(op.result)
         self.cache_arrayitem_value(op.getdescr(), value, indexvalue, fieldvalue)
 


More information about the Pypy-commit mailing list