Author: Armin Rigo <[email protected]>
Branch: conditional_call_value_4
Changeset: r88569:5482941a8917
Date: 2016-11-23 10:22 +0100
http://bitbucket.org/pypy/pypy/changeset/5482941a8917/
Log: Start to adapt tests from conditional_call_value_2
diff --git a/rpython/jit/backend/x86/test/test_call.py
b/rpython/jit/backend/x86/test/test_call.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/x86/test/test_call.py
@@ -0,0 +1,7 @@
+from rpython.jit.backend.x86.test.test_basic import Jit386Mixin
+from rpython.jit.metainterp.test import test_call
+
+class TestCall(Jit386Mixin, test_call.CallTest):
+ # for the individual tests see
+ # ====> ../../../metainterp/test/test_call.py
+ pass
diff --git a/rpython/jit/metainterp/heapcache.py
b/rpython/jit/metainterp/heapcache.py
--- a/rpython/jit/metainterp/heapcache.py
+++ b/rpython/jit/metainterp/heapcache.py
@@ -271,6 +271,7 @@
return
if (OpHelpers.is_plain_call(opnum) or
OpHelpers.is_call_loopinvariant(opnum) or
+ OpHelpers.is_cond_call_value(opnum) or
opnum == rop.COND_CALL):
effectinfo = descr.get_extra_info()
ef = effectinfo.extraeffect
diff --git a/rpython/jit/metainterp/pyjitpl.py
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -1066,6 +1066,8 @@
@arguments("box", "box", "boxes2", "descr", "orgpc")
def _opimpl_conditional_call_value(self, valuebox, funcbox, argboxes,
calldescr, pc):
+ if isinstance(valuebox, Const) and valuebox.nonnull():
+ return valuebox
return self.do_conditional_call(valuebox, funcbox, argboxes,
calldescr, pc, is_value=True)
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
@@ -2,7 +2,7 @@
from rpython.jit.metainterp.test.support import LLJitMixin
from rpython.rlib import jit
-class TestCall(LLJitMixin):
+class CallTest(object):
def test_indirect_call(self):
@jit.dont_look_inside
def f1(x):
@@ -52,3 +52,128 @@
assert self.meta_interp(main, [10]) == 42
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)
+
+ 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]
+
+ def main(n):
+ if n == 10:
+ l = []
+ else:
+ l = None
+ l = jit.conditional_call_value(l, f, n)
+ return len(l)
+
+ assert self.interp_operations(main, [10]) == 0
+ assert self.interp_operations(main, [5]) == 1
+
+ def test_cond_call_constant_in_pyjitpl(self):
+ 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_elidable(n, 23, f, 40, 2)
+
+ assert main(12) == 12 # because 12 != 23
+ assert self.interp_operations(main, [12]) == 12 # because 12 != 23
+ self.check_operations_history(finish=1) # empty history
+ assert self.interp_operations(main, [23]) == 42 # because 23 == 23
+ self.check_operations_history(finish=1) # empty history
+
+ def test_cond_call_constant_in_optimizer(self):
+ myjitdriver = jit.JitDriver(greens = ['m'], reds = ['n', 'p'])
+ def externfn(x):
+ return x - 3
+ class V:
+ def __init__(self, value):
+ self.value = value
+ def f(n, m, p):
+ 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_elidable(p, -42, externfn, v.value)
+ return n
+ res = self.meta_interp(f, [21, 5, -42])
+ assert res == -1
+ # the COND_CALL_PURE 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)
+
+ def test_cond_call_constant_in_optimizer_2(self):
+ myjitdriver = jit.JitDriver(greens = ['m'], reds = ['n', 'p'])
+ def externfn(x):
+ return 2
+ def f(n, m, p):
+ while n > 0:
+ myjitdriver.can_enter_jit(n=n, p=p, m=m)
+ myjitdriver.jit_merge_point(n=n, p=p, m=m)
+ assert p > 14
+ assert p < 16
+ n -= jit.conditional_call_elidable(p, 15, externfn, n)
+ return n
+ res = self.meta_interp(f, [21, 5, 15])
+ assert res == -1
+ # optimizer: the COND_CALL_PURE is turned into a regular
+ # CALL_PURE, which itself becomes CALL
+ self.check_resops(call_pure_i=0, cond_call_pure_i=0, call_i=2,
+ int_sub=2)
+
+ def test_cond_call_constant_in_optimizer_3(self):
+ myjitdriver = jit.JitDriver(greens = ['m'], reds = ['n', 'p'])
+ def externfn(x):
+ return 1
+ def f(n, m, p):
+ while n > 0:
+ myjitdriver.can_enter_jit(n=n, p=p, m=m)
+ myjitdriver.jit_merge_point(n=n, p=p, m=m)
+ assert p > 14
+ assert p < 16
+ n0 = n
+ n -= jit.conditional_call_elidable(p, 15, externfn, n0)
+ n -= jit.conditional_call_elidable(p, 15, externfn, n0)
+ return n
+ res = self.meta_interp(f, [21, 5, 15])
+ assert res == -1
+ # same as test_cond_call_constant_in_optimizer_2, but the two
+ # intermediate CALL_PUREs are replaced with only one, because
+ # they are called with the same arguments
+ self.check_resops(call_pure_i=0, cond_call_pure_i=0, call_i=2,
+ int_sub=4)
+
+ def test_cond_call_constant_in_optimizer_4(self):
+ class X:
+ def __init__(self, value):
+ self.value = value
+ self.triple = -1
+ def _compute_triple(self):
+ self.triple = self.value * 3
+ return self.triple
+ def get_triple(self):
+ return jit.conditional_call_elidable(self.triple, -1,
+ X._compute_triple, self)
+ def main(n, initvalue):
+ x = X(n)
+ x.triple = initvalue
+ return x.get_triple() + x.get_triple()
+
+ assert self.interp_operations(main, [100, -1]) == 600
+ self.check_operations_history(finish=1) # empty history
+
+
+class TestCall(LLJitMixin, CallTest):
+ pass
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -1247,8 +1247,9 @@
if self.instance == _jit_conditional_call_value:
from rpython.annotator import model as annmodel
func = args_s[1].const
- # conditional_call_value(): function must be elidable
- assert func._elidable_function_
+ 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):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit