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

Reply via email to