[pypy-commit] pypy improve-rbigint: Make _wide_digit use a cast instead of making a new value (slighty faster), make sure we support 32bit (I'm building a 32bit binary myself now, seems to work). And fix things those things arigo pointed out

stian noreply at buildbot.pypy.org
Sat Jul 21 18:42:02 CEST 2012


Author: stian
Branch: improve-rbigint
Changeset: r56369:019df915b3ec
Date: 2012-07-14 20:50 +0200
http://bitbucket.org/pypy/pypy/changeset/019df915b3ec/

Log:	Make _wide_digit use a cast instead of making a new value (slighty
	faster), make sure we support 32bit (I'm building a 32bit binary
	myself now, seems to work). And fix things those things arigo
	pointed out

diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -462,11 +462,6 @@
     rewrite_op_llong_floordiv_zer = _do_builtin_call
     rewrite_op_llong_mod          = _do_builtin_call
     rewrite_op_llong_mod_zer      = _do_builtin_call
-    rewrite_op_lllong_abs          = _do_builtin_call
-    rewrite_op_lllong_floordiv     = _do_builtin_call
-    rewrite_op_lllong_floordiv_zer = _do_builtin_call
-    rewrite_op_lllong_mod          = _do_builtin_call
-    rewrite_op_lllong_mod_zer      = _do_builtin_call
     rewrite_op_ullong_floordiv     = _do_builtin_call
     rewrite_op_ullong_floordiv_zer = _do_builtin_call
     rewrite_op_ullong_mod          = _do_builtin_call
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -250,101 +250,6 @@
 
 _ll_1_ll_math_ll_math_sqrt = ll_math.ll_math_sqrt
 
-# long long long support
-# -----------------
-
-def u_to_longlonglong(x):
-    return rffi.cast(lltype.SignedLongLongLong, x)
-
-def _ll_1_lllong_invert(xll):
-    y = ~r_ulonglonglong(xll)
-    return u_to_longlonglong(y)
-
-def _ll_2_lllong_lt(xll, yll):
-    return xll < yll
-
-def _ll_2_lllong_le(xll, yll):
-    return xll <= yll
-
-def _ll_2_lllong_eq(xll, yll):
-    return xll == yll
-
-def _ll_2_lllong_ne(xll, yll):
-    return xll != yll
-
-def _ll_2_lllong_gt(xll, yll):
-    return xll > yll
-
-def _ll_2_lllong_ge(xll, yll):
-    return xll >= yll
-
-def _ll_2_lllong_add(xull, yull):
-    z = (xull) + (yull)
-    return (z)
-
-def _ll_2_lllong_sub(xull, yull):
-    z = (xull) - (yull)
-    return (z)
-
-def _ll_2_lllong_mul(xull, yull):
-    z = (xull) * (yull)
-    return (z)
-
-def _ll_2_lllong_and(xull, yull):
-    z = (xull) & (yull)
-    return (z)
-
-def _ll_2_lllong_or(xull, yull):
-    z = (xull) | (yull)
-    return (z)
-
-def _ll_2_lllong_xor(xull, yull):
-    z = (xull) ^ (yull)
-    return (z)
-
-def _ll_2_lllong_lshift(xlll, y):
-    return xll << y
-
-def _ll_2_lllong_rshift(xlll, y):
-    return xll >> y
-
-def _ll_1_lllong_from_int(x):
-    return r_longlonglong(intmask(x))
-
-def _ll_1_lllong_from_uint(x):
-    return r_longlonglong(r_uint(x))
-
-def _ll_1_lllong_to_int(xlll):
-    return intmask(xll)
-
-def _ll_1_lllong_from_float(xf):
-    return r_longlonglong(xf)
-
-def _ll_1_llong_to_float(xll):
-    return float(rffi.cast(lltype.SignedLongLongLong, xlll))
-
-def _ll_1_llong_abs(xll):
-    if xll < 0:
-        return -xll
-    else:
-        return xll
-
-def _ll_2_llong_floordiv(xll, yll):
-    return llop.lllong_floordiv(lltype.SignedLongLongLong, xll, yll)
-
-def _ll_2_llong_floordiv_zer(xll, yll):
-    if yll == 0:
-        raise ZeroDivisionError
-    return llop.lllong_floordiv(lltype.SignedLongLongLong, xll, yll)
-
-def _ll_2_llong_mod(xll, yll):
-    return llop.lllong_mod(lltype.SignedLongLongLong, xll, yll)
-
-def _ll_2_llong_mod_zer(xll, yll):
-    if yll == 0:
-        raise ZeroDivisionError
-    return llop.lllong_mod(lltype.SignedLongLongLong, xll, yll)
-
 
 # long long support
 # -----------------
diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -20,10 +20,13 @@
 
 #SHIFT = (LONG_BIT // 2) - 1
 if SUPPORT_INT128:
+    rffi.TYPES += ["__int128"]
+    rffi.setup()
     SHIFT = 63
     BASE = long(1 << SHIFT)
     UDIGIT_TYPE = r_ulonglong
     UDIGIT_MASK = longlongmask
+    LONG_TYPE = rffi.__INT128
     if LONG_BIT > SHIFT:
         STORE_TYPE = lltype.Signed
         UNSIGNED_TYPE = lltype.Unsigned
@@ -37,6 +40,7 @@
     UDIGIT_MASK = intmask
     STORE_TYPE = lltype.Signed
     UNSIGNED_TYPE = lltype.Unsigned
+    LONG_TYPE = rffi.LONGLONG
 
 MASK = BASE - 1
 FLOAT_MULTIPLIER = float(1 << LONG_BIT) # Because it works.
@@ -82,14 +86,7 @@
 _mask_digit._annspecialcase_ = 'specialize:argtype(0)'
 
 def _widen_digit(x):
-    """if not we_are_translated():
-        assert is_valid_int(x), "widen_digit() takes an int, got a %r" % type(x)"""
-    if SHIFT > 31:
-        # XXX: Using rffi.cast is probably quicker, but I dunno how to get it working.
-        return r_longlonglong(x)
-    else:
-        return r_longlong(x)
-_widen_digit._always_inline_ = True
+    return rffi.cast(LONG_TYPE, x)
 
 def _store_digit(x):
     return rffi.cast(STORE_TYPE, x)
diff --git a/pypy/rpython/lltypesystem/ll2ctypes.py b/pypy/rpython/lltypesystem/ll2ctypes.py
--- a/pypy/rpython/lltypesystem/ll2ctypes.py
+++ b/pypy/rpython/lltypesystem/ll2ctypes.py
@@ -133,12 +133,14 @@
         rffi.LONGLONG:   ctypes.c_longlong,
         rffi.ULONGLONG:  ctypes.c_ulonglong,
         rffi.SIZE_T:     ctypes.c_size_t,
-        rffi.__INT128:   ctypes.c_longlong, # XXX: Not right at all. But for some reason, It started by while doing JIT compile after a merge with default. Can't extend ctypes, because thats a python standard, right?
         lltype.Bool:     getattr(ctypes, "c_bool", ctypes.c_byte),
         llmemory.Address:  ctypes.c_void_p,
         llmemory.GCREF:    ctypes.c_void_p,
         llmemory.WeakRef:  ctypes.c_void_p, # XXX
         })
