Author: Carl Friedrich Bolz <cfb...@gmx.de> Branch: guard-compatible Changeset: r83000:1fb0c5a8a04e Date: 2016-03-12 22:38 +0100 http://bitbucket.org/pypy/pypy/changeset/1fb0c5a8a04e/
Log: a new decorator elidable_compatible, with a docstring how I want things to work diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -93,6 +93,8 @@ * force_virtualizable - a performance hint to force the virtualizable early (useful e.g. for python generators that are going to be read later anyway) + * promote_compatible - an internal hint used in the implementation of + elidable_compatible """ return x @@ -126,6 +128,42 @@ def promote_string(x): return hint(x, promote_string=True) +def elidable_compatible(): + """ func must be a function of at least one argument. That first argument + must be pointer-like (XXX for now?) The behaviour of @elidable_compatible + is as follows: + + it turns a call to func like this: + res = func(a1, *args) + + into something that behaves similar to this: + promote(a1) + res = func(a1, *args) + + However, the promote of a1 is not implemented with a guard_value. Instead, + it uses guard_compatible, which is less strict and causes less failures. + More precisely, executing the guard_compatible(x) will only fail if + func(x, *args) != func(a1, *args) + + In this, a1 must not be None. + + This works particularly well if func maps many different values a1 to a + single value res. If func is an injection, there is no reason to not simply + use a regular promote. + + XXX what happens if the *args are not constant? + XXX we need a better name + """ + def decorate(func): + elidable(func) + def wrapped_func(x, *args): + assert x is not None + x = hint(x, promote_compatible=True) + return func(x, *args) + 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 @@ -5,7 +5,7 @@ from rpython.rlib.jit import (hint, we_are_jitted, JitDriver, elidable_promote, JitHintError, oopspec, isconstant, conditional_call, elidable, unroll_safe, dont_look_inside, - enter_portal_frame, leave_portal_frame) + enter_portal_frame, leave_portal_frame, elidable_compatible) from rpython.rlib.rarithmetic import r_uint from rpython.rtyper.test.tool import BaseRtypingTest from rpython.rtyper.lltypesystem import lltype @@ -143,6 +143,27 @@ res = self.interpret(f, [2]) assert res == 5 + def test_elidable_promote(self): + class A(object): + pass + a1 = A() + a1.x = 1 + a2 = A() + a2.x = 2 + @elidable_compatible() + def g(a): + return a.x + def f(x): + if x == 1: + a = a1 + else: + a = a2 + return g(a) + res = self.interpret(f, [1]) + assert res == 1 + res = self.interpret(f, [4]) + assert res == 2 + def test_elidable_promote_args(self): @elidable_promote(promote_args='0') def g(func, x): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit