Author: Carl Friedrich Bolz <cfb...@gmx.de> Branch: Changeset: r75485:023b261dd2d5 Date: 2015-01-22 16:50 +0100 http://bitbucket.org/pypy/pypy/changeset/023b261dd2d5/
Log: merge diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -130,3 +130,6 @@ mmap(), called rarely during major GCs, if such a major GC occurs at exactly the wrong time), and some of the less rare kind (particularly on Windows tests). + +.. branch: osx-package.py +.. branch: package.py-helpful-error-message diff --git a/pypy/module/pypyjit/test_pypy_c/test_containers.py b/pypy/module/pypyjit/test_pypy_c/test_containers.py --- a/pypy/module/pypyjit/test_pypy_c/test_containers.py +++ b/pypy/module/pypyjit/test_pypy_c/test_containers.py @@ -78,7 +78,7 @@ {{{ setfield_gc(p13, 0, descr=<FieldS dicttable.lookup_function_no .+>) setfield_gc(p13, 0, descr=<FieldS dicttable.num_live_items .+>) - setfield_gc(p13, 16, descr=<FieldS dicttable.resize_counter .+>) + setfield_gc(p13, 32, descr=<FieldS dicttable.resize_counter .+>) }}} guard_no_exception(descr=...) p20 = new_with_vtable(ConstClass(W_IntObject)) diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py --- a/rpython/jit/codewriter/jtransform.py +++ b/rpython/jit/codewriter/jtransform.py @@ -253,6 +253,12 @@ return [None, # hack, do the right renaming from op.args[0] to op.result SpaceOperation("record_known_class", [op.args[0], const_vtable], None)] + def rewrite_op_likely(self, op): + return None # "no real effect" + + def rewrite_op_unlikely(self, op): + return None # "no real effect" + def rewrite_op_raw_malloc_usage(self, op): if self.cpu.translate_support_code or isinstance(op.args[0], Variable): return # the operation disappears diff --git a/rpython/jit/codewriter/test/test_jtransform.py b/rpython/jit/codewriter/test/test_jtransform.py --- a/rpython/jit/codewriter/test/test_jtransform.py +++ b/rpython/jit/codewriter/test/test_jtransform.py @@ -1376,3 +1376,12 @@ tr.rewrite_operation(op) except Exception, e: assert 'foobar' in str(e) + +def test_likely_unlikely(): + v1 = varoftype(lltype.Bool) + v2 = varoftype(lltype.Bool) + op = SpaceOperation('likely', [v1], v2) + tr = Transformer() + assert tr.rewrite_operation(op) is None + op = SpaceOperation('unlikely', [v1], v2) + assert tr.rewrite_operation(op) is None diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py --- a/rpython/rlib/objectmodel.py +++ b/rpython/rlib/objectmodel.py @@ -636,6 +636,30 @@ # ____________________________________________________________ +def likely(condition): + assert isinstance(condition, bool) + return condition + +def unlikely(condition): + assert isinstance(condition, bool) + return condition + +class Entry(ExtRegistryEntry): + _about_ = (likely, unlikely) + + def compute_result_annotation(self, s_x): + from rpython.annotator import model as annmodel + return annmodel.SomeBool() + + def specialize_call(self, hop): + from rpython.rtyper.lltypesystem import lltype + vlist = hop.inputargs(lltype.Bool) + hop.exception_cannot_occur() + return hop.genop(self.instance.__name__, vlist, + resulttype=lltype.Bool) + +# ____________________________________________________________ + class r_dict(object): """An RPython dict-like object. diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -365,6 +365,9 @@ 'convert_float_bytes_to_longlong': LLOp(canfold=True), 'convert_longlong_bytes_to_float': LLOp(canfold=True), + 'likely': LLOp(canfold=True), + 'unlikely': LLOp(canfold=True), + # __________ pointer operations __________ 'malloc': LLOp(canmallocgc=True), diff --git a/rpython/rtyper/lltypesystem/opimpl.py b/rpython/rtyper/lltypesystem/opimpl.py --- a/rpython/rtyper/lltypesystem/opimpl.py +++ b/rpython/rtyper/lltypesystem/opimpl.py @@ -699,6 +699,14 @@ return p[0] op_raw_load.need_result_type = True +def op_likely(x): + assert isinstance(x, bool) + return x + +def op_unlikely(x): + assert isinstance(x, bool) + return x + # ____________________________________________________________ def get_op_impl(opname): diff --git a/rpython/rtyper/lltypesystem/rordereddict.py b/rpython/rtyper/lltypesystem/rordereddict.py --- a/rpython/rtyper/lltypesystem/rordereddict.py +++ b/rpython/rtyper/lltypesystem/rordereddict.py @@ -4,7 +4,7 @@ from rpython.rtyper.rdict import AbstractDictRepr, AbstractDictIteratorRepr from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rlib import objectmodel, jit, rgc -from rpython.rlib.objectmodel import specialize +from rpython.rlib.objectmodel import specialize, likely from rpython.rlib.debug import ll_assert from rpython.rlib.rarithmetic import r_uint, intmask from rpython.rtyper import rmodel @@ -46,7 +46,11 @@ @jit.oopspec('ordereddict.lookup(d, key, hash, flag)') def ll_call_lookup_function(d, key, hash, flag): fun = d.lookup_function_no & FUNC_MASK - if fun == FUNC_BYTE: + # This likely() here forces gcc to compile the check for fun == FUNC_BYTE + # first. Otherwise, this is a regular switch and gcc (at least 4.7) + # compiles this as a series of checks, with the FUNC_BYTE case last. + # It sounds minor, but it is worth 6-7% on a PyPy microbenchmark. + if likely(fun == FUNC_BYTE): return ll_dict_lookup(d, key, hash, flag, TYPE_BYTE) elif fun == FUNC_SHORT: return ll_dict_lookup(d, key, hash, flag, TYPE_SHORT) diff --git a/rpython/translator/c/src/int.h b/rpython/translator/c/src/int.h --- a/rpython/translator/c/src/int.h +++ b/rpython/translator/c/src/int.h @@ -238,6 +238,14 @@ #define OP_BOOL_NOT(x, r) r = !(x) +#ifdef __GNUC__ +# define OP_LIKELY(x, r) r = __builtin_expect((x), 1) +# define OP_UNLIKELY(x, r) r = __builtin_expect((x), 0) +#else +# define OP_LIKELY(x, r) r = (x) +# define OP_UNLIKELY(x, r) r = (x) +#endif + RPY_EXTERN long long op_llong_mul_ovf(long long a, long long b); /* The definitions above can be used with various types */ diff --git a/rpython/translator/c/test/test_lltyped.py b/rpython/translator/c/test/test_lltyped.py --- a/rpython/translator/c/test/test_lltyped.py +++ b/rpython/translator/c/test/test_lltyped.py @@ -956,3 +956,18 @@ fn = self.getcompiled(f, [int]) assert fn(0) == 9 + + def test_likely_unlikely(self): + from rpython.rlib.objectmodel import likely, unlikely + + def f(n): + if unlikely(n > 50): + return -10 + if likely(n > 5): + return 42 + return 3 + + fn = self.getcompiled(f, [int]) + assert fn(0) == 3 + assert fn(10) == 42 + assert fn(100) == -10 diff --git a/rpython/translator/exceptiontransform.py b/rpython/translator/exceptiontransform.py --- a/rpython/translator/exceptiontransform.py +++ b/rpython/translator/exceptiontransform.py @@ -398,6 +398,10 @@ else: v_exc_type = self.gen_getfield('exc_type', llops) var_no_exc = self.gen_isnull(v_exc_type, llops) + # + # We could add a "var_no_exc is likely true" hint, but it seems + # not to help, so it was commented out again. + #var_no_exc = llops.genop('likely', [var_no_exc], lltype.Bool) block.operations.extend(llops) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit