Author: Armin Rigo <ar...@tunes.org>
Branch: remove-raisingops
Changeset: r84723:d193b0c27d68
Date: 2016-05-27 08:59 +0200
http://bitbucket.org/pypy/pypy/changeset/d193b0c27d68/

Log:    Reintroduce the optimization in int_floordiv and int_mod: avoids the
        sign-checking and fixing of the result in case the two arguments are
        known to be positive

diff --git a/rpython/rtyper/rint.py b/rpython/rtyper/rint.py
--- a/rpython/rtyper/rint.py
+++ b/rpython/rtyper/rint.py
@@ -370,7 +370,10 @@
     else:
         hop.exception_cannot_occur()
 
-    llfunc = globals()['ll_' + repr.opprefix + func]
+    funcname = 'll_' + repr.opprefix + func
+    llfunc = globals()[funcname]
+    if all(s_arg.nonneg for s_arg in hop.args_s):
+        llfunc = globals().get(funcname + '_nonnegargs', llfunc)
     v_result = hop.gendirectcall(llfunc, *vlist)
     assert v_result.concretetype == repr.lowleveltype
     return v_result
@@ -396,6 +399,13 @@
     else:     u = x - p
     return r + (u >> INT_BITS_1)
 
+@jit.oopspec("int.py_div(x, y)")
+def ll_int_floordiv_nonnegargs(x, y):
+    from rpython.rlib.debug import ll_assert
+    r = llop.int_floordiv(Signed, x, y)            # <= truncates like in C
+    ll_assert(r >= 0, "int_floordiv_nonnegargs(): one arg is negative")
+    return r
+
 def ll_int_floordiv_zer(x, y):
     if y == 0:
         raise ZeroDivisionError("integer division")
@@ -473,6 +483,13 @@
     else:     u = r
     return r + (y & (u >> INT_BITS_1))
 
+@jit.oopspec("int.py_mod(x, y)")
+def ll_int_mod_nonnegargs(x, y):
+    from rpython.rlib.debug import ll_assert
+    r = llop.int_mod(Signed, x, y)                 # <= truncates like in C
+    ll_assert(r >= 0, "int_mod_nonnegargs(): one arg is negative")
+    return r
+
 def ll_int_mod_zer(x, y):
     if y == 0:
         raise ZeroDivisionError
diff --git a/rpython/rtyper/test/test_rint.py b/rpython/rtyper/test/test_rint.py
--- a/rpython/rtyper/test/test_rint.py
+++ b/rpython/rtyper/test/test_rint.py
@@ -390,6 +390,22 @@
         res = self.interpret(f, [sys.maxint])
         assert res == 0
 
+    def test_int_floordiv_nonnegargs(self):
+        def f(x, y):
+            assert x >= 0
+            assert y >= 0
+            return x // y
+        res = self.interpret(f, [1234567, 123])
+        assert res == 1234567 // 123
+
+    def test_int_mod_nonnegargs(self):
+        def f(x, y):
+            assert x >= 0
+            assert y >= 0
+            return x % y
+        res = self.interpret(f, [1234567, 123])
+        assert res == 1234567 % 123
+
     def test_cast_to_float_exc_check(self):
         def f(x):
             try:
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to