[pypy-svn] pypy jit-short_from_state: reenabled getarrayitem support without caching setarrayitems across loop boundaries

hakanardo commits-noreply at bitbucket.org
Thu Apr 21 07:46:35 CEST 2011


Author: Hakan Ardo <hakan at debian.org>
Branch: jit-short_from_state
Changeset: r43503:16de1276f38a
Date: 2011-04-21 07:45 +0200
http://bitbucket.org/pypy/pypy/changeset/16de1276f38a/

Log:	reenabled getarrayitem support without caching setarrayitems across
	loop boundaries

diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -2032,6 +2032,46 @@
             return sa
         res = self.meta_interp(f, [32, 7])
         assert res == f(32, 7)
+        
+    def test_caching_setarrayitem_fixed(self):
+        myjitdriver = JitDriver(greens = [], reds = ['sa', 'i', 'n', 'a', 'node'])
+        def f(n, a):
+            i = sa = 0
+            node = [1, 2, 3]
+            while i < n:
+                myjitdriver.can_enter_jit(sa=sa, i=i, n=n, a=a, node=node)
+                myjitdriver.jit_merge_point(sa=sa, i=i, n=n, a=a, node=node)
+                sa += node[0] + node[1]
+                if i < n/2:
+                    node[0] = a
+                    node[1] = a
+                else:
+                    node[0] = a
+                    node[1] = a + 1
+                i += 1
+            return sa
+        res = self.meta_interp(f, [32, 7])
+        assert res == f(32, 7)
+        
+    def test_caching_setarrayitem_var(self):
+        myjitdriver = JitDriver(greens = [], reds = ['sa', 'i', 'n', 'a', 'b', 'node'])
+        def f(n, a, b):
+            i = sa = 0
+            node = [1, 2, 3]
+            while i < n:
+                myjitdriver.can_enter_jit(sa=sa, i=i, n=n, a=a, b=b, node=node)
+                myjitdriver.jit_merge_point(sa=sa, i=i, n=n, a=a, b=b, node=node)
+                sa += node[0] + node[b]
+                if i < n/2:
+                    node[0] = a
+                    node[b] = a
+                else:
+                    node[0] = a
+                    node[b] = a + 1
+                i += 1
+            return sa
+        res = self.meta_interp(f, [32, 7, 2])
+        assert res == f(32, 7, 2)
 
     def test_getfield_result_with_intbound(self):
         myjitdriver = JitDriver(greens = [], reds = ['sa', 'i', 'n', 'a', 'node'])

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
@@ -118,8 +118,10 @@
 class CachedArrayItems(object):
     def __init__(self):
         self.fixed_index_items = {}
+        self.fixed_index_getops = {}
         self.var_index_item = None
         self.var_index_indexvalue = None
+        self.var_index_getop = None
 
 class BogusPureField(JitException):
     pass
@@ -148,8 +150,6 @@
         for descr, d in self.cached_fields.items():
             new.cached_fields[descr] = d.get_cloned(optimizer, valuemap)
 
-        return new
-
         new.cached_arrayitems = {}
         for descr, d in self.cached_arrayitems.items():
             newd = {}
@@ -157,7 +157,7 @@
             for value, cache in d.items():
                 newcache = CachedArrayItems()
                 newd[value.get_cloned(optimizer, valuemap)] = newcache
-                if cache.var_index_item:
+                if cache.var_index_item and cache.var_index_getop:
                     newcache.var_index_item = \
                           cache.var_index_item.get_cloned(optimizer, valuemap)
                 if cache.var_index_indexvalue:
@@ -165,7 +165,8 @@
                           cache.var_index_indexvalue.get_cloned(optimizer,
                                                                 valuemap)
                 for index, fieldvalue in cache.fixed_index_items.items():
-                    newcache.fixed_index_items[index] = \
+                    if cache.fixed_index_getops.get(index, None):
+                        newcache.fixed_index_items[index] = \
                            fieldvalue.get_cloned(optimizer, valuemap)
 
         return new
@@ -175,22 +176,16 @@
             d.produce_potential_short_preamble_ops(self.optimizer,
                                                    potential_ops, descr)
 
-        # FIXME
         for descr, d in self.cached_arrayitems.items():
             for value, cache in d.items():
-                for index, fieldvalue in cache.fixed_index_items.items():
-                    result = fieldvalue.get_key_box()
-                    op = ResOperation(rop.GETARRAYITEM_GC,
-                                      [value.get_key_box(), ConstInt(index)],
-                                      result, descr)
-                    potential_ops[result] = op
+                for index in cache.fixed_index_items.keys():
+                    op = cache.fixed_index_getops[index]
+                    if op:
+                        potential_ops[op.result] = op
                 if cache.var_index_item and cache.var_index_indexvalue:
-                    result = cache.var_index_item.get_key_box()
-                    op = ResOperation(rop.GETARRAYITEM_GC,
-                                      [value.get_key_box(),
-                                       cache.var_index_indexvalue.get_key_box()],
-                                      result, descr)
-                    potential_ops[result] = op
+                    op = cache.var_index_getop
+                    if op:
+                        potential_ops[op.result] = op
                     
 
     def clean_caches(self):
@@ -205,7 +200,8 @@
             cf = self.cached_fields[descr] = CachedField()
         return cf
 
-    def cache_arrayitem_value(self, descr, value, indexvalue, fieldvalue, write=False):
+    def cache_arrayitem_value(self, descr, value, indexvalue, fieldvalue,
+                              write=False, getop=None):
         d = self.cached_arrayitems.get(descr, None)
         if d is None:
             d = self.cached_arrayitems[descr] = {}
@@ -223,9 +219,11 @@
                     othercache.var_index_item = None
                     try:
                         del othercache.fixed_index_items[index]
+                        del othercache.fixed_index_getops[index]
                     except KeyError:
                         pass
             cache.fixed_index_items[index] = fieldvalue
+            cache.fixed_index_getops[index] = getop
         else:
             if write:
                 for value, othercache in d.iteritems():
@@ -233,8 +231,10 @@
                     othercache.var_index_indexvalue = None
                     othercache.var_index_item = None
                     othercache.fixed_index_items.clear()
+                    othercache.fixed_index_getops.clear()
             cache.var_index_indexvalue = indexvalue
             cache.var_index_item = fieldvalue
+            cache.var_index_getop = getop
 
     def read_cached_arrayitem(self, descr, value, indexvalue):
         d = self.cached_arrayitems.get(descr, None)
@@ -388,9 +388,9 @@
             structvalue.ensure_nonnull()
             ###self.optimizer.optimize_default(op)
             self.emit_operation(op)
-        # then remember the result of reading the field
-        fieldvalue = self.getvalue(op.result)
-        cf.remember_field_value(structvalue, fieldvalue, op)
+            # then remember the result of reading the field
+            fieldvalue = self.getvalue(op.result)
+            cf.remember_field_value(structvalue, fieldvalue, op)
 
     def optimize_SETFIELD_GC(self, op):
         if self.has_pure_result(rop.GETFIELD_GC_PURE, [op.getarg(0)],
@@ -412,7 +412,8 @@
         ###self.optimizer.optimize_default(op)
         self.emit_operation(op)
         fieldvalue = self.getvalue(op.result)
-        self.cache_arrayitem_value(op.getdescr(), value, indexvalue, fieldvalue)
+        self.cache_arrayitem_value(op.getdescr(), value, indexvalue, fieldvalue,
+                                   getop=op)
 
     def optimize_SETARRAYITEM_GC(self, op):
         self.emit_operation(op)


More information about the Pypy-commit mailing list