Author: Carl Friedrich Bolz <cfb...@gmx.de> Branch: Changeset: r45229:382f399e74b3 Date: 2011-07-01 16:19 +0200 http://bitbucket.org/pypy/pypy/changeset/382f399e74b3/
Log: rename purefunction into elidable (but keep an purefunction around as an alias, some external projects like prolog still use it). diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py --- a/pypy/interpreter/argument.py +++ b/pypy/interpreter/argument.py @@ -17,7 +17,7 @@ self.varargname = varargname self.kwargname = kwargname - @jit.purefunction + @jit.elidable def find_argname(self, name): try: return self.argnames.index(name) diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -16,7 +16,7 @@ funccallunrolling = unrolling_iterable(range(4)) -@jit.purefunction_promote() +@jit.elidable_promote() def _get_immutable_code(func): assert not func.can_change_code return func.code diff --git a/pypy/jit/backend/x86/test/test_zrpy_gc.py b/pypy/jit/backend/x86/test/test_zrpy_gc.py --- a/pypy/jit/backend/x86/test/test_zrpy_gc.py +++ b/pypy/jit/backend/x86/test/test_zrpy_gc.py @@ -10,7 +10,7 @@ from pypy.rlib import rgc from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rlib.jit import JitDriver, dont_look_inside -from pypy.rlib.jit import purefunction, unroll_safe +from pypy.rlib.jit import elidable, unroll_safe from pypy.jit.backend.llsupport.gc import GcLLDescr_framework from pypy.tool.udir import udir from pypy.config.translationoption import DEFL_GC @@ -561,7 +561,7 @@ self.run('compile_framework_external_exception_handling') def define_compile_framework_bug1(self): - @purefunction + @elidable def nonmoving(): x = X(1) for i in range(7): diff --git a/pypy/jit/codewriter/call.py b/pypy/jit/codewriter/call.py --- a/pypy/jit/codewriter/call.py +++ b/pypy/jit/codewriter/call.py @@ -208,12 +208,12 @@ assert NON_VOID_ARGS == [T for T in ARGS if T is not lltype.Void] assert RESULT == FUNC.RESULT # ok - # get the 'pure' and 'loopinvariant' flags from the function object - pure = False + # get the 'elidable' and 'loopinvariant' flags from the function object + elidable = False loopinvariant = False if op.opname == "direct_call": func = getattr(get_funcobj(op.args[0].value), '_callable', None) - pure = getattr(func, "_pure_function_", False) + elidable = getattr(func, "_elidable_function_", False) loopinvariant = getattr(func, "_jit_loop_invariant_", False) if loopinvariant: assert not NON_VOID_ARGS, ("arguments not supported for " @@ -225,9 +225,9 @@ extraeffect = EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE elif loopinvariant: extraeffect = EffectInfo.EF_LOOPINVARIANT - elif pure: + elif elidable: # XXX check what to do about exceptions (also MemoryError?) - extraeffect = EffectInfo.EF_PURE + extraeffect = EffectInfo.EF_ELIDABLE elif self._canraise(op): extraeffect = EffectInfo.EF_CAN_RAISE else: @@ -239,7 +239,7 @@ # if oopspecindex != EffectInfo.OS_NONE: assert effectinfo is not None - if pure or loopinvariant: + if elidable or loopinvariant: assert effectinfo is not None assert extraeffect != EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE # XXX this should also say assert not can_invalidate, but diff --git a/pypy/jit/codewriter/effectinfo.py b/pypy/jit/codewriter/effectinfo.py --- a/pypy/jit/codewriter/effectinfo.py +++ b/pypy/jit/codewriter/effectinfo.py @@ -9,7 +9,7 @@ _cache = {} # the 'extraeffect' field is one of the following values: - EF_PURE = 0 #pure function (and cannot raise) + EF_ELIDABLE = 0 #elidable function (and cannot raise) EF_LOOPINVARIANT = 1 #special: call it only once per loop EF_CANNOT_RAISE = 2 #a function which cannot raise EF_CAN_RAISE = 3 #normal function (can raise) @@ -92,7 +92,7 @@ result.readonly_descrs_fields = readonly_descrs_fields result.readonly_descrs_arrays = readonly_descrs_arrays if extraeffect == EffectInfo.EF_LOOPINVARIANT or \ - extraeffect == EffectInfo.EF_PURE: + extraeffect == EffectInfo.EF_ELIDABLE: result.write_descrs_fields = [] result.write_descrs_arrays = [] else: diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py --- a/pypy/jit/codewriter/jtransform.py +++ b/pypy/jit/codewriter/jtransform.py @@ -847,7 +847,7 @@ op1 = self.prepare_builtin_call(op, "llong_%s", args) op2 = self._handle_oopspec_call(op1, args, EffectInfo.OS_LLONG_%s, - EffectInfo.EF_PURE) + EffectInfo.EF_ELIDABLE) if %r == "TO_INT": assert op2.result.concretetype == lltype.Signed return op2 @@ -1328,13 +1328,13 @@ otherindex += EffectInfo._OS_offset_uni self._register_extra_helper(otherindex, othername, argtypes, resulttype, - EffectInfo.EF_PURE) + EffectInfo.EF_ELIDABLE) # return self._handle_oopspec_call(op, args, dict[oopspec_name], - EffectInfo.EF_PURE) + EffectInfo.EF_ELIDABLE) def _handle_str2unicode_call(self, op, oopspec_name, args): - # ll_str2unicode is not EF_PURE, because it can raise + # ll_str2unicode is not EF_ELIDABLE, because it can raise # UnicodeDecodeError... return self._handle_oopspec_call(op, args, EffectInfo.OS_STR2UNICODE) @@ -1380,7 +1380,7 @@ def _handle_math_sqrt_call(self, op, oopspec_name, args): return self._handle_oopspec_call(op, args, EffectInfo.OS_MATH_SQRT, - EffectInfo.EF_PURE) + EffectInfo.EF_ELIDABLE) def rewrite_op_jit_force_quasi_immutable(self, op): v_inst, c_fieldname = op.args diff --git a/pypy/jit/codewriter/policy.py b/pypy/jit/codewriter/policy.py --- a/pypy/jit/codewriter/policy.py +++ b/pypy/jit/codewriter/policy.py @@ -35,8 +35,8 @@ def _reject_function(self, func): if hasattr(func, '_jit_look_inside_'): return not func._jit_look_inside_ - # explicitly pure functions are always opaque - if getattr(func, '_pure_function_', False): + # explicitly elidable functions are always opaque + if getattr(func, '_elidable_function_', False): return True # pypy.rpython.module.* are opaque helpers mod = func.__module__ or '?' diff --git a/pypy/jit/codewriter/test/test_jtransform.py b/pypy/jit/codewriter/test/test_jtransform.py --- a/pypy/jit/codewriter/test/test_jtransform.py +++ b/pypy/jit/codewriter/test/test_jtransform.py @@ -122,7 +122,7 @@ if oopspecindex == EI.OS_STR2UNICODE: assert extraeffect == None # not pure, can raise! else: - assert extraeffect == EI.EF_PURE + assert extraeffect == EI.EF_ELIDABLE return 'calldescr-%d' % oopspecindex def calldescr_canraise(self, calldescr): return False diff --git a/pypy/jit/codewriter/test/test_policy.py b/pypy/jit/codewriter/test/test_policy.py --- a/pypy/jit/codewriter/test/test_policy.py +++ b/pypy/jit/codewriter/test/test_policy.py @@ -45,8 +45,8 @@ policy.set_supports_floats(False) assert not policy.look_inside_graph(graph) -def test_purefunction(): - @jit.purefunction +def test_elidable(): + @jit.elidable def g(x): return x + 2 graph = support.getgraph(g, [5]) diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -546,7 +546,7 @@ effectinfo = descr.get_extra_info() if effectinfo is not None: if effectinfo.extraeffect == EffectInfo.EF_LOOPINVARIANT or \ - effectinfo.extraeffect == EffectInfo.EF_PURE: + effectinfo.extraeffect == EffectInfo.EF_ELIDABLE: return True return False diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py --- a/pypy/jit/metainterp/pyjitpl.py +++ b/pypy/jit/metainterp/pyjitpl.py @@ -1233,7 +1233,7 @@ effect = effectinfo.extraeffect if effect == effectinfo.EF_CANNOT_RAISE: return self.execute_varargs(rop.CALL, allboxes, descr, False) - elif effect == effectinfo.EF_PURE: + elif effect == effectinfo.EF_ELIDABLE: return self.metainterp.record_result_of_call_pure( self.execute_varargs(rop.CALL, allboxes, descr, False)) elif effect == effectinfo.EF_LOOPINVARIANT: diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py --- a/pypy/jit/metainterp/test/test_ajit.py +++ b/pypy/jit/metainterp/test/test_ajit.py @@ -1,7 +1,7 @@ import py import sys from pypy.rlib.jit import JitDriver, we_are_jitted, hint, dont_look_inside -from pypy.rlib.jit import loop_invariant +from pypy.rlib.jit import loop_invariant, elidable from pypy.rlib.jit import jit_debug, assert_green, AssertGreenFailed from pypy.rlib.jit import unroll_safe, current_trace_length from pypy.jit.metainterp import pyjitpl, history @@ -304,10 +304,10 @@ assert res == 42 self.check_operations_history(int_add=1, int_mul=0, call=1, guard_no_exception=0) - def test_residual_call_pure(self): + def test_residual_call_elidable(self): def externfn(x, y): return x * y - externfn._pure_function_ = True + externfn._elidable_function_ = True def f(n): n = hint(n, promote=True) return externfn(n, n+1) @@ -317,10 +317,10 @@ self.check_operations_history(int_add=0, int_mul=0, call=0, call_pure=0) - def test_residual_call_pure_1(self): + def test_residual_call_elidable_1(self): + @elidable def externfn(x, y): return x * y - externfn._pure_function_ = True def f(n): return externfn(n, n+1) res = self.interp_operations(f, [6]) @@ -329,11 +329,11 @@ self.check_operations_history(int_add=1, int_mul=0, call=0, call_pure=1) - def test_residual_call_pure_2(self): + def test_residual_call_elidable_2(self): myjitdriver = JitDriver(greens = [], reds = ['n']) + @elidable def externfn(x): return x - 1 - externfn._pure_function_ = True def f(n): while n > 0: myjitdriver.can_enter_jit(n=n) @@ -346,11 +346,11 @@ # by optimizeopt.py self.check_loops(int_sub=0, call=1, call_pure=0) - def test_constfold_call_pure(self): + def test_constfold_call_elidable(self): myjitdriver = JitDriver(greens = ['m'], reds = ['n']) + @elidable def externfn(x): return x - 3 - externfn._pure_function_ = True def f(n, m): while n > 0: myjitdriver.can_enter_jit(n=n, m=m) @@ -362,11 +362,11 @@ # the CALL_PURE is constant-folded away by optimizeopt.py self.check_loops(int_sub=1, call=0, call_pure=0) - def test_constfold_call_pure_2(self): + def test_constfold_call_elidable_2(self): myjitdriver = JitDriver(greens = ['m'], reds = ['n']) + @elidable def externfn(x): return x - 3 - externfn._pure_function_ = True class V: def __init__(self, value): self.value = value @@ -382,19 +382,19 @@ # the CALL_PURE is constant-folded away by optimizeopt.py self.check_loops(int_sub=1, call=0, call_pure=0) - def test_pure_function_returning_object(self): + def test_elidable_function_returning_object(self): myjitdriver = JitDriver(greens = ['m'], reds = ['n']) class V: def __init__(self, x): self.x = x v1 = V(1) v2 = V(2) + @elidable def externfn(x): if x: return v1 else: return v2 - externfn._pure_function_ = True def f(n, m): while n > 0: myjitdriver.can_enter_jit(n=n, m=m) diff --git a/pypy/jit/metainterp/test/test_jitprof.py b/pypy/jit/metainterp/test/test_jitprof.py --- a/pypy/jit/metainterp/test/test_jitprof.py +++ b/pypy/jit/metainterp/test/test_jitprof.py @@ -1,6 +1,6 @@ from pypy.jit.metainterp.warmspot import ll_meta_interp -from pypy.rlib.jit import JitDriver, dont_look_inside, purefunction +from pypy.rlib.jit import JitDriver, dont_look_inside, elidable from pypy.jit.metainterp.test.support import LLJitMixin from pypy.jit.metainterp import pyjitpl from pypy.jit.metainterp.jitprof import * @@ -89,7 +89,7 @@ assert profiler.calls == 1 def test_blackhole_pure(self): - @purefunction + @elidable def g(n): return n+1 diff --git a/pypy/jit/metainterp/test/test_send.py b/pypy/jit/metainterp/test/test_send.py --- a/pypy/jit/metainterp/test/test_send.py +++ b/pypy/jit/metainterp/test/test_send.py @@ -1,5 +1,5 @@ import py -from pypy.rlib.jit import JitDriver, hint, purefunction +from pypy.rlib.jit import JitDriver, hint, elidable from pypy.jit.codewriter.policy import StopAtXPolicy from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin @@ -604,7 +604,7 @@ def test_constfold_pure_oosend(self): myjitdriver = JitDriver(greens=[], reds = ['i', 'obj']) class A: - @purefunction + @elidable def foo(self): return 42 def fn(n, i): diff --git a/pypy/jit/tl/tlc.py b/pypy/jit/tl/tlc.py --- a/pypy/jit/tl/tlc.py +++ b/pypy/jit/tl/tlc.py @@ -5,7 +5,7 @@ from pypy.rlib.objectmodel import specialize, we_are_translated from pypy.jit.tl.tlopcode import * from pypy.jit.tl import tlopcode -from pypy.rlib.jit import JitDriver +from pypy.rlib.jit import JitDriver, elidable class Obj(object): @@ -71,6 +71,7 @@ classes = [] # [(descr, cls), ...] + @elidable def get(key): for descr, cls in Class.classes: if key.attributes == descr.attributes and\ @@ -79,7 +80,6 @@ result = Class(key) Class.classes.append((key, result)) return result - get._pure_function_ = True get = staticmethod(get) def __init__(self, descr): diff --git a/pypy/module/_lsprof/interp_lsprof.py b/pypy/module/_lsprof/interp_lsprof.py --- a/pypy/module/_lsprof/interp_lsprof.py +++ b/pypy/module/_lsprof/interp_lsprof.py @@ -149,7 +149,7 @@ factor * float(self.ll_it), w_sublist) return space.wrap(w_se) - @jit.purefunction + @jit.elidable def _get_or_make_subentry(self, entry, make=True): try: return self.calls[entry] @@ -282,7 +282,7 @@ c_setup_profiling() space.getexecutioncontext().setllprofile(lsprof_call, space.wrap(self)) - @jit.purefunction + @jit.elidable def _get_or_make_entry(self, f_code, make=True): try: return self.data[f_code] @@ -293,7 +293,7 @@ return entry return None - @jit.purefunction + @jit.elidable def _get_or_make_builtin_entry(self, key, make=True): try: return self.builtin_data[key] diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py --- a/pypy/module/imp/importing.py +++ b/pypy/module/imp/importing.py @@ -120,7 +120,7 @@ def check_sys_modules_w(space, modulename): return space.finditem_str(space.sys.get('modules'), modulename) -@jit.purefunction +@jit.elidable def _get_dot_position(str, n): # return the index in str of the '.' such that there are n '.'-separated # strings after it diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -80,7 +80,7 @@ pypysig_getaddr_occurred = external('pypysig_getaddr_occurred', [], lltype.Ptr(LONG_STRUCT), _nowrapper=True, - pure_function=True) + elidable_function=True) c_alarm = external('alarm', [rffi.INT], rffi.INT) c_pause = external('pause', [], rffi.INT) c_siginterrupt = external('siginterrupt', [rffi.INT, rffi.INT], rffi.INT) diff --git a/pypy/objspace/std/celldict.py b/pypy/objspace/std/celldict.py --- a/pypy/objspace/std/celldict.py +++ b/pypy/objspace/std/celldict.py @@ -32,7 +32,7 @@ return self._getcell_makenew(key) return self.content.get(key, None) - @jit.purefunction + @jit.elidable def _getcell_makenew(self, key): return self.content.setdefault(key, ModuleCell()) diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py --- a/pypy/objspace/std/mapdict.py +++ b/pypy/objspace/std/mapdict.py @@ -53,7 +53,7 @@ else: return self._index_indirection(selector) - @jit.purefunction + @jit.elidable def _index_jit_pure(self, name, index): return self._index_indirection((name, index)) @@ -113,14 +113,14 @@ def set_terminator(self, obj, terminator): raise NotImplementedError("abstract base class") - @jit.purefunction + @jit.elidable def size_estimate(self): return self._size_estimate >> NUM_DIGITS def search(self, attrtype): return None - @jit.purefunction + @jit.elidable def _get_new_attr(self, name, index): selector = name, index cache = self.cache_attrs diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -9,8 +9,8 @@ from pypy.objspace.std.objecttype import object_typedef from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.objectmodel import current_object_addr_as_int, compute_hash -from pypy.rlib.jit import hint, purefunction_promote, we_are_jitted -from pypy.rlib.jit import purefunction, dont_look_inside, unroll_safe +from pypy.rlib.jit import hint, elidable_promote, we_are_jitted +from pypy.rlib.jit import elidable, dont_look_inside, unroll_safe from pypy.rlib.rarithmetic import intmask, r_uint class TypeCell(W_Root): @@ -177,7 +177,7 @@ # prebuilt objects cannot get their version_tag changed return w_self._pure_version_tag() - @purefunction_promote() + @elidable_promote() def _pure_version_tag(w_self): return w_self._version_tag @@ -247,7 +247,7 @@ return w_value return w_value - @purefunction + @elidable def _pure_getdictvalue_no_unwrapping(w_self, space, version_tag, attr): return w_self._getdictvalue_no_unwrapping(space, attr) @@ -360,7 +360,7 @@ w_class, w_value = w_self._pure_lookup_where_with_method_cache(name, version_tag) return w_class, unwrap_cell(space, w_value) - @purefunction + @elidable def _pure_lookup_where_with_method_cache(w_self, name, version_tag): space = w_self.space cache = space.fromcache(MethodCache) @@ -820,7 +820,7 @@ def _issubtype(w_sub, w_type): return w_type in w_sub.mro_w -@purefunction_promote() +@elidable_promote() def _pure_issubtype(w_sub, w_type, version_tag1, version_tag2): return _issubtype(w_sub, w_type) diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py --- a/pypy/rlib/jit.py +++ b/pypy/rlib/jit.py @@ -6,21 +6,24 @@ from pypy.rlib.unroll import unrolling_iterable from pypy.rlib.nonconst import NonConstant -def purefunction(func): - """ Decorate a function as pure. Pure means precisely that: +def elidable(func): + """ Decorate a function as "trace-elidable". This means precisely that: (1) the result of the call should not change if the arguments are the same (same numbers or same pointers) (2) it's fine to remove the call completely if we can guess the result according to rule 1 - Most importantly it doesn't mean that pure function has no observable - side effect, but those side effects can be ommited (ie caching). + Most importantly it doesn't mean that an elidable function has no observable + side effect, but those side effects are idempotent (ie caching). For now, such a function should never raise an exception. """ - func._pure_function_ = True + func._elidable_function_ = True return func +# keep "purefunction" for not breaking external projects, deprecated +purefunction = elidable + def hint(x, **kwds): """ Hint for the JIT @@ -60,13 +63,13 @@ func._jit_loop_invariant_ = True return func -def purefunction_promote(promote_args='all'): +def elidable_promote(promote_args='all'): """ A decorator that promotes all arguments and then calls the supplied function """ def decorator(func): import inspect - purefunction(func) + elidable(func) args, varargs, varkw, defaults = inspect.getargspec(func) args = ["v%s" % (i, ) for i in range(len(args))] assert varargs is None and varkw is None @@ -85,6 +88,9 @@ return result return decorator +# keep "purefunction_promote" for not breaking external projects, deprecated +purefunction_promote = elidable_promote + def oopspec(spec): def decorator(func): func.oopspec = spec diff --git a/pypy/rlib/libffi.py b/pypy/rlib/libffi.py --- a/pypy/rlib/libffi.py +++ b/pypy/rlib/libffi.py @@ -40,7 +40,7 @@ del cls._import @staticmethod - @jit.purefunction + @jit.elidable def getkind(ffi_type): """Returns 'v' for void, 'f' for float, 'i' for signed integer, and 'u' for unsigned integer. @@ -74,7 +74,7 @@ raise KeyError @staticmethod - @jit.purefunction + @jit.elidable def is_struct(ffi_type): return intmask(ffi_type.c_type) == intmask(FFI_TYPE_STRUCT) diff --git a/pypy/rlib/longlong2float.py b/pypy/rlib/longlong2float.py --- a/pypy/rlib/longlong2float.py +++ b/pypy/rlib/longlong2float.py @@ -49,9 +49,9 @@ longlong2float = rffi.llexternal( "pypy__longlong2float", [rffi.LONGLONG], rffi.DOUBLE, _callable=longlong2float_emulator, compilation_info=eci, - _nowrapper=True, pure_function=True) + _nowrapper=True, elidable_function=True) float2longlong = rffi.llexternal( "pypy__float2longlong", [rffi.DOUBLE], rffi.LONGLONG, _callable=float2longlong_emulator, compilation_info=eci, - _nowrapper=True, pure_function=True) + _nowrapper=True, elidable_function=True) diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py --- a/pypy/rlib/rbigint.py +++ b/pypy/rlib/rbigint.py @@ -124,7 +124,7 @@ return len(self._digits) @staticmethod - @jit.purefunction + @jit.elidable def fromint(intval): # This function is marked as pure, so you must not call it and # then modify the result. @@ -156,7 +156,7 @@ return v @staticmethod - @jit.purefunction + @jit.elidable def frombool(b): # This function is marked as pure, so you must not call it and # then modify the result. @@ -179,7 +179,7 @@ raise OverflowError @staticmethod - @jit.purefunction + @jit.elidable def _fromfloat_finite(dval): sign = 1 if dval < 0.0: @@ -201,7 +201,7 @@ return v @staticmethod - @jit.purefunction + @jit.elidable @specialize.argtype(0) def fromrarith_int(i): # This function is marked as pure, so you must not call it and @@ -209,7 +209,7 @@ return rbigint(*args_from_rarith_int(i)) @staticmethod - @jit.purefunction + @jit.elidable def fromdecimalstr(s): # This function is marked as pure, so you must not call it and # then modify the result. diff --git a/pypy/rlib/rmd5.py b/pypy/rlib/rmd5.py --- a/pypy/rlib/rmd5.py +++ b/pypy/rlib/rmd5.py @@ -51,7 +51,7 @@ _rotateLeft = rffi.llexternal( "pypy__rotateLeft", [lltype.Unsigned, lltype.Signed], lltype.Unsigned, _callable=_rotateLeft_emulator, compilation_info=eci, - _nowrapper=True, pure_function=True) + _nowrapper=True, elidable_function=True) # we expect the function _rotateLeft to be actually inlined diff --git a/pypy/rlib/test/test_jit.py b/pypy/rlib/test/test_jit.py --- a/pypy/rlib/test/test_jit.py +++ b/pypy/rlib/test/test_jit.py @@ -1,6 +1,6 @@ import py from pypy.conftest import option -from pypy.rlib.jit import hint, we_are_jitted, JitDriver, purefunction_promote +from pypy.rlib.jit import hint, we_are_jitted, JitDriver, elidable_promote from pypy.rlib.jit import JitHintError, oopspec from pypy.translator.translator import TranslationContext, graphof from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin @@ -31,8 +31,8 @@ res = self.interpret(f, [4]) assert res == 5 - def test_purefunction_promote(self): - @purefunction_promote() + def test_elidable_promote(self): + @elidable_promote() def g(func): return func + 1 def f(x): @@ -40,8 +40,8 @@ res = self.interpret(f, [2]) assert res == 5 - def test_purefunction_promote_args(self): - @purefunction_promote(promote_args='0') + def test_elidable_promote_args(self): + @elidable_promote(promote_args='0') def g(func, x): return func + 1 def f(x): diff --git a/pypy/rpython/lltypesystem/ll_str.py b/pypy/rpython/lltypesystem/ll_str.py --- a/pypy/rpython/lltypesystem/ll_str.py +++ b/pypy/rpython/lltypesystem/ll_str.py @@ -1,12 +1,13 @@ from pypy.rpython.lltypesystem.lltype import GcArray, Array, Char, malloc from pypy.rpython.annlowlevel import llstr from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong +from pypy.rlib import jit CHAR_ARRAY = GcArray(Char) +@jit.elidable def ll_int_str(repr, i): return ll_int2dec(i) -ll_int_str._pure_function_ = True def ll_unsigned(i): if isinstance(i, r_longlong) or isinstance(i, r_ulonglong): @@ -14,6 +15,7 @@ else: return r_uint(i) +@jit.elidable def ll_int2dec(i): from pypy.rpython.lltypesystem.rstr import mallocstr temp = malloc(CHAR_ARRAY, 20) @@ -44,13 +46,13 @@ result.chars[j] = temp[len-j-1] j += 1 return result -ll_int2dec._pure_function_ = True hex_chars = malloc(Array(Char), 16, immortal=True) for i in range(16): hex_chars[i] = "%x"%i +@jit.elidable def ll_int2hex(i, addPrefix): from pypy.rpython.lltypesystem.rstr import mallocstr temp = malloc(CHAR_ARRAY, 20) @@ -86,8 +88,8 @@ result.chars[j] = temp[len-j-1] j += 1 return result -ll_int2hex._pure_function_ = True +@jit.elidable def ll_int2oct(i, addPrefix): from pypy.rpython.lltypesystem.rstr import mallocstr if i == 0: @@ -123,9 +125,8 @@ result.chars[j] = temp[len-j-1] j += 1 return result -ll_int2oct._pure_function_ = True +@jit.elidable def ll_float_str(repr, f): from pypy.rlib.rfloat import formatd return llstr(formatd(f, 'f', 6)) -ll_float_str._pure_function_ = True diff --git a/pypy/rpython/lltypesystem/module/ll_math.py b/pypy/rpython/lltypesystem/module/ll_math.py --- a/pypy/rpython/lltypesystem/module/ll_math.py +++ b/pypy/rpython/lltypesystem/module/ll_math.py @@ -58,7 +58,7 @@ math_log10 = llexternal('log10', [rffi.DOUBLE], rffi.DOUBLE) math_copysign = llexternal(underscore + 'copysign', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE, - pure_function=True) + elidable_function=True) math_atan2 = llexternal('atan2', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) math_frexp = llexternal('frexp', [rffi.DOUBLE, rffi.INTP], rffi.DOUBLE) math_modf = llexternal('modf', [rffi.DOUBLE, rffi.DOUBLEP], rffi.DOUBLE) @@ -67,11 +67,11 @@ math_fmod = llexternal('fmod', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) math_hypot = llexternal(underscore + 'hypot', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) -math_floor = llexternal('floor', [rffi.DOUBLE], rffi.DOUBLE, pure_function=True) +math_floor = llexternal('floor', [rffi.DOUBLE], rffi.DOUBLE, elidable_function=True) math_sqrt = llexternal('sqrt', [rffi.DOUBLE], rffi.DOUBLE) -@jit.purefunction +@jit.elidable def sqrt_nonneg(x): return math_sqrt(x) sqrt_nonneg.oopspec = "math.sqrt_nonneg(x)" diff --git a/pypy/rpython/lltypesystem/rffi.py b/pypy/rpython/lltypesystem/rffi.py --- a/pypy/rpython/lltypesystem/rffi.py +++ b/pypy/rpython/lltypesystem/rffi.py @@ -55,7 +55,7 @@ compilation_info=ExternalCompilationInfo(), sandboxsafe=False, threadsafe='auto', _nowrapper=False, calling_conv='c', - oo_primitive=None, pure_function=False, + oo_primitive=None, elidable_function=False, macro=None): """Build an external function that will invoke the C function 'name' with the given 'args' types and 'result' type. @@ -87,8 +87,8 @@ name, macro, ext_type, compilation_info) else: _callable = ll2ctypes.LL2CtypesCallable(ext_type, calling_conv) - if pure_function: - _callable._pure_function_ = True + if elidable_function: + _callable._elidable_function_ = True kwds = {} if oo_primitive: kwds['oo_primitive'] = oo_primitive diff --git a/pypy/rpython/lltypesystem/rstr.py b/pypy/rpython/lltypesystem/rstr.py --- a/pypy/rpython/lltypesystem/rstr.py +++ b/pypy/rpython/lltypesystem/rstr.py @@ -4,7 +4,7 @@ from pypy.rlib.objectmodel import malloc_zero_filled, we_are_translated from pypy.rlib.objectmodel import _hash_string, enforceargs from pypy.rlib.debug import ll_assert -from pypy.rlib.jit import purefunction, we_are_jitted, dont_look_inside +from pypy.rlib.jit import elidable, we_are_jitted, dont_look_inside from pypy.rlib.rarithmetic import ovfcheck from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rpython.rmodel import inputconst, IntegerRepr @@ -144,7 +144,7 @@ self.ll = LLHelpers self.malloc = mallocunicode - @purefunction + @elidable def ll_str(self, s): # XXX crazy that this is here, but I don't want to break # rmodel logic @@ -159,7 +159,7 @@ result.chars[i] = cast_primitive(Char, c) return result - @purefunction + @elidable def ll_encode_latin1(self, s): length = len(s.chars) result = mallocstr(length) @@ -258,7 +258,7 @@ class LLHelpers(AbstractLLHelpers): - @purefunction + @elidable def ll_str_mul(s, times): if times < 0: times = 0 @@ -280,7 +280,7 @@ i += j return newstr - @purefunction + @elidable def ll_char_mul(ch, times): if typeOf(ch) is Char: malloc = mallocstr @@ -325,8 +325,7 @@ return s ll_str2unicode.oopspec = 'str.str2unicode(str)' - # it's pure but it does not look like it - @purefunction + @elidable def ll_strhash(s): # unlike CPython, there is no reason to avoid to return -1 # but our malloc initializes the memory to zero, so we use zero as the @@ -342,7 +341,7 @@ def ll_strfasthash(s): return s.hash # assumes that the hash is already computed - @purefunction + @elidable def ll_strconcat(s1, s2): len1 = len(s1.chars) len2 = len(s2.chars) @@ -352,7 +351,7 @@ return newstr ll_strconcat.oopspec = 'stroruni.concat(s1, s2)' - @purefunction + @elidable def ll_strip(s, ch, left, right): s_len = len(s.chars) if s_len == 0: @@ -370,7 +369,7 @@ s.copy_contents(s, result, lpos, 0, r_len) return result - @purefunction + @elidable def ll_upper(s): s_chars = s.chars s_len = len(s_chars) @@ -387,7 +386,7 @@ i += 1 return result - @purefunction + @elidable def ll_lower(s): s_chars = s.chars s_len = len(s_chars) @@ -428,7 +427,7 @@ i += 1 return result - @purefunction + @elidable def ll_strcmp(s1, s2): if not s1 and not s2: return True @@ -451,7 +450,7 @@ i += 1 return len1 - len2 - @purefunction + @elidable def ll_streq(s1, s2): if s1 == s2: # also if both are NULLs return True @@ -471,7 +470,7 @@ return True ll_streq.oopspec = 'stroruni.equal(s1, s2)' - @purefunction + @elidable def ll_startswith(s1, s2): len1 = len(s1.chars) len2 = len(s2.chars) @@ -487,7 +486,7 @@ return True - @purefunction + @elidable def ll_endswith(s1, s2): len1 = len(s1.chars) len2 = len(s2.chars) @@ -504,7 +503,7 @@ return True - @purefunction + @elidable def ll_find_char(s, ch, start, end): i = start if end > len(s.chars): @@ -516,7 +515,7 @@ return -1 ll_find_char._annenforceargs_ = [None, None, int, int] - @purefunction + @elidable def ll_rfind_char(s, ch, start, end): if end > len(s.chars): end = len(s.chars) @@ -527,7 +526,7 @@ return i return -1 - @purefunction + @elidable def ll_count_char(s, ch, start, end): count = 0 i = start @@ -595,7 +594,7 @@ res = 0 return res - @purefunction + @elidable def ll_search(s1, s2, start, end, mode): count = 0 n = end - start @@ -718,7 +717,7 @@ i += 1 return result - @purefunction + @elidable def _ll_stringslice(s1, start, stop): lgt = stop - start assert start >= 0 @@ -816,7 +815,7 @@ item.copy_contents(s, item, j, 0, i - j) return res - @purefunction + @elidable def ll_replace_chr_chr(s, c1, c2): length = len(s.chars) newstr = s.malloc(length) @@ -831,7 +830,7 @@ j += 1 return newstr - @purefunction + @elidable def ll_contains(s, c): chars = s.chars strlen = len(chars) @@ -842,7 +841,7 @@ i += 1 return False - @purefunction + @elidable def ll_int(s, base): if not 2 <= base <= 36: raise ValueError _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit