[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