[pypy-commit] pypy default: Try to avoid writing with a type on which the sign was forgotten.

arigo noreply at buildbot.pypy.org
Thu Dec 20 16:29:33 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r59524:71357aa32f93
Date: 2012-12-20 16:29 +0100
http://bitbucket.org/pypy/pypy/changeset/71357aa32f93/

Log:	Try to avoid writing with a type on which the sign was forgotten.
	Should help in the JIT.

diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py
--- a/pypy/module/_cffi_backend/misc.py
+++ b/pypy/module/_cffi_backend/misc.py
@@ -1,7 +1,7 @@
 from __future__ import with_statement
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi
-from pypy.rlib.rarithmetic import r_uint, r_ulonglong
+from pypy.rlib.rarithmetic import r_uint, r_ulonglong, is_signed_integer_type
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.rlib.objectmodel import keepalive_until_here, specialize
 from pypy.rlib import jit
@@ -64,10 +64,16 @@
 
 @specialize.argtype(1)
 def write_raw_integer_data(target, source, size):
-    for TP, TPP in _prim_unsigned_types:
-        if size == rffi.sizeof(TP):
-            rffi.cast(TPP, target)[0] = rffi.cast(TP, source)
-            return
+    if is_signed_integer_type(lltype.typeOf(source)):
+        for TP, TPP in _prim_signed_types:
+            if size == rffi.sizeof(TP):
+                rffi.cast(TPP, target)[0] = rffi.cast(TP, source)
+                return
+    else:
+        for TP, TPP in _prim_unsigned_types:
+            if size == rffi.sizeof(TP):
+                rffi.cast(TPP, target)[0] = rffi.cast(TP, source)
+                return
     raise NotImplementedError("bad integer size")
 
 def write_raw_float_data(target, source, size):
diff --git a/pypy/rlib/rarithmetic.py b/pypy/rlib/rarithmetic.py
--- a/pypy/rlib/rarithmetic.py
+++ b/pypy/rlib/rarithmetic.py
@@ -246,6 +246,17 @@
         return r_class(0)
 most_neg_value_of._annspecialcase_ = 'specialize:memo'
 
+def is_signed_integer_type(tp):
+    from pypy.rpython.lltypesystem import lltype, rffi
+    if tp is lltype.Signed:
+        return True
+    try:
+        r_class = rffi.platform.numbertype_to_rclass[tp]
+        return r_class.SIGNED
+    except KeyError:
+        return False   # not an integer type
+is_signed_integer_type._annspecialcase_ = 'specialize:memo'
+
 def highest_bit(n):
     """
     Calculates the highest set bit in n.  This function assumes that n is a
diff --git a/pypy/rlib/test/test_rarithmetic.py b/pypy/rlib/test/test_rarithmetic.py
--- a/pypy/rlib/test/test_rarithmetic.py
+++ b/pypy/rlib/test/test_rarithmetic.py
@@ -364,6 +364,17 @@
     assert most_neg_value_of_same_type(r_longlong(123)) == llmin
     assert most_neg_value_of_same_type(r_ulonglong(123)) == 0
 
+def test_is_signed_integer_type():
+    from pypy.rpython.lltypesystem import lltype, rffi
+    assert is_signed_integer_type(lltype.Signed)
+    assert is_signed_integer_type(rffi.SIGNEDCHAR)
+    assert is_signed_integer_type(lltype.SignedLongLong)
+    assert not is_signed_integer_type(lltype.Unsigned)
+    assert not is_signed_integer_type(lltype.UnsignedLongLong)
+    assert not is_signed_integer_type(lltype.Char)
+    assert not is_signed_integer_type(lltype.UniChar)
+    assert not is_signed_integer_type(lltype.Bool)
+
 def test_r_ulonglong():
     x = r_longlong(-1)
     y = r_ulonglong(x)


More information about the pypy-commit mailing list