Author: Armin Rigo <[email protected]>
Branch: conditional_call_value_4
Changeset: r88572:1e9f2a40fd2e
Date: 2016-11-23 11:00 +0100
http://bitbucket.org/pypy/pypy/changeset/1e9f2a40fd2e/

Log:    From conditional_call_value_2: found out again why we'd like the
        function to be only "almost" elidable

diff --git a/rpython/jit/metainterp/test/test_ajit.py 
b/rpython/jit/metainterp/test/test_ajit.py
--- a/rpython/jit/metainterp/test/test_ajit.py
+++ b/rpython/jit/metainterp/test/test_ajit.py
@@ -4577,12 +4577,11 @@
         self.check_resops(guard_true=10)   # 5 unrolled, plus 5 unrelated
 
     def test_conditional_call_value(self):
-        from rpython.rlib.jit import conditional_call_value
-        @elidable
+        from rpython.rlib.jit import conditional_call_elidable
         def g(j):
             return j + 5
         def f(i, j):
-            return conditional_call_value(i, g, j)
+            return conditional_call_elidable(i, g, j)
         res = self.interp_operations(f, [-42, 200])
         assert res == -42
         res = self.interp_operations(f, [0, 200])
diff --git a/rpython/jit/metainterp/test/test_call.py 
b/rpython/jit/metainterp/test/test_call.py
--- a/rpython/jit/metainterp/test/test_call.py
+++ b/rpython/jit/metainterp/test/test_call.py
@@ -1,5 +1,5 @@
 
-from rpython.jit.metainterp.test.support import LLJitMixin
+from rpython.jit.metainterp.test.support import LLJitMixin, noConst
 from rpython.rlib import jit
 
 class CallTest(object):
@@ -54,18 +54,16 @@
         self.check_resops(guard_no_exception=0)
 
     def test_cond_call_i(self):
-        @jit.elidable
         def f(n):
             return n * 200
 
         def main(n, m):
-            return jit.conditional_call_value(n, f, m)
+            return jit.conditional_call_elidable(n, f, m)
 
         assert self.interp_operations(main, [0, 10]) == 2000
         assert self.interp_operations(main, [15, 42]) == 15
 
     def test_cond_call_r(self):
-        @jit.elidable
         def f(n):
             return [n]
 
@@ -74,7 +72,7 @@
                 l = []
             else:
                 l = None
-            l = jit.conditional_call_value(l, f, n)
+            l = jit.conditional_call_elidable(l, f, n)
             return len(l)
 
         assert main(10) == 0
@@ -83,24 +81,22 @@
         assert self.interp_operations(main, [5]) == 1
 
     def test_cond_call_constant_in_pyjitpl(self):
-        @jit.elidable
         def f(a, b):
             return a + b
         def main(n):
             # this is completely constant-folded because the arguments
             # to f() are constants.
-            return jit.conditional_call_value(n, f, 40, 2)
+            return jit.conditional_call_elidable(n, f, 40, 2)
 
         assert main(12) == 12
         assert main(0) == 42
         assert self.interp_operations(main, [12]) == 12
-        self.check_operations_history(finish=1)   # empty history
+        self.check_operations_history({'finish': 1})   # empty history
         assert self.interp_operations(main, [0]) == 42
-        self.check_operations_history(finish=1)   # empty history
+        self.check_operations_history({'finish': 1})   # empty history
 
     def test_cond_call_constant_in_optimizer(self):
         myjitdriver = jit.JitDriver(greens = ['m'], reds = ['n', 'p'])
-        @jit.elidable
         def externfn(x):
             return x - 3
         class V:
@@ -110,18 +106,17 @@
             while n > 0:
                 myjitdriver.can_enter_jit(n=n, p=p, m=m)
                 myjitdriver.jit_merge_point(n=n, p=p, m=m)
-                v = V(m)
-                n -= jit.conditional_call_value(p, externfn, v.value)
+                m1 = noConst(m)
+                n -= jit.conditional_call_elidable(p, externfn, m1)
             return n
         res = self.meta_interp(f, [21, 5, 0])
         assert res == -1
         # the COND_CALL_VALUE is constant-folded away by optimizeopt.py
-        self.check_resops(call_pure_i=0, cond_call_pure_i=0, call_i=0,
-                          int_sub=2)
+        self.check_resops({'int_sub': 2, 'int_gt': 2, 'guard_true': 2,
+                           'jump': 1})
 
     def test_cond_call_constant_in_optimizer_2(self):
         myjitdriver = jit.JitDriver(greens = ['m'], reds = ['n', 'p'])
-        @jit.elidable
         def externfn(x):
             return 2
         def f(n, m, p):
@@ -130,7 +125,7 @@
                 myjitdriver.jit_merge_point(n=n, p=p, m=m)
                 assert p > -1
                 assert p < 1