+        
+    if '__int128' in rffi.TYPES:
+        _ctypes_cache[rffi.__INT128] = ctypes.c_longlong # XXX: Not right at all. But for some reason, It started by while doing JIT compile after a merge with default. Can't extend ctypes, because thats a python standard, right?
 
     # for unicode strings, do not use ctypes.c_wchar because ctypes
     # automatically converts arrays into unicode strings.
diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -39,7 +39,7 @@
     'float': float,
     'uint': r_uint,
     'llong': r_longlong_arg,
-    'llong': r_longlong_arg,
+    'ullong': r_ulonglong,
     'lllong': r_longlonglong,
     }
 
diff --git a/pypy/rpython/lltypesystem/rffi.py b/pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py
+++ b/pypy/rpython/lltypesystem/rffi.py
@@ -11,7 +11,7 @@
 from pypy.rlib import rarithmetic, rgc
 from pypy.rpython.extregistry import ExtRegistryEntry
 from pypy.rlib.unroll import unrolling_iterable
-from pypy.rpython.tool.rfficache import platform
+from pypy.rpython.tool.rfficache import platform, sizeof_c_type
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.rpython.annlowlevel import llhelper
 from pypy.rlib.objectmodel import we_are_translated
@@ -19,6 +19,7 @@
 from pypy.rlib import jit
 from pypy.rpython.lltypesystem import llmemory
 from pypy.rlib.rarithmetic import maxint, LONG_BIT
+from pypy.translator.platform import CompilationError
 import os, sys
 
 class CConstant(Symbolic):
@@ -434,10 +435,17 @@
         TYPES.append(name)
 TYPES += ['signed char', 'unsigned char',
           'long long', 'unsigned long long',
-          '__int128',
           'size_t', 'time_t', 'wchar_t',
           'uintptr_t', 'intptr_t',
           'void*']    # generic pointer type
+
+# This is a bit of a hack since we can't use rffi_platform here.
+try:          
+    sizeof_c_type('__int128')
+    TYPES += ['__int128']
+except CompilationError:
+    pass
+    
 _TYPES_ARE_UNSIGNED = set(['size_t', 'uintptr_t'])   # plus "unsigned *"
 if os.name != 'nt':
     TYPES.append('mode_t')
