[pypy-svn] r78694 - pypy/trunk/pypy/translator/c/src

arigo at codespeak.net arigo at codespeak.net
Thu Nov 4 16:41:28 CET 2010


Author: arigo
Date: Thu Nov  4 16:41:25 2010
New Revision: 78694

Modified:
   pypy/trunk/pypy/translator/c/src/g_include.h
   pypy/trunk/pypy/translator/c/src/int.h
Log:
- a general clean-up of int.h.  Fixes an issue with
  OP_INT_ADD_NONNEG_OVF(), hopefully.

- disable the file asm_gcc_x86.h for now.  On some simple
  tests I actually got slower results with it.  It seems
  that correct scheduling is more important on modern
  processors than simply reducing the number of operations.


Modified: pypy/trunk/pypy/translator/c/src/g_include.h
==============================================================================
--- pypy/trunk/pypy/translator/c/src/g_include.h	(original)
+++ pypy/trunk/pypy/translator/c/src/g_include.h	Thu Nov  4 16:41:25 2010
@@ -39,9 +39,10 @@
 #include "src/instrument.h"
 
 /* optional assembler bits */
-#if defined(__GNUC__) && defined(__i386__)
-#  include "src/asm_gcc_x86.h"
-#endif
+// disabled: does not give any speed-up
+//#if defined(__GNUC__) && defined(__i386__)
+//#  include "src/asm_gcc_x86.h"
+//#endif
 
 #if defined(__GNUC__) && defined(__ppc__)
 #  include "src/asm_ppc.h"

Modified: pypy/trunk/pypy/translator/c/src/int.h
==============================================================================
--- pypy/trunk/pypy/translator/c/src/int.h	(original)
+++ pypy/trunk/pypy/translator/c/src/int.h	Thu Nov  4 16:41:25 2010
@@ -2,40 +2,27 @@
 /************************************************************/
  /***  C header subsection: operations between ints        ***/
 
-#ifndef LLONG_MAX
-# if SIZEOF_LONG_LONG == 8
-#  define LLONG_MAX 0X7FFFFFFFFFFFFFFFLL
-# else
-#  error "fix LLONG_MAX"
-# endif
-#endif
-
-#ifndef LLONG_MIN
-# define LLONG_MIN (-LLONG_MAX-1)
-#endif
 
 /*** unary operations ***/
 
-#define OP_INT_IS_TRUE(x,r)   OP_INT_NE(x,0,r)
-
-#define OP_INT_INVERT(x,r)    r = ~((x))
-
-#define OP_INT_NEG(x,r)    r = -(x)
+#define OP_INT_IS_TRUE(x,r)   r = ((x) != 0)
+#define OP_INT_INVERT(x,r)    r = ~(x)
+#define OP_INT_NEG(x,r)       r = -(x)
 
 #define OP_INT_NEG_OVF(x,r) \
-    if ((x) == LONG_MIN) FAIL_OVF("integer negate"); \
+	if ((x) == LONG_MIN) FAIL_OVF("integer negate"); \
 	OP_INT_NEG(x,r)
 #define OP_LLONG_NEG_OVF(x,r) \
-    if ((x) == LLONG_MIN) FAIL_OVF("integer negate"); \
+	if ((x) == LLONG_MIN) FAIL_OVF("integer negate"); \
 	OP_LLONG_NEG(x,r)
 
 #define OP_INT_ABS(x,r)    r = (x) >= 0 ? x : -(x)
 
 #define OP_INT_ABS_OVF(x,r) \
-    if ((x) == LONG_MIN) FAIL_OVF("integer absolute"); \
+	if ((x) == LONG_MIN) FAIL_OVF("integer absolute"); \
 	OP_INT_ABS(x,r)
 #define OP_LLONG_ABS_OVF(x,r) \
-    if ((x) == LLONG_MIN) FAIL_OVF("integer absolute"); \
+	if ((x) == LLONG_MIN) FAIL_OVF("integer absolute"); \
 	OP_LLONG_ABS(x,r)
 
 /***  binary operations ***/
@@ -59,50 +46,46 @@
 
 #define OP_INT_ADD(x,y,r)     r = (x) + (y)
 
+/* cast to avoid undefined behaviour on overflow */
 #define OP_INT_ADD_OVF(x,y,r) \
-	OP_INT_ADD(x,y,r); \
-	if ((r^(x)) >= 0 || (r^(y)) >= 0); \
-	else FAIL_OVF("integer addition")
+        r = (long)((unsigned long)x + y); \
+        if ((r^x) < 0 && (r^y) < 0) FAIL_OVF("integer addition")
+
+#define OP_LLONG_ADD_OVF(x,y,r) \
+        r = (long long)((unsigned long long)x + y); \
+        if ((r^x) < 0 && (r^y) < 0) FAIL_OVF("integer addition")
 
 #define OP_INT_ADD_NONNEG_OVF(x,y,r)  /* y can be assumed >= 0 */ \
-    r = (long)((unsigned long)x + (unsigned long)y); \
-    if (r >= (x)); \
-    else FAIL_OVF("integer addition")
-/* Can a C compiler be too clever and think it can "prove" that
- * r >= x always holds above?  Yes.  Hence the casting. */
+        r = (long)((unsigned long)x + y); \
+        if ((r&~x) < 0) FAIL_OVF("integer addition")
 
 #define OP_INT_SUB(x,y,r)     r = (x) - (y)
 
 #define OP_INT_SUB_OVF(x,y,r) \
-	OP_INT_SUB(x,y,r); \
-	if ((r^(x)) >= 0 || (r^~(y)) >= 0); \
-	else FAIL_OVF("integer subtraction")
-
-#define OP_INT_MUL(x,y,r)     r = (x) * (y)
-
-#if defined(HAVE_LONG_LONG) && SIZE_OF_LONG_LONG < SIZE_OF_LONG
-#  define OP_INT_MUL_OVF_LL      1
-#lse
-#  define OP_INT_MUL_OVF_LL      0
-#endif
+        r = (long)((unsigned long)x - y); \
+        if ((r^x) < 0 && (r^~y) < 0) FAIL_OVF("integer subtraction")
 
-#if !OP_INT_MUL_OVF_LL
+#define OP_LLONG_SUB_OVF(x,y,r) \
+        r = (long long)((unsigned long long)x - y); \
+        if ((r^x) < 0 && (r^~y) < 0) FAIL_OVF("integer subtraction")
 
-#define OP_INT_MUL_OVF(x,y,r) \
-	if (op_int_mul_ovf(x,y,&r)); \
-	else FAIL_OVF("integer multiplication")
-
-#else
+#define OP_INT_MUL(x,y,r)     r = (x) * (y)
 
+#if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
 #define OP_INT_MUL_OVF(x,y,r) \
 	{ \
-		PY_LONG_LONG lr = (PY_LONG_LONG)(x) * (PY_LONG_LONG)(y); \
-		r = (long)lr; \
-		if ((PY_LONG_LONG)r == lr); \
-		else FAIL_OVF("integer multiplication"); \
+		long long _lr = (long long)x * y; \
+		r = (long)_lr; \
+		if (_lr != (long long)r) FAIL_OVF("integer multiplication"); \
 	}
+#else
+#define OP_INT_MUL_OVF(x,y,r) \
+	r = op_llong_mul_ovf(x, y)   /* long == long long */
 #endif
 
+#define OP_LLONG_MUL_OVF(x,y,r) \
+	r = op_llong_mul_ovf(x, y)
+
 /* shifting */
 
 /* NB. shifting has same limitations as C: the shift count must be
@@ -121,6 +104,10 @@
 	OP_INT_LSHIFT(x,y,r); \
 	if ((x) != Py_ARITHMETIC_RIGHT_SHIFT(long, r, (y))) \
 		FAIL_OVF("x<<y losing bits or changing sign")
+#define OP_LLONG_LSHIFT_OVF(x,y,r) \
+	OP_LLONG_LSHIFT(x,y,r); \
+	if ((x) != Py_ARITHMETIC_RIGHT_SHIFT(PY_LONG_LONG, r, (y))) \
+		FAIL_OVF("x<<y losing bits or changing sign")
 
 /* floor division */
 
@@ -129,27 +116,48 @@
 #define OP_LLONG_FLOORDIV(x,y,r)  r = (x) / (y)
 #define OP_ULLONG_FLOORDIV(x,y,r) r = (x) / (y)
 
