[pypy-svn] r78956 - in pypy/branch/rlist-jit/pypy: jit/codewriter jit/metainterp jit/metainterp/test jit/tl rpython

arigo at codespeak.net arigo at codespeak.net
Wed Nov 10 11:46:18 CET 2010


Author: arigo
Date: Wed Nov 10 11:46:14 2010
New Revision: 78956

Modified:
   pypy/branch/rlist-jit/pypy/jit/codewriter/jtransform.py
   pypy/branch/rlist-jit/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/rlist-jit/pypy/jit/metainterp/test/test_recursive.py
   pypy/branch/rlist-jit/pypy/jit/metainterp/test/test_virtualizable.py
   pypy/branch/rlist-jit/pypy/jit/metainterp/warmspot.py
   pypy/branch/rlist-jit/pypy/jit/tl/tl.py
   pypy/branch/rlist-jit/pypy/rpython/rlist.py
Log:
Fixes a few failing tests.  Adds a requirement: virtualizable2
arrays specified with 'lst[*]' must be accessed using non-negative,
non-raising getitems and setitems.  (This requirement was implicit
before, in the sense that it mostly worked to do negative indexing
except at one place in pyjitpl.)


Modified: pypy/branch/rlist-jit/pypy/jit/codewriter/jtransform.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/jit/codewriter/jtransform.py	(original)
+++ pypy/branch/rlist-jit/pypy/jit/codewriter/jtransform.py	Wed Nov 10 11:46:14 2010
@@ -82,6 +82,7 @@
         self.follow_constant_exit(block)
         self.optimize_goto_if_not(block)
         for link in block.exits:
+            self._check_no_vable_array(link.args)
             self._do_renaming_on_link(renamings, link)
 
     def _do_renaming(self, rename, op):
@@ -99,6 +100,26 @@
                 op.args[i] = ListOfKind(v.kind, newlst)
         return op
 
+    def _check_no_vable_array(self, list):
+        for v in list:
+            if v in self.vable_array_vars:
+                raise AssertionError(
+                    "A virtualizable array is passed around; it should\n"
+                    "only be used immediately after being read.  Note\n"
+                    "that a possible cause is indexing with an index not\n"
+                    "known non-negative, or catching IndexError, or\n"
+                    "not inlining at all (for tests: use listops=True).\n"
+                    "Occurred in: %r" % self.graph)
+            # extra expanation: with the way things are organized in
+            # rpython/rlist.py, the ll_getitem becomes a function call
+            # that is typically meant to be inlined by the JIT, but
+            # this does not work with vable arrays because
+            # jtransform.py expects the getfield and the getarrayitem
+            # to be in the same basic block.  It works a bit as a hack
+            # for simple cases where we performed the backendopt
+            # inlining before (even with a very low threshold, because
+            # there is _always_inline_ on the relevant functions).
+
     def _do_renaming_on_link(self, rename, link):
         for i, v in enumerate(link.args):
             if isinstance(v, Variable):
@@ -169,7 +190,10 @@
         else:
             return rewrite(self, op)
 
-    def rewrite_op_same_as(self, op): pass
+    def rewrite_op_same_as(self, op):
+        if op.args[0] in self.vable_array_vars:
+            self.vable_array_vars[op.result]= self.vable_array_vars[op.args[0]]
+
     def rewrite_op_cast_pointer(self, op): pass
     def rewrite_op_cast_opaque_ptr(self, op): pass   # rlib.rerased
     def rewrite_op_cast_primitive(self, op): pass
