Author: Carl Friedrich Bolz <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit