[pypy-svn] pypy default: Remove the scary sequence of operations for int_mod, and

arigo commits-noreply at bitbucket.org
Fri Mar 25 17:39:57 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r42939:e43b8c3ccf87
Date: 2011-03-25 17:25 +0100
http://bitbucket.org/pypy/pypy/changeset/e43b8c3ccf87/

Log:	Remove the scary sequence of operations for int_mod, and replace it
	with a call to a helper. The helper contains an 'if:else:' path,
	but it should generate far better code, both normally and when
	JITted.

diff --git a/pypy/rpython/test/test_rint.py b/pypy/rpython/test/test_rint.py
--- a/pypy/rpython/test/test_rint.py
+++ b/pypy/rpython/test/test_rint.py
@@ -266,6 +266,8 @@
                 x = inttype(random.randint(-100000, 100000))
                 y = inttype(random.randint(-100000, 100000))
                 if not y: continue
+                if (i & 31) == 0:
+                    x = (x//y) * y      # case where x is exactly divisible by y
                 res = self.interpret(d, [x, y])
                 assert res == d(x, y)
 
@@ -276,6 +278,8 @@
                 x = inttype(random.randint(-100000, 100000))
                 y = inttype(random.randint(-100000, 100000))
                 if not y: continue
+                if (i & 31) == 0:
+                    x = (x//y) * y      # case where x is exactly divisible by y
                 res = self.interpret(m, [x, y])
                 assert res == m(x, y)
 

diff --git a/pypy/rpython/rint.py b/pypy/rpython/rint.py
--- a/pypy/rpython/rint.py
+++ b/pypy/rpython/rint.py
@@ -239,25 +239,26 @@
             v_res = hop.genop(prefix + 'sub', [v_res, v_corr],
                               resulttype=repr)
         elif op == 'mod':
-            # return r + y*(((x^y)<0)&(r!=0));
-            v_xor = hop.genop(prefix + 'xor', vlist,
-                            resulttype=repr)
-            v_xor_le = hop.genop(prefix + 'lt', [v_xor, c_zero],
-                               resulttype=Bool)
-            v_xor_le = hop.llops.convertvar(v_xor_le, bool_repr, repr)
-            v_mod_ne = hop.genop(prefix + 'ne', [v_res, c_zero],
-                               resulttype=Bool)
-            v_mod_ne = hop.llops.convertvar(v_mod_ne, bool_repr, repr)
-            v_corr1 = hop.genop(prefix + 'and', [v_xor_le, v_mod_ne],
-                             resulttype=repr)
-            v_corr = hop.genop(prefix + 'mul', [v_corr1, vlist[1]],
-                             resulttype=repr)
-            v_res = hop.genop(prefix + 'add', [v_res, v_corr],
-                              resulttype=repr)
+            llfunc = globals()['ll_correct_' + prefix + 'mod']
+            v_res = hop.gendirectcall(llfunc, vlist[1], v_res)
     v_res = hop.llops.convertvar(v_res, repr, r_result)
     return v_res
 
 
+INT_BITS_1 = r_int.BITS - 1
+LLONG_BITS_1 = r_longlong.BITS - 1
+
+def ll_correct_int_mod(y, r):
+    if y < 0: u = -r
+    else:     u = r
+    return r + (y & (u >> INT_BITS_1))
+
+def ll_correct_llong_mod(y, r):
+    if y < 0: u = -r
+    else:     u = r
+    return r + (y & (u >> LLONG_BITS_1))
+
+
 #Helper functions for comparisons
 
 def _rtype_compare_template(hop, func):


More information about the Pypy-commit mailing list