Author: Carl Friedrich Bolz <[email protected]>
Branch: guard-compatible
Changeset: r83418:a208c212e736
Date: 2016-03-29 13:11 +0200
http://bitbucket.org/pypy/pypy/changeset/a208c212e736/

Log:    promote the result of elidable_compatible if the other arguments are
        constant

diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -156,16 +156,28 @@
     """
     def decorate(func):
         elidable(func)
+        def _all_args_const(*args):
+            if len(args) == 0:
+                return True
+            if len(args) == 1:
+                return isconstant(args[0])
+            return isconstant(args[0]) and _all_args_const(*args[1:])
         def wrapped_func(x, *args):
             assert x is not None
             x = hint(x, promote_compatible=True)
             if quasi_immut_field_name_for_second_arg is not None:
-                return func(x, getattr(x, 
quasi_immut_field_name_for_second_arg), *args)
-            return func(x, *args)
+                result = func(x, getattr(x, 
quasi_immut_field_name_for_second_arg), *args)
+            else:
+                result = func(x, *args)
+            if _all_args_const(*args):
+                promote(result) # make the tracer treat it as a constant
+            return result
+        wrapped_func.func_name = "elidable_compatible_%s" % (func.func_name, )
         return wrapped_func
     return decorate
 
 
+
 def dont_look_inside(func):
     """ Make sure the JIT does not trace inside decorated function
     (it becomes a call instead)
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
@@ -143,7 +143,7 @@
         res = self.interpret(f, [2])
         assert res == 5
 
-    def test_elidable_promote(self):
+    def test_elidable_compatible(self):
         class A(object):
             pass
         a1 = A()
@@ -153,16 +153,21 @@
         @elidable_compatible()
         def g(a):
             return a.x
+        @elidable_compatible()
+        def h(a, b, c):
+            return a.x + b + c
         def f(x):
             if x == 1:
                 a = a1
             else:
                 a = a2
-            return g(a)
+            return g(a) + h(a, 2, 0)
+        assert f(1) == 4
+        assert f(4) == 6
         res = self.interpret(f, [1])
-        assert res == 1
+        assert res == 4
         res = self.interpret(f, [4])
-        assert res == 2
+        assert res == 6
 
     def test_elidable_promote_args(self):
         @elidable_promote(promote_args='0')
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to