[pypy-svn] r22915 - in pypy/dist/pypy/translator: backendopt c/src c/test

ericvrp at codespeak.net ericvrp at codespeak.net
Tue Jan 31 23:52:10 CET 2006


Author: ericvrp
Date: Tue Jan 31 23:51:48 2006
New Revision: 22915

Modified:
   pypy/dist/pypy/translator/backendopt/all.py
   pypy/dist/pypy/translator/c/src/int.h
   pypy/dist/pypy/translator/c/test/test_typed.py
Log:
Disabling raisingop2direct_call transformation until it no longer breaks translation.
Reverting int.h until that time too.


Modified: pypy/dist/pypy/translator/backendopt/all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/all.py	(original)
+++ pypy/dist/pypy/translator/backendopt/all.py	Tue Jan 31 23:51:48 2006
@@ -9,7 +9,7 @@
 from pypy.translator.backendopt.escape import malloc_to_stack
 
 
-def backend_optimizations(translator, raisingop2direct_call_all=True,
+def backend_optimizations(translator, raisingop2direct_call_all=False,
                                       inline_threshold=1,
                                       mallocs=True,
                                       ssa_form=True,

Modified: pypy/dist/pypy/translator/c/src/int.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/int.h	(original)
+++ pypy/dist/pypy/translator/c/src/int.h	Tue Jan 31 23:51:48 2006
@@ -1,3 +1,4 @@
+
 /************************************************************/
  /***  C header subsection: operations between ints        ***/
 
@@ -11,9 +12,19 @@
 
 #define OP_INT_NEG(x,r,err)    r = -(x)
 
+#define OP_INT_NEG_OVF(x,r,err) \
+	OP_INT_NEG(x,r,err); \
+	if ((x) >= 0 || (x) != -(x)); \
+	else FAIL_OVF(err, "integer negate")
+
 #define OP_INT_ABS(x,r,err)    r = (x) >= 0 ? x : -(x)
 #define OP_UINT_ABS(x,r,err)   r = (x)
 
+#define OP_INT_ABS_OVF(x,r,err) \
+	OP_INT_ABS(x,r,err); \
+	if ((x) >= 0 || (x) != -(x)); \
+	else FAIL_OVF(err, "integer absolute")
+
 /***  binary operations ***/
 
 #define OP_INT_EQ(x,y,r,err)	  r = ((x) == (y))
@@ -30,10 +41,37 @@
 
 #define OP_INT_ADD(x,y,r,err)     r = (x) + (y)
 
+#define OP_INT_ADD_OVF(x,y,r,err) \
+	OP_INT_ADD(x,y,r,err); \
+	if ((r^(x)) >= 0 || (r^(y)) >= 0); \
+	else FAIL_OVF(err, "integer addition")
+
 #define OP_INT_SUB(x,y,r,err)     r = (x) - (y)
 
+#define OP_INT_SUB_OVF(x,y,r,err) \
+	OP_INT_SUB(x,y,r,err); \
+	if ((r^(x)) >= 0 || (r^~(y)) >= 0); \
+	else FAIL_OVF(err, "integer subtraction")
+
 #define OP_INT_MUL(x,y,r,err)     r = (x) * (y)
 
+#ifndef HAVE_LONG_LONG
+
+#define OP_INT_MUL_OVF(x,y,r,err) \
+	if (op_int_mul_ovf(x,y,&r)); \
+	else FAIL_OVF(err, "integer multiplication")
+
+#else
+
+#define OP_INT_MUL_OVF(x,y,r,err) \
+	{ \
+		PY_LONG_LONG lr = (PY_LONG_LONG)(x) * (PY_LONG_LONG)(y); \
+		r = (long)lr; \
+		if ((PY_LONG_LONG)r == lr); \
+		else FAIL_OVF(err, "integer multiplication"); \
+	}
+#endif
+
 /* shifting */
 
 /* NB. shifting has same limitations as C: the shift count must be
@@ -44,18 +82,68 @@
 #define OP_INT_LSHIFT(x,y,r,err)    r = (x) << (y)
 #define OP_UINT_LSHIFT(x,y,r,err)   r = (x) << (y)
 
+#define OP_INT_LSHIFT_OVF(x,y,r,err) \
+	OP_INT_LSHIFT(x,y,r,err); \
+	if ((x) != Py_ARITHMETIC_RIGHT_SHIFT(long, r, (y))) \
+		FAIL_OVF(err, "x<<y loosing bits or changing sign")
+
+/* the safe value-checking version of the above macros */
+
+#define OP_INT_RSHIFT_VAL(x,y,r,err) \
+	if ((y) >= 0) { OP_INT_RSHIFT(x,y,r,err); } \
+	else FAIL_VAL(err, "negative shift count")
+
+#define OP_INT_LSHIFT_VAL(x,y,r,err) \
+	if ((y) >= 0) { OP_INT_LSHIFT(x,y,r,err); } \
+	else FAIL_VAL(err, "negative shift count")
+
+#define OP_INT_LSHIFT_OVF_VAL(x,y,r,err) \
+	if ((y) >= 0) { OP_INT_LSHIFT_OVF(x,y,r,err); } \
+	else FAIL_VAL(err, "negative shift count")
+
+
 /* floor division */
 
-/* NB: OP_INT_FLOORDIV and OP_INT_MOD are the operations that end up in the graphs
-       after the raisingop2direct_call transformation has been done. */
-#define OP_INT_FLOORDIV(x,y,r,err)    r = (x) / (y)
+#define OP_INT_FLOORDIV(x,y,r,err)    r = op_divmod_adj(x, y, NULL)
 #define OP_UINT_FLOORDIV(x,y,r,err)   r = (x) / (y)
 
+#define OP_INT_FLOORDIV_OVF(x,y,r,err) \
+	if ((y) == -1 && (x) < 0 && ((unsigned long)(x) << 1) == 0) \
+		FAIL_OVF(err, "integer division"); \
+	OP_INT_FLOORDIV(x,y,r,err)
+
+#define OP_INT_FLOORDIV_ZER(x,y,r,err) \
+	if ((y)) { OP_INT_FLOORDIV(x,y,r,err); } \
+	else FAIL_ZER(err, "integer division")
+#define OP_UINT_FLOORDIV_ZER(x,y,r,err) \
+	if ((y)) { OP_UINT_FLOORDIV(x,y,r,err); } \
+	else FAIL_ZER(err, "unsigned integer division")
+
+#define OP_INT_FLOORDIV_OVF_ZER(x,y,r,err) \
+	if ((y)) { OP_INT_FLOORDIV_OVF(x,y,r,err); } \
+	else FAIL_ZER(err, "integer division")
+
 /* modulus */
 
-#define OP_INT_MOD(x,y,r,err)     r = (x) % (y)
+#define OP_INT_MOD(x,y,r,err)     op_divmod_adj(x, y, &r)
 #define OP_UINT_MOD(x,y,r,err)    r = (x) % (y)
 
+#define OP_INT_MOD_OVF(x,y,r,err) \
+	if ((y) == -1 && (x) < 0 && ((unsigned long)(x) << 1) == 0) \
+		FAIL_OVF(err, "integer modulo"); \
+	OP_INT_MOD(x,y,r,err)
+
+#define OP_INT_MOD_ZER(x,y,r,err) \
+	if ((y)) { OP_INT_MOD(x,y,r,err); } \
+	else FAIL_ZER(err, "integer modulo")
+#define OP_UINT_MOD_ZER(x,y,r,err) \
+	if ((y)) { OP_UINT_MOD(x,y,r,err); } \
+	else FAIL_ZER(err, "unsigned integer modulo")
+
+#define OP_INT_MOD_OVF_ZER(x,y,r,err) \
+	if ((y)) { OP_INT_MOD_OVF(x,y,r,err); } \
+	else FAIL_ZER(err, "integer modulo")
+
 /* bit operations */
 
 #define OP_INT_AND(x,y,r,err)     r = (x) & (y)
@@ -84,6 +172,85 @@
 
 /* _________________ certain implementations __________________ */
 
+#ifndef HAVE_LONG_LONG
+/* adjusted from intobject.c, Python 2.3.3 */
+
+/* prototypes */
+
+op_int_mul_ovf(long a, long b, long *longprod);
+
+/* implementations */
+
+#ifndef PYPY_NOT_MAIN_FILE
+
+int
+op_int_mul_ovf(long a, long b, long *longprod)
+{
+	double doubled_longprod;	/* (double)longprod */
+	double doubleprod;		/* (double)a * (double)b */
+
+	*longprod = a * b;
+	doubleprod = (double)a * (double)b;
+	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;
+
+	/* Somebody somewhere lost info.  Close enough, or way off?  Note
+	   that a != 0 and b != 0 (else doubled_longprod == doubleprod == 0).
+	   The difference either is or isn't significant compared to the
+	   true value (of which doubleprod is a good approximation).
+	*/
+	{
+		const double diff = doubled_longprod - doubleprod;
+		const double absdiff = diff >= 0.0 ? diff : -diff;
+		const double absprod = doubleprod >= 0.0 ? doubleprod :
+							  -doubleprod;
+		/* absdiff/absprod <= 1/32 iff
+		   32 * absdiff <= absprod -- 5 good bits is "close enough" */
+		if (32.0 * absdiff <= absprod)
+			return 1;
+		return 0;
+	}
+}
+
+#endif /* PYPY_NOT_MAIN_FILE */
+
+#endif /* HAVE_LONG_LONG */
+
+/* XXX we might probe the compiler whether it does what we want */
+
+/* prototypes */
+
+long op_divmod_adj(long x, long y, long *p_rem);
+
+/* implementations */
+
+#ifndef PYPY_NOT_MAIN_FILE
+
+long op_divmod_adj(long x, long y, long *p_rem)
+{
+	long xdivy = x / y;
+	long xmody = x - xdivy * y;
+	/* If the signs of x and y differ, and the remainder is non-0,
+	 * C89 doesn't define whether xdivy is now the floor or the
+	 * ceiling of the infinitely precise quotient.  We want the floor,
+	 * and we have it iff the remainder's sign matches y's.
+	 */
+	if (xmody && ((y ^ xmody) < 0) /* i.e. and signs differ */) {
+		xmody += y;
+		--xdivy;
+		assert(xmody && ((y ^ xmody) >= 0));
+	}
+	if (p_rem)
+		*p_rem = xmody;
+	return xdivy;
+}
+
+#endif /* PYPY_NOT_MAIN_FILE */
+
 /* no editing below this point */
 /* following lines are generated by mkuint.py */
 

Modified: pypy/dist/pypy/translator/c/test/test_typed.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_typed.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_typed.py	Tue Jan 31 23:51:48 2006
@@ -14,7 +14,7 @@
     def process(self, t):
         _TestAnnotatedTestCase.process(self, t)
         t.buildrtyper().specialize()
-        raisingop2direct_call(t)
+        #raisingop2direct_call(t)
 
     def test_call_five(self):
         # --  the result of call_five() isn't a real list, but an rlist
@@ -223,7 +223,7 @@
         raises(OverflowError, fn, n, 5)
 
     def test_int_mod_ovf_zer(self):
-        py.test.skip("XXX does not annotate anymore after raisingops2direct_call transformation")
+        #py.test.skip("XXX does not annotate anymore after raisingops2direct_call transformation")
         fn = self.getcompiled(snippet.mod_func)
         raises(OverflowError, fn, -1)
         raises(ZeroDivisionError, fn, 0)



More information about the Pypy-commit mailing list