diff --git a/pypy/rpython/rint.py b/pypy/rpython/rint.py
--- a/pypy/rpython/rint.py
+++ b/pypy/rpython/rint.py
@@ -4,7 +4,8 @@
 from pypy.objspace.flow.operation import op_appendices
 from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Bool, Float, \
      Void, Char, UniChar, malloc, pyobjectptr, UnsignedLongLong, \
-     SignedLongLong, build_number, Number, cast_primitive, typeOf, SignedLongLongLong
+     SignedLongLong, build_number, Number, cast_primitive, typeOf, \
+     SignedLongLongLong
 from pypy.rpython.rmodel import IntegerRepr, inputconst
 from pypy.rpython.robject import PyObjRepr, pyobj_repr
 from pypy.rlib.rarithmetic import intmask, r_int, r_uint, r_ulonglong, \
@@ -32,11 +33,10 @@
 
 signed_repr = getintegerrepr(Signed, 'int_')
 signedlonglong_repr = getintegerrepr(SignedLongLong, 'llong_')
-unsigned_repr = getintegerrepr(SignedLongLongLong, 'lllong_')
+signedlonglonglong_repr = getintegerrepr(SignedLongLongLong, 'lllong_')
 unsigned_repr = getintegerrepr(Unsigned, 'uint_')
 unsignedlonglong_repr = getintegerrepr(UnsignedLongLong, 'ullong_')
 
-
 class __extend__(pairtype(IntegerRepr, IntegerRepr)):
 
     def convert_from_to((r_from, r_to), v, llops):
diff --git a/pypy/translator/c/primitive.py b/pypy/translator/c/primitive.py
--- a/pypy/translator/c/primitive.py
+++ b/pypy/translator/c/primitive.py
@@ -12,6 +12,9 @@
 from pypy.rpython.lltypesystem.llarena import RoundedUpForAllocation
 from pypy.translator.c.support import cdecl, barebonearray
 
+from pypy.rpython.tool import rffi_platform
+SUPPORT_INT128 = rffi_platform.has('__int128', '')
+
 # ____________________________________________________________
 #
 # Primitives
@@ -247,4 +250,5 @@
 define_c_primitive(rffi.ULONG, 'unsigned long', 'UL')
 define_c_primitive(rffi.LONGLONG, 'long long', 'LL')
 define_c_primitive(rffi.ULONGLONG, 'unsigned long long', 'ULL')
-define_c_primitive(rffi.__INT128, '__int128', 'LL') # Unless it's a 128bit platform, LL is the biggest
\ No newline at end of file
+if SUPPORT_INT128:
+    define_c_primitive(rffi.__INT128, '__int128', 'LL') # Unless it's a 128bit platform, LL is the biggest
\ No newline at end of file
diff --git a/pypy/translator/goal/targetbigintbenchmark.py b/pypy/translator/goal/targetbigintbenchmark.py
--- a/pypy/translator/goal/targetbigintbenchmark.py
+++ b/pypy/translator/goal/targetbigintbenchmark.py
@@ -35,25 +35,24 @@
         Sum:  142.686547
         
         Pypy with improvements:
-        mod by 2:  0.007256
-        mod by 10000:  3.175842
-        mod by 1024 (power of two):  0.011571
-        Div huge number by 2**128: 2.187273
-        rshift: 2.319537
-        lshift: 1.488359
-        Floordiv by 2: 1.513284
-        Floordiv by 3 (not power of two): 4.210322
-        2**500000: 0.033903
-        (2**N)**5000000 (power of two): 0.052366
-        10000 ** BIGNUM % 100 2.032749
-        i = i * i: 4.609749
-        n**10000 (not power of two): 6.266791
-        Power of two ** power of two: 0.013294
-        v = v * power of two 4.107085
-        v = v * v 6.384141
-        v = v + v 2.820538
-        Sum:  41.234060
-
+        mod by 2:  0.003079
+        mod by 10000:  3.227921
+        mod by 1024 (power of two):  0.011448
+        Div huge number by 2**128: 2.185106
+        rshift: 2.327723
+        lshift: 1.490478
+        Floordiv by 2: 1.555817
+        Floordiv by 3 (not power of two): 4.179813
+        2**500000: 0.034017
+        (2**N)**5000000 (power of two): 0.047109
+        10000 ** BIGNUM % 100 2.024060
+        i = i * i: 3.966529
+        n**10000 (not power of two): 6.251766
+        Power of two ** power of two: 0.013693
+        v = v * power of two 3.535467
+        v = v * v 6.361221
+        v = v + v 2.771434
+        Sum:  39.986681
 
         With SUPPORT_INT128 set to False
         mod by 2:  0.004103


More information about the pypy-commit mailing list