Author: Armin Rigo <[email protected]>
Branch:
Changeset: r75464:5fc2a9b77793
Date: 2015-01-21 18:44 +0100
http://bitbucket.org/pypy/pypy/changeset/5fc2a9b77793/
Log: Add objectmodel.likely(), .unlikely()
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/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
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit