Author: Maciej Fijalkowski <[email protected]>
Branch: unroll-if-const
Changeset: r45953:b3e72b286556
Date: 2011-07-25 01:08 +0200
http://bitbucket.org/pypy/pypy/changeset/b3e72b286556/

Log:    work in progress

diff --git a/pypy/jit/codewriter/call.py b/pypy/jit/codewriter/call.py
--- a/pypy/jit/codewriter/call.py
+++ b/pypy/jit/codewriter/call.py
@@ -137,6 +137,9 @@
             if (hasattr(targetgraph, 'func') and
                 hasattr(targetgraph.func, 'oopspec')):
                 return 'builtin'
+            if (hasattr(targetgraph, 'func') and
+                hasattr(targetgraph.func, '_jit_unroll_if_const_')):
+                return 'regularifconst'
         elif op.opname == 'oosend':
             SELFTYPE, methname, opargs = support.decompose_oosend(op)
             if SELFTYPE.oopspec_name is not None:
diff --git a/pypy/jit/codewriter/jtransform.py 
b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -337,6 +337,15 @@
         op1 = SpaceOperation('-live-', [], None)
         return [op0, op1]
 
+    def handle_regularifconst_call(self, op):
+        """ A direct call that turns into inline_ifconst_call_xxx. The first
+        argument is jitcode, then number of const arg then calldescr and
+        finally all other args
+        """
+        import pdb
+        pdb.set_trace()
+        [targetgraph] = self.callcontrol.graphs_from(op)
+
     def handle_builtin_call(self, op):
         oopspec_name, args = support.decode_builtin_call(op)
         # dispatch to various implementations depending on the oopspec_name
diff --git a/pypy/jit/codewriter/policy.py b/pypy/jit/codewriter/policy.py
--- a/pypy/jit/codewriter/policy.py
+++ b/pypy/jit/codewriter/policy.py
@@ -58,6 +58,8 @@
                             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_if_const_', False)
 
         unsupported = contains_unsupported_variable_type(graph,
                                                          self.supports_floats,
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
@@ -3,7 +3,7 @@
 from pypy.rlib.jit import JitDriver, we_are_jitted, hint, dont_look_inside
 from pypy.rlib.jit import loop_invariant, elidable, promote
 from pypy.rlib.jit import jit_debug, assert_green, AssertGreenFailed
-from pypy.rlib.jit import unroll_safe, current_trace_length
+from pypy.rlib.jit import unroll_safe, current_trace_length, unroll_if_const
 from pypy.jit.metainterp import pyjitpl, history
 from pypy.jit.metainterp.warmstate import set_future_value
 from pypy.jit.metainterp.warmspot import get_stats
@@ -2400,6 +2400,34 @@
         # 1 preamble and 6 speciealized versions of each loop
         self.check_tree_loop_count(2*(1 + 6))
 
+    def test_unroll_if_const(self):
+        @unroll_if_const(0)
+        def f(arg):
+            s = 0
+            while arg > 0:
+                s += arg
+                arg -= 1
+            return s
+
+        driver = JitDriver(greens = ['code'], reds = ['n', 'arg', 's'])
+
+        def main(code, n, arg):
+            s = 0
+            while n > 0:
+                driver.jit_merge_point(code=code, n=n, arg=arg, s=s)
+                if code == 0:
+                    s += f(arg)
+                else:
+                    s += f(1)
+                n -= 1
+            return s
+
+        res = self.meta_interp(main, [0, 10, 2], enable_opts='')
+        assert res == main(0, 10, 2)
+        self.check_loops(call=1)
+        res = self.meta_interp(main, [1, 10, 2], enable_opts='')
+        assert res == main(0, 10, 2)
+        self.check_loops(call=0)
 
 class TestOOtype(BasicTests, OOJitMixin):
 
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -41,6 +41,14 @@
     """
     return x
 
+def unroll_if_const(argno):
+    """ Mark function as loop unrollable if arg number argno is a constant
+    """
+    def decorator(f):
+        f._jit_unroll_if_const_ = (argno,)
+        return f
+    return decorator
+
 @specialize.argtype(0)
 def promote(x):
     return hint(x, promote=True)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to