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

Reply via email to