Author: Armin Rigo <ar...@tunes.org> Branch: conditional_call_value_2 Changeset: r87000:72155a41e42e Date: 2016-09-11 16:27 +0200 http://bitbucket.org/pypy/pypy/changeset/72155a41e42e/
Log: Test. Improve comment 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 @@ -95,6 +95,27 @@ 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']) + @jit.elidable + 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) + 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 @@ -1209,12 +1209,18 @@ return ONE OF function(*args) OR (value if value != special_constant) whichever is better for the JIT. Usually it first checks if 'value' - is equal to 'special_constant', and only if it is, it calls - 'function(*args)'. The 'function' must be marked as @elidable. An - example of an "unusual" case is if, say, all arguments are constant. - In this case the JIT knows the result of the call in advance, and - so it always uses the 'function(*args)' path without comparing - 'value' and 'special_constant' at all. + is equal to 'special_constant', and conditionally calls + 'function(*args)' if it is. The 'function' must be marked as + @elidable. + + If 'value != special_constant', then the JIT assumes that both + solutions would work and _are equal_. This means that if, say, all + arguments to the call are constants, then the JIT removes everything + and replaces it with a constant (by constant-folding + 'function(*args)'). That constant is whatever value was seen as + result during tracing (which is the original 'value' if different + from 'special_constant'--that's supposed to be equal to + 'function(*args)'). """ if we_are_jitted(): return _jit_conditional_call_elidable(value, special_constant, _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit