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

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


Author: arigo
Date: Tue Jan 26 14:19:14 2010
New Revision: 70878

Modified:
   pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/codewriter.py
   pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_codewriter.py
   pypy/branch/unroll-safe-if-const-arg/pypy/rlib/jit.py
Log:
Write the decorator, unroll_safe_if_const_arg(argpos).
Support it in codewriter.py.


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:19:14 2010
@@ -162,15 +162,22 @@
             if getattr(funcobj, 'graph', None) is None:
                 return 'residual'
             targetgraph = funcobj.graph
-            if (hasattr(targetgraph, 'func') and
-                hasattr(targetgraph.func, 'oopspec')):
-                return 'builtin'
+            if hasattr(targetgraph, 'func'):
+                if hasattr(targetgraph.func, 'oopspec'):
+                    return 'builtin'
+                if hasattr(targetgraph.func, '_jit_unroll_safe_if_const_arg_'):
+                    return 'unrollsafeif'
         elif op.opname == 'oosend':
             SELFTYPE, methname, opargs = support.decompose_oosend(op)
             if SELFTYPE.oopspec_name is not None:
                 return 'builtin'
-        if self.graphs_from(op, is_candidate) is None:
+        graphs = self.graphs_from(op, is_candidate)
+        if graphs is None:
             return 'residual'
+        for graph in graphs:
+            if hasattr(graph, 'func'):
+                assert not hasattr(graph.func, 'oopspec')
+                assert not hasattr(graph.func, '_unroll_safe_if_const_arg_')
         return 'regular'
 
     def is_candidate(self, graph):
@@ -1211,7 +1218,7 @@
         kind = self.codewriter.guess_call_kind(op)
         return getattr(self, 'handle_%s_oosend' % kind)(op)
 
-    def handle_regular_call(self, op, oosend_methdescr=None):
+    def handle_regular_call(self, op, oosend_methdescr=None, if_const_arg=None):
         self.minimize_variables()
         [targetgraph] = self.codewriter.graphs_from(op)
         jitbox = self.codewriter.get_jitcode(targetgraph, self.graph,
@@ -1220,12 +1227,29 @@
             args = op.args
         else:
             args = op.args[1:]
-        self.emit('call')
+        if if_const_arg is None:
+            self.emit('call')
+        else:
+            self.emit('call_if_const_arg')
+            self.emit(if_const_arg)
         self.emit(self.get_position(jitbox))
         self.emit_varargs([x for x in args
                            if x.concretetype is not lltype.Void])
         self.register_var(op.result)
 
+    def handle_unrollsafeif_call(self, op):
+        [targetgraph] = self.codewriter.graphs_from(op)
+        argpos = targetgraph.func._jit_unroll_safe_if_const_arg_
+        assert isinstance(argpos, int)
+        # fix argpos to not count the None arguments
+        argpos2 = 0
+        args = op.args[1:]
+        for v in args[:argpos]:
+            if v.concretetype is not lltype.Void:
+                argpos2 += 1
+        assert args[argpos].concretetype is not lltype.Void
+        self.handle_regular_call(op, if_const_arg=argpos2)
+
     def handle_residual_call(self, op, skip_last=False):
         self.minimize_variables()
         if skip_last:

Modified: pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_codewriter.py
==============================================================================
--- pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_codewriter.py	(original)
+++ pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_codewriter.py	Tue Jan 26 14:19:14 2010
@@ -512,6 +512,25 @@
         assert ConstInt(55) in jitcode.constants
         assert ConstInt(66) not in jitcode.constants
 
+    def test_unroll_safe_if_const_arg(self):
+        @jit.unroll_safe_if_const_arg(2)
+        def g(x, z, y):
+            while y > 0:
+                x += 2
+                y -= 1
+            return x
+        def f(x, z, y):
+            return g(x, z, y)
+        graphs = self.make_graphs(f, [3, None, 5])
+        cw = CodeWriter(self.rtyper)
+        cw.candidate_graphs = graphs
+        cw._start(self.metainterp_sd, None)
+        jitcode = cw.make_one_bytecode((graphs[0], None), False)
+        assert 'call' not in jitcode._source
+        assert 'call_if_const_arg' in jitcode._source
+        index = jitcode._source.index('call_if_const_arg')
+        assert jitcode._source[index+1] == 1     # argpos without Nones
+
 
 class ImmutableFieldsTests:
 

Modified: pypy/branch/unroll-safe-if-const-arg/pypy/rlib/jit.py
==============================================================================
--- pypy/branch/unroll-safe-if-const-arg/pypy/rlib/jit.py	(original)
+++ pypy/branch/unroll-safe-if-const-arg/pypy/rlib/jit.py	Tue Jan 26 14:19:14 2010
@@ -20,6 +20,13 @@
     func._jit_unroll_safe_ = True
     return func
 
+def unroll_safe_if_const_arg(argpos):
+    assert isinstance(argpos, int)
+    def _decorate(func):
+        func._jit_unroll_safe_if_const_arg_ = argpos
+        return func
+    return _decorate
+
 def loop_invariant(func):
     dont_look_inside(func)
     func._jit_loop_invariant_ = True



More information about the Pypy-commit mailing list