-#define OP_INT_FLOORDIV_OVF(x,y,r) \
-	if ((y) == -1 && (x) == LONG_MIN) \
-            { FAIL_OVF("integer division"); } \
-        else OP_INT_FLOORDIV(x,y,r)
-
-#define OP_INT_FLOORDIV_ZER(x,y,r) \
-	if ((y)) { OP_INT_FLOORDIV(x,y,r); } \
-	else FAIL_ZER("integer division")
-#define OP_UINT_FLOORDIV_ZER(x,y,r) \
-	if ((y)) { OP_UINT_FLOORDIV(x,y,r); } \
-	else FAIL_ZER("unsigned integer division")
-#define OP_LLONG_FLOORDIV_ZER(x,y,r) \
-	if ((y)) { OP_LLONG_FLOORDIV(x,y,r); } \
-	else FAIL_ZER("integer division")
-#define OP_ULLONG_FLOORDIV_ZER(x,y,r) \
-	if ((y)) { OP_ULLONG_FLOORDIV(x,y,r); } \
-	else FAIL_ZER("unsigned integer division")
-
-#define OP_INT_FLOORDIV_OVF_ZER(x,y,r) \
-	if ((y)) { OP_INT_FLOORDIV_OVF(x,y,r); } \
-	else FAIL_ZER("integer division")
+#define OP_INT_FLOORDIV_OVF(x,y,r)                      \
+	if ((y) == -1 && (x) == LONG_MIN)               \
+	    { FAIL_OVF("integer division"); r=0; }      \
+	else                                            \
+	    r = (x) / (y)
+#define OP_LLONG_FLOORDIV_OVF(x,y,r)                    \
+	if ((y) == -1 && (x) == LLONG_MIN)              \
+	    { FAIL_OVF("integer division"); r=0; }      \
+	else                                            \
+	    r = (x) / (y)
+
+#define OP_INT_FLOORDIV_ZER(x,y,r)                      \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer division"); r=0; }      \
+	else                                            \
+	    r = (x) / (y)
+#define OP_UINT_FLOORDIV_ZER(x,y,r)                             \
+	if ((y) == 0)                                           \
+	    { FAIL_ZER("unsigned integer division"); r=0; }     \
+	else                                                    \
+	    r = (x) / (y)
+#define OP_LLONG_FLOORDIV_ZER(x,y,r)                    \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer division"); r=0; }      \
+	else                                            \
+	    r = (x) / (y)
+#define OP_ULLONG_FLOORDIV_ZER(x,y,r)                           \
+	if ((y) == 0)                                           \
+	    { FAIL_ZER("unsigned integer division"); r=0; }     \
+	else                                                    \
+	    r = (x) / (y)
+
+#define OP_INT_FLOORDIV_OVF_ZER(x,y,r)                  \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer division"); r=0; }      \
+	else                                            \
+	    { OP_INT_FLOORDIV_OVF(x,y,r); }
+#define OP_LLONG_FLOORDIV_OVF_ZER(x,y,r)                \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer division"); r=0; }      \
+	else                                            \
+	    { OP_LLONG_FLOORDIV_OVF(x,y,r); }
 
 /* modulus */
 
@@ -158,27 +166,47 @@
 #define OP_LLONG_MOD(x,y,r)   r = (x) % (y)
 #define OP_ULLONG_MOD(x,y,r)  r = (x) % (y)
 
