[pypy-svn] r70879 - in pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp: . test

arigo at codespeak.net arigo at codespeak.net
Tue Jan 26 14:57:57 CET 2010


Author: arigo
Date: Tue Jan 26 14:57:56 2010
New Revision: 70879

Modified:
   pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/codewriter.py
   pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/policy.py
   pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_send.py
Log:
(fijal, cfbolz looking, arigo)
Implement call_if_not_const in pyjitpl.  Should be all.


Modified: pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/codewriter.py	(original)
+++ pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/codewriter.py	Tue Jan 26 14:57:56 2010
@@ -102,7 +102,7 @@
                     continue
                 kind = self.guess_call_kind(op, is_candidate)
                 # use callers() to view the calling chain in pdb
-                if kind != "regular":
+                if kind != "regular" and kind != "unrollsafeif":
                     continue
                 for graph in self.graphs_from(op, is_candidate):
                     if graph in seen:
@@ -1230,6 +1230,7 @@
         if if_const_arg is None:
             self.emit('call')
         else:
+            assert jitbox.calldescr is not None
             self.emit('call_if_const_arg')
             self.emit(if_const_arg)
         self.emit(self.get_position(jitbox))

Modified: pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/policy.py
==============================================================================
--- pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/policy.py	(original)
+++ pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/policy.py	Tue Jan 26 14:57:56 2010
@@ -56,8 +56,9 @@
         else:
             see_function = (self.look_inside_function(func) and not
                             self._reject_function(func))
-            contains_loop = contains_loop and not getattr(
-                    func, '_jit_unroll_safe_', False)
+            contains_loop = (contains_loop
+                and not getattr(func, '_jit_unroll_safe_', False)
+                and not hasattr(func, '_jit_unroll_safe_if_const_arg_'))
 
         res = see_function and not contains_unsupported_variable_type(graph,
                                                          self.supports_floats)

Modified: pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/pyjitpl.py	Tue Jan 26 14:57:56 2010
@@ -647,6 +647,15 @@
     def opimpl_residual_call_loopinvariant(self, calldescr, varargs):
         return self.execute_varargs(rop.CALL_LOOPINVARIANT, varargs, calldescr, exc=True)
 
+    @arguments("int", "bytecode", "varargs")
+    def opimpl_call_if_const_arg(self, if_const_arg, callee, varargs):
+        if isinstance(varargs[if_const_arg], Const):
+            return self.perform_call(callee, varargs)
+        else:
+            assert callee.cfnptr is not None
+            return self.do_residual_call([callee.cfnptr] + varargs,
+                                         descr=callee.calldescr, exc=True)
+
     @arguments("varargs")
     def opimpl_recursion_leave_prep(self, varargs):
         warmrunnerstate = self.metainterp.staticdata.state

Modified: pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_send.py
==============================================================================
--- pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_send.py	(original)
+++ pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_send.py	Tue Jan 26 14:57:56 2010
@@ -1,5 +1,6 @@
 import py
 from pypy.rlib.jit import JitDriver, hint, purefunction
+from pypy.rlib import jit
 from pypy.jit.metainterp.policy import StopAtXPolicy
 from pypy.rpython.ootypesystem import ootype
 from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
@@ -607,6 +608,29 @@
         res = self.meta_interp(fn, [20], policy=StopAtXPolicy(extern))
         assert res == 21
 
+    def test_unroll_safe_if_const_arg(self):
+        myjitdriver = JitDriver(greens=['g'], reds = ['i', 'x'])
+        @jit.unroll_safe_if_const_arg(1)
+        def do_stuff(x, y):
+            while y > 0:
+                x += 2
+                y -= 1
+            return x
+        def fn(g, i):
+            x = 0
+            while i > 0:
+                myjitdriver.can_enter_jit(g=g, i=i, x=x)
+                myjitdriver.jit_merge_point(g=g, i=i, x=x)
+                x = do_stuff(x, g)    # unroll_safe
+                x = do_stuff(x, i)    # not unroll_safe
+                i -= 1
+            return x
+        res = self.meta_interp(fn, [10, 20])
+        assert res == fn(10, 20)
+        # xxx we could get a call instead of a call_may_force,
+        # given enough efforts, but it seems not very useful in
+        # practice
+        self.check_loops(int_add=10, call_may_force=1)
 
 class TestOOtype(SendTests, OOJitMixin):
     pass



More information about the Pypy-commit mailing list