@@ -256,6 +280,7 @@
            The name is one of '{residual,direct}_call_{r,ir,irf}_{i,r,f,v}'."""
         if args is None:
             args = op.args[1:]
+        self._check_no_vable_array(args)
         lst_i, lst_r, lst_f = self.make_three_lists(args)
         reskind = getkind(op.result.concretetype)[0]
         if lst_f or reskind == 'f': kinds = 'irf'
@@ -523,9 +548,8 @@
                                                 arrayfielddescr,
                                                 arraydescr)
             return []
-        # check for deepfrozen structures that force constant-folding
-        immut = v_inst.concretetype.TO._immutable_field(c_fieldname.value)
-        if immut:
+        # check for _immutable_fields_ hints
+        if v_inst.concretetype.TO._immutable_field(c_fieldname.value):
             if (self.callcontrol is not None and
                 self.callcontrol.could_be_green_field(v_inst.concretetype.TO,
                                                       c_fieldname.value)):

Modified: pypy/branch/rlist-jit/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/rlist-jit/pypy/jit/metainterp/pyjitpl.py	Wed Nov 10 11:46:14 2010
@@ -601,8 +601,10 @@
         virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box)
         arrayindex = vinfo.array_field_by_descrs[arrayfielddescr]
         index = indexbox.getint()
-        if index < 0:
-            index += vinfo.get_array_length(virtualizable, arrayindex)
+        # Support for negative index: disabled
+        # (see codewriter/jtransform.py, _check_no_vable_array).
+        #if index < 0:
+        #    index += vinfo.get_array_length(virtualizable, arrayindex)
         assert 0 <= index < vinfo.get_array_length(virtualizable, arrayindex)
         return vinfo.get_index_in_array(virtualizable, arrayindex, index)
 

Modified: pypy/branch/rlist-jit/pypy/jit/metainterp/test/test_recursive.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/jit/metainterp/test/test_recursive.py	(original)
+++ pypy/branch/rlist-jit/pypy/jit/metainterp/test/test_recursive.py	Wed Nov 10 11:46:14 2010
@@ -927,12 +927,16 @@
                                             x=x)
                 frame.s = hint(frame.s, promote=True)
                 n -= 1
-                x += frame.l[frame.s]
+                s = frame.s
+                assert s >= 0
+                x += frame.l[s]
                 frame.s += 1
                 if codeno == 0:
                     subframe = Frame([n, n+1, n+2, n+3], 0)
                     x += f(1, 10, 1, subframe)
-                x += frame.l[frame.s]
+                s = frame.s
+                assert s >= 0
+                x += frame.l[s]
                 x += len(frame.l)
                 frame.s -= 1
             return x

Modified: pypy/branch/rlist-jit/pypy/jit/metainterp/test/test_virtualizable.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/jit/metainterp/test/test_virtualizable.py	(original)
+++ pypy/branch/rlist-jit/pypy/jit/metainterp/test/test_virtualizable.py	Wed Nov 10 11:46:14 2010
@@ -480,9 +480,13 @@
                 myjitdriver.jit_merge_point(frame=frame, n=n, x=x)
                 frame.s = hint(frame.s, promote=True)
                 n -= 1
-                x += frame.l[frame.s]
+                s = frame.s
+                assert s >= 0
+                x += frame.l[s]
                 frame.s += 1
-                x += frame.l[frame.s]
+                s = frame.s
+                assert s >= 0
+                x += frame.l[s]
                 x += len(frame.l)
                 frame.s -= 1
             return x
@@ -994,7 +998,9 @@
                 jitdriver.can_enter_jit(frame=frame, n=n)
                 jitdriver.jit_merge_point(frame=frame, n=n)
                 popped = frame.stack[frame.stackpos]
-                frame.stackpos -= 1
+                sp = frame.stackpos - 1
+                assert sp >= 0
+                frame.stackpos = sp
                 to_push = intmask(popped * 3)
                 frame.stack[frame.stackpos] = to_push
                 frame.stackpos += 1

Modified: pypy/branch/rlist-jit/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/jit/metainterp/warmspot.py	(original)
+++ pypy/branch/rlist-jit/pypy/jit/metainterp/warmspot.py	Wed Nov 10 11:46:14 2010
@@ -163,6 +163,8 @@
         self.check_access_directly_sanity(graphs)
         if backendopt:
             self.prejit_optimizations(policy, graphs)
+        elif self.opt.listops:
+            self.prejit_optimizations_minimal_inline(policy, graphs)
 
         self.build_meta_interp(ProfilerClass)
         self.make_args_specifications()
@@ -260,6 +262,10 @@
                               remove_asserts=True,
                               really_remove_asserts=True)
 
+    def prejit_optimizations_minimal_inline(self, policy, graphs):
+        from pypy.translator.backendopt.inline import auto_inline_graphs
+        auto_inline_graphs(self.translator, graphs, 0.01)
+
     def build_cpu(self, CPUClass, translate_support_code=False,
                   no_stats=False, **kwds):
         assert CPUClass is not None

Modified: pypy/branch/rlist-jit/pypy/jit/tl/tl.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/jit/tl/tl.py	(original)
+++ pypy/branch/rlist-jit/pypy/jit/tl/tl.py	Wed Nov 10 11:46:14 2010
@@ -16,32 +16,40 @@
     def __init__(self, size):
         self = hint(self, access_directly=True, fresh_virtualizable=True)
         self.stack = [0] * size
-        self.stackpos = 0
+        self.stackpos = 0        # always store a known-nonneg integer here
 
     def append(self, elem):
         self.stack[self.stackpos] = elem
         self.stackpos += 1
 
     def pop(self):
-        self.stackpos -= 1
-        if self.stackpos < 0:
+        stackpos = self.stackpos - 1
+        if stackpos < 0:
             raise IndexError
-        return self.stack[self.stackpos]
+        self.stackpos = stackpos     # always store a known-nonneg integer here
+        return self.stack[stackpos]
 
     def pick(self, i):
-        self.append(self.stack[self.stackpos - i - 1])
+        n = self.stackpos - i - 1
+        assert n >= 0
+        self.append(self.stack[n])
 
     def put(self, i):
         elem = self.pop()
-        self.stack[self.stackpos - i - 1] = elem
+        n = self.stackpos - i - 1
+        assert n >= 0
+        self.stack[n] = elem
 
     def roll(self, r):
         if r < -1:
             i = self.stackpos + r
             if i < 0:
                 raise IndexError
-            elem = self.stack[self.stackpos - 1]
+            n = self.stackpos - 1
+            assert n >= 0
+            elem = self.stack[n]
             for j in range(self.stackpos - 2, i - 1, -1):
+                assert j >= 0
                 self.stack[j + 1] = self.stack[j]
             self.stack[i] = elem
         elif r > 1:
@@ -51,7 +59,9 @@
             elem = self.stack[i]
             for j in range(i, self.stackpos - 1):
                 self.stack[j] = self.stack[j + 1]
-            self.stack[self.stackpos - 1] = elem
+            n = self.stackpos - 1
+            assert n >= 0
+            self.stack[n] = elem
 
 
 def make_interp(supports_call):

Modified: pypy/branch/rlist-jit/pypy/rpython/rlist.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/rpython/rlist.py	(original)
+++ pypy/branch/rlist-jit/pypy/rpython/rlist.py	Wed Nov 10 11:46:14 2010
@@ -688,6 +688,7 @@
         if index >= l.ll_length():
             raise IndexError
     return l.ll_getitem_fast(index)
+ll_getitem_nonneg._always_inline_ = True
 # no oopspec -- the function is inlined by the JIT
 
 def ll_getitem(func, l, index):
@@ -719,6 +720,7 @@
     if index < 0:
         index += l.ll_length()
     return ll_getitem_foldable_nonneg(l, index)
+ll_getitem_foldable._always_inline_ = True
 # no oopspec -- the function is inlined by the JIT
 
 def ll_setitem_nonneg(func, l, index, newitem):
@@ -727,6 +729,7 @@
         if index >= l.ll_length():
             raise IndexError
     l.ll_setitem_fast(index, newitem)
+ll_setitem_nonneg._always_inline_ = True
 # no oopspec -- the function is inlined by the JIT
 
 def ll_setitem(func, l, index, newitem):



More information about the Pypy-commit mailing list