[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