[pypy-svn] r47521 - in pypy/dist/pypy: rpython rpython/lltypesystem rpython/test translator/c/src translator/cli translator/jvm translator/oosupport/test_template
arigo at codespeak.net
arigo at codespeak.net
Wed Oct 17 22:01:32 CEST 2007
Author: arigo
Date: Wed Oct 17 22:01:30 2007
New Revision: 47521
Modified:
pypy/dist/pypy/rpython/llinterp.py
pypy/dist/pypy/rpython/lltypesystem/lloperation.py
pypy/dist/pypy/rpython/rint.py
pypy/dist/pypy/rpython/test/test_rint.py
pypy/dist/pypy/translator/c/src/int.h
pypy/dist/pypy/translator/cli/opcodes.py
pypy/dist/pypy/translator/jvm/opcodes.py
pypy/dist/pypy/translator/oosupport/test_template/overflow.py
Log:
Experimental. An operation 'int_add_nonneg_ovf' which is like
'int_add_ovf' but can assume that the 2nd argument is nonneg. In genc
we can test that much more simply, and somehow I expect this case to be
relatively common in the ll helpers for RPython data structures.
Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py (original)
+++ pypy/dist/pypy/rpython/llinterp.py Wed Oct 17 22:01:30 2007
@@ -969,6 +969,11 @@
_makefunc2('op_ullong_lshift_val', '<<', 'r_ulonglong')
_makefunc2('op_ullong_rshift_val', '>>', 'r_ulonglong')
+ def op_int_add_nonneg_ovf(self, x, y):
+ if isinstance(y, int):
+ assert y >= 0
+ return self.op_int_add_ovf(x, y)
+
def op_cast_float_to_int(self, f):
assert type(f) is float
try:
Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py Wed Oct 17 22:01:30 2007
@@ -186,6 +186,8 @@
'int_xor': LLOp(canfold=True),
'int_add_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
+ 'int_add_nonneg_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
+ # ^^^ more efficient version when 2nd arg is nonneg
'int_sub_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
'int_mul_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
'int_floordiv_ovf': LLOp(canraise=(OverflowError,), tryfold=True),
Modified: pypy/dist/pypy/rpython/rint.py
==============================================================================
--- pypy/dist/pypy/rpython/rint.py (original)
+++ pypy/dist/pypy/rpython/rint.py Wed Oct 17 22:01:30 2007
@@ -57,7 +57,15 @@
rtype_inplace_add = rtype_add
def rtype_add_ovf(_, hop):
- return _rtype_template(hop, 'add_ovf')
+ func = 'add_ovf'
+ if hop.r_result.opprefix == 'int_':
+ if hop.args_s[1].nonneg:
+ func = 'add_nonneg_ovf'
+ elif hop.args_s[0].nonneg:
+ hop = hop.copy()
+ hop.swap_fst_snd_args()
+ func = 'add_nonneg_ovf'
+ return _rtype_template(hop, func)
def rtype_sub(_, hop):
return _rtype_template(hop, 'sub')
@@ -183,7 +191,7 @@
appendix = op_appendices[implicit_exc]
func += '_' + appendix
- r_result = hop.rtyper.makerepr(hop.s_result)
+ r_result = hop.r_result
if r_result.lowleveltype == Bool:
repr = signed_repr
else:
Modified: pypy/dist/pypy/rpython/test/test_rint.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rint.py (original)
+++ pypy/dist/pypy/rpython/test/test_rint.py Wed Oct 17 22:01:30 2007
@@ -309,6 +309,24 @@
res2 = self.interpret(func, [x, y])
assert res1 == res2
+ def test_int_add_nonneg_ovf(self):
+ def f(x):
+ try:
+ a = ovfcheck(x + 50)
+ except OverflowError:
+ return 0
+ try:
+ a += ovfcheck(100 + x)
+ except OverflowError:
+ return 1
+ return a
+ res = self.interpret(f, [-3])
+ assert res == 144
+ res = self.interpret(f, [sys.maxint-50])
+ assert res == 1
+ res = self.interpret(f, [sys.maxint])
+ assert res == 0
+
class TestLLtype(BaseTestRint, LLRtypeMixin):
pass
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 Wed Oct 17 22:01:30 2007
@@ -56,6 +56,11 @@
if ((r^(x)) >= 0 || (r^(y)) >= 0); \
else FAIL_OVF("integer addition")
+#define OP_INT_ADD_NONNEG_OVF(x,y,r) /* y can be assumed >= 0 */ \
+ OP_INT_ADD(x,y,r); \
+ if (r >= (x)); \
+ else FAIL_OVF("integer addition")
+
#define OP_INT_SUB(x,y,r) r = (x) - (y)
#define OP_INT_SUB_OVF(x,y,r) \
Modified: pypy/dist/pypy/translator/cli/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/cli/opcodes.py (original)
+++ pypy/dist/pypy/translator/cli/opcodes.py Wed Oct 17 22:01:30 2007
@@ -104,6 +104,7 @@
'int_rshift': 'shr',
'int_xor': 'xor',
'int_add_ovf': _check_ovf('add.ovf'),
+ 'int_add_nonneg_ovf': _check_ovf('add.ovf'),
'int_sub_ovf': _check_ovf('sub.ovf'),
'int_mul_ovf': _check_ovf('mul.ovf'),
'int_floordiv_ovf': 'div', # these can't overflow!
Modified: pypy/dist/pypy/translator/jvm/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/opcodes.py (original)
+++ pypy/dist/pypy/translator/jvm/opcodes.py Wed Oct 17 22:01:30 2007
@@ -111,6 +111,7 @@
'int_rshift': jvmgen.ISHR,
'int_xor': jvmgen.IXOR,
'int_add_ovf': jvmgen.IADDOVF,
+ 'int_add_nonneg_ovf': jvmgen.IADDOVF,
'int_sub_ovf': jvmgen.ISUBOVF,
'int_mul_ovf': jvmgen.IMULOVF,
'int_floordiv_ovf': jvmgen.IDIV, # these can't overflow!
Modified: pypy/dist/pypy/translator/oosupport/test_template/overflow.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/test_template/overflow.py (original)
+++ pypy/dist/pypy/translator/oosupport/test_template/overflow.py Wed Oct 17 22:01:30 2007
@@ -16,6 +16,14 @@
return 42
self.check(fn, [sys.maxint, 1])
+ def test_add2(self):
+ def fn(x):
+ try:
+ return ovfcheck(x+1) # special 'int_add_nonneg_ovf' operation
+ except OverflowError:
+ return 42
+ self.check(fn, [sys.maxint])
+
def test_sub(self):
def fn(x, y):
try:
More information about the Pypy-commit
mailing list