-                n -= jit.conditional_call_value(p, externfn, n)
+                n -= jit.conditional_call_elidable(p, externfn, n)
             return n
         res = self.meta_interp(f, [21, 5, 0])
         assert res == -1
@@ -141,7 +136,6 @@
 
     def test_cond_call_constant_in_optimizer_3(self):
         myjitdriver = jit.JitDriver(greens = ['m'], reds = ['n', 'p'])
-        @jit.elidable
         def externfn(x):
             return 1
         def f(n, m, p):
@@ -151,8 +145,8 @@
                 assert p > -1
                 assert p < 1
                 n0 = n
-                n -= jit.conditional_call_value(p, externfn, n0)
-                n -= jit.conditional_call_value(p, externfn, n0)
+                n -= jit.conditional_call_elidable(p, externfn, n0)
+                n -= jit.conditional_call_elidable(p, externfn, n0)
             return n
         res = self.meta_interp(f, [21, 5, 15])
         assert res == -1
@@ -167,12 +161,11 @@
             def __init__(self, value):
                 self.value = value
                 self.triple = 0
-            @jit.elidable
             def _compute_triple(self):
                 self.triple = self.value * 3
                 return self.triple
             def get_triple(self):
-                return jit.conditional_call_value(self.triple,
+                return jit.conditional_call_elidable(self.triple,
                                                   X._compute_triple, self)
         def main(n):
             x = X(n)
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -1218,7 +1218,7 @@
     return value    # special-cased below
 
 @specialize.call_location()
-def conditional_call_value(value, function, *args):
+def conditional_call_elidable(value, function, *args):
     """Does the same as:
 
         if value == <0 or None>:
@@ -1226,10 +1226,21 @@
         return value
 
     For the JIT.  Allows one branch which doesn't create a bridge,
-    typically used for caching.  The function must be @elidable.
-    The value and the function's return type must match and cannot
-    be a float: they must be either regular 'int', or something
-    that turns into a pointer.
+    typically used for caching.  The value and the function's return
+    type must match and cannot be a float: they must be either regular
+    'int', or something that turns into a pointer.
+
+    Even if the function is not marked @elidable, it is still treated
+    mostly like one.  The only difference is that (in heapcache.py)
+    we don't assume this function won't change anything observable.
+    This is useful for caches, as you can write:
+
+        def _compute_and_cache(...):
+            self.cache = ...compute...
+            return self.cache
+
+        x = jit.conditional_call_elidable(self.cache, _compute_and_cache, ...)
+
     """
     if we_are_jitted():
         return _jit_conditional_call_value(value, function, *args)
@@ -1243,7 +1254,7 @@
                 value = function(*args)
                 assert not isinstance(value, int)
         return value
-conditional_call_value._always_inline_ = True
+conditional_call_elidable._always_inline_ = True
 
 class ConditionalCallEntry(ExtRegistryEntry):
     _about_ = _jit_conditional_call, _jit_conditional_call_value
@@ -1253,10 +1264,6 @@
                                                  args_s[1], args_s[2:])
         if self.instance == _jit_conditional_call_value:
             from rpython.annotator import model as annmodel
-            func = args_s[1].const
-            assert getattr(func, '_elidable_function_', None), (
-                "%r used in jit.conditional_call_value() should be "
-                "@jit.elidable" % (func,))
             return annmodel.unionof(s_res, args_s[0])
 
     def specialize_call(self, hop):
diff --git a/rpython/rlib/test/test_jit.py b/rpython/rlib/test/test_jit.py
--- a/rpython/rlib/test/test_jit.py
+++ b/rpython/rlib/test/test_jit.py
@@ -3,8 +3,8 @@
 from rpython.conftest import option
 from rpython.annotator.model import UnionError
 from rpython.rlib.jit import (hint, we_are_jitted, JitDriver, elidable_promote,
-    JitHintError, oopspec, isconstant, conditional_call, 
conditional_call_value,
-    elidable, unroll_safe, dont_look_inside,
+    JitHintError, oopspec, isconstant, conditional_call,
+    elidable, unroll_safe, dont_look_inside, conditional_call_elidable,
     enter_portal_frame, leave_portal_frame)
 from rpython.rlib.rarithmetic import r_uint
 from rpython.rtyper.test.tool import BaseRtypingTest
@@ -302,12 +302,11 @@
         mix.getgraph(later, [annmodel.s_Bool], annmodel.s_None)
         mix.finish()
 
-    def test_conditional_call_value(self):
-        @elidable
+    def test_conditional_call_elidable(self):
         def g(x, y):
             return x - y + 5
         def f(n, x, y):
-            return conditional_call_value(n, g, x, y)
+            return conditional_call_elidable(n, g, x, y)
         assert f(0, 1000, 100) == 905
         res = self.interpret(f, [0, 1000, 100])
         assert res == 905
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to