-#define OP_INT_MOD_OVF(x,y,r) \
-	if ((y) == -1 && (x) == LONG_MIN) \
-            { FAIL_OVF("integer modulo"); }\
-        else OP_INT_MOD(x,y,r)
-
-#define OP_INT_MOD_ZER(x,y,r) \
-	if ((y)) { OP_INT_MOD(x,y,r); } \
-	else FAIL_ZER("integer modulo")
-#define OP_UINT_MOD_ZER(x,y,r) \
-	if ((y)) { OP_UINT_MOD(x,y,r); } \
-	else FAIL_ZER("unsigned integer modulo")
-#define OP_LLONG_MOD_ZER(x,y,r) \
-	if ((y)) { OP_LLONG_MOD(x,y,r); } \
-	else FAIL_ZER("integer modulo")
-#define OP_ULLONG_MOD_ZER(x,y,r) \
-	if ((y)) { OP_ULLONG_MOD(x,y,r); } \
-	else FAIL_ZER("integer modulo")
-
-#define OP_INT_MOD_OVF_ZER(x,y,r) \
-	if ((y)) { OP_INT_MOD_OVF(x,y,r); } \
-	else FAIL_ZER("integer modulo")
+#define OP_INT_MOD_OVF(x,y,r)                           \
+	if ((y) == -1 && (x) == LONG_MIN)               \
+	    { FAIL_OVF("integer modulo"); r=0; }        \
+	else                                            \
+	    r = (x) % (y)
+#define OP_LLONG_MOD_OVF(x,y,r)                         \
+	if ((y) == -1 && (x) == LLONG_MIN)              \
+	    { FAIL_OVF("integer modulo"); r=0; }        \
+	else                                            \
+	    r = (x) % (y)
+#define OP_INT_MOD_ZER(x,y,r)                           \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer modulo"); r=0; }        \
+	else                                            \
+	    r = (x) % (y)
+#define OP_UINT_MOD_ZER(x,y,r)                                  \
+	if ((y) == 0)                                           \
+	    { FAIL_ZER("unsigned integer modulo"); r=0; }       \
+	else                                                    \
+	    r = (x) % (y)
+#define OP_LLONG_MOD_ZER(x,y,r)                         \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer modulo"); r=0; }        \
+	else                                            \
+	    r = (x) % (y)
+#define OP_ULLONG_MOD_ZER(x,y,r)                                \
+	if ((y) == 0)                                           \
+	    { FAIL_ZER("unsigned integer modulo"); r=0; }       \
+	else                                                    \
+	    r = (x) % (y)
+
+#define OP_INT_MOD_OVF_ZER(x,y,r)                       \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer modulo"); r=0; }        \
+	else                                            \
+	    { OP_INT_MOD_OVF(x,y,r); }
+#define OP_LLONG_MOD_OVF_ZER(x,y,r)                     \
+	if ((y) == 0)                                   \
+	    { FAIL_ZER("integer modulo"); r=0; }        \
+	else                                            \
+	    { OP_LLONG_MOD_OVF(x,y,r); }
 
 /* bit operations */
 
@@ -208,31 +236,30 @@
 
 /* _________________ certain implementations __________________ */
 
-#if !OP_INT_MUL_OVF_LL
 /* adjusted from intobject.c, Python 2.3.3 */
 
 /* prototypes */
 
-int op_int_mul_ovf(long a, long b, long *longprod);
+long long op_llong_mul_ovf(long long a, long long b);
 
 /* implementations */
 
 #ifndef PYPY_NOT_MAIN_FILE
 
-int
-op_int_mul_ovf(long a, long b, long *longprod)
+long long op_llong_mul_ovf(long long a, long long b)
 {
 	double doubled_longprod;	/* (double)longprod */
 	double doubleprod;		/* (double)a * (double)b */
+	long long longprod;
 
-	*longprod = a * b;
+	longprod = a * b;
 	doubleprod = (double)a * (double)b;
-	doubled_longprod = (double)*longprod;
+	doubled_longprod = (double)longprod;
 
 	/* Fast path for normal case:  small multiplicands, and no info
 	   is lost in either method. */
 	if (doubled_longprod == doubleprod)
-		return 1;
+		return longprod;
 
 	/* Somebody somewhere lost info.  Close enough, or way off?  Note
 	   that a != 0 and b != 0 (else doubled_longprod == doubleprod == 0).
@@ -247,15 +274,15 @@
 		/* absdiff/absprod <= 1/32 iff
 		   32 * absdiff <= absprod -- 5 good bits is "close enough" */
 		if (32.0 * absdiff <= absprod)
-			return 1;
-		return 0;
+			return longprod;
+
+		FAIL_OVF("integer multiplication");
+		return -1;
 	}
 }
 
 #endif /* PYPY_NOT_MAIN_FILE */
 
-#endif /* !OP_INT_MUL_OVF_LL */
-
 /* implementations */
 
 #define OP_UINT_IS_TRUE OP_INT_IS_TRUE



More information about the Pypy-commit mailing list