1. Pypy
  2. Untitled project
  3. pypy

Commits

Hakan Ardo  committed 90eac6f Merge

Some integer optimizations and modificatiosn to the integer division implementation to allow the jit to optimize it better in some cases.

  • Participants
  • Parent commits 20676e2, 46f3657
  • Branches default

Comments (0)

Files changed (7)

File pypy/jit/codewriter/support.py

View file
  • Ignore whitespace
 def _ll_2_int_floordiv_ovf_zer(x, y):
     if y == 0:
         raise ZeroDivisionError
-    if ((x + sys.maxint) & y) == -1:    # detect "x = -sys.maxint-1, y = -1".
+    if x == -sys.maxint - 1 and y == -1:
         raise OverflowError
     return llop.int_floordiv(lltype.Signed, x, y)
 
 def _ll_2_int_floordiv_ovf(x, y):
-    if ((x + sys.maxint) & y) == -1:    # detect "x = -sys.maxint-1, y = -1".
+    if x == -sys.maxint - 1 and y == -1:        
         raise OverflowError
     return llop.int_floordiv(lltype.Signed, x, y)
 
 def _ll_2_int_mod_ovf_zer(x, y):
     if y == 0:
         raise ZeroDivisionError
-    if ((x + sys.maxint) & y) == -1:    # detect "x = -sys.maxint-1, y = -1".
+    if x == -sys.maxint - 1 and y == -1:
         raise OverflowError
     return llop.int_mod(lltype.Signed, x, y)
 
 def _ll_2_int_mod_ovf(x, y):
-    if ((x + sys.maxint) & y) == -1:    # detect "x = -sys.maxint-1, y = -1".
+    if x == -sys.maxint - 1 and y == -1:
         raise OverflowError
     return llop.int_mod(lltype.Signed, x, y)
 

File pypy/jit/metainterp/optimizeopt/intbounds.py

View file
  • Ignore whitespace
     optimize_GUARD_FALSE = optimize_GUARD_TRUE
     optimize_GUARD_VALUE = optimize_GUARD_TRUE
 
+    def optimize_INT_XOR(self, op):
+        v1 = self.getvalue(op.getarg(0))
+        v2 = self.getvalue(op.getarg(1))
+        if v1 is v2:
+            self.make_constant_int(op.result, 0)
+            return
+        self.emit_operation(op)
+        if v1.intbound.known_ge(IntBound(0, 0)) and \
+           v2.intbound.known_ge(IntBound(0, 0)):
+            r = self.getvalue(op.result)
+            r.intbound.make_ge(IntLowerBound(0))
+
     def optimize_INT_AND(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))
         r = self.getvalue(op.result)
         r.intbound.intersect(v1.intbound.mul_bound(v2.intbound))
 
+    def optimize_INT_FLOORDIV(self, op):
+        v1 = self.getvalue(op.getarg(0))
+        v2 = self.getvalue(op.getarg(1))
+        self.emit_operation(op)
+        if v1.intbound.known_ge(IntBound(0, 0)) and \
+           v2.intbound.known_ge(IntBound(0, 0)):
+            r = self.getvalue(op.result)
+            r.intbound.make_ge(IntLowerBound(0))
+
     def optimize_INT_ADD_OVF(self, op):
         v1 = self.getvalue(op.getarg(0))
         v2 = self.getvalue(op.getarg(1))

File pypy/jit/metainterp/optimizeopt/optimizer.py

View file
  • Ignore whitespace
             box = self.box
             assert isinstance(box, Const)
             return box.nonnull()
+        elif self.intbound:
+            if self.intbound.known_gt(IntBound(0, 0)) or \
+               self.intbound.known_lt(IntBound(0, 0)):
+                return True
+            else:
+                return False
         else:
             return False
 

File pypy/jit/metainterp/optimizeopt/unroll.py

  • Ignore whitespace
File contents unchanged.

File pypy/jit/metainterp/test/test_optimizeopt.py

View file
  • Ignore whitespace
         """
         self.optimize_loop(ops, expected)
 
+    def test_bound_xor(self):
+        ops = """
+        [i0, i1, i2]
+        it1 = int_ge(i1, 0)
+        guard_true(it1) []
+        it2 = int_gt(i2, 0)
+        guard_true(it2) []
+        ix1 = int_xor(i0, i0)
+        ix1t = int_ge(ix1, 0)
+        guard_true(ix1t) []
+        ix2 = int_xor(i0, i1)
+        ix2t = int_ge(ix2, 0)
+        guard_true(ix2t) []
+        ix3 = int_xor(i1, i0)
+        ix3t = int_ge(ix3, 0)
+        guard_true(ix3t) []
+        ix4 = int_xor(i1, i2)
+        ix4t = int_ge(ix4, 0)
+        guard_true(ix4t) []
+        jump(i0, i1, i2)
+        """
+        preamble = """
+        [i0, i1, i2]
+        it1 = int_ge(i1, 0)
+        guard_true(it1) []
+        it2 = int_gt(i2, 0)
+        guard_true(it2) []
+        ix2 = int_xor(i0, i1)
+        ix2t = int_ge(ix2, 0)
+        guard_true(ix2t) []
+        ix3 = int_xor(i1, i0)
+        ix3t = int_ge(ix3, 0)
+        guard_true(ix3t) []
+        ix4 = int_xor(i1, i2)
+        jump(i0, i1, i2)
+        """
+        expected = """
+        [i0, i1, i2]
+        jump(i0, i1, i2)        
+        """
+        self.optimize_loop(ops, expected, preamble)
+
+    def test_bound_floordiv(self):
+        ops = """
+        [i0, i1, i2]
+        it1 = int_ge(i1, 0)
+        guard_true(it1) []
+        it2 = int_gt(i2, 0)
+        guard_true(it2) []
+        ix2 = int_floordiv(i0, i1)
+        ix2t = int_ge(ix2, 0)
+        guard_true(ix2t) []
+        ix3 = int_floordiv(i1, i0)
+        ix3t = int_ge(ix3, 0)
+        guard_true(ix3t) []
+        ix4 = int_floordiv(i1, i2)
+        ix4t = int_ge(ix4, 0)
+        guard_true(ix4t) []
+        jump(i0, i1, i2)
+        """
+        preamble = """
+        [i0, i1, i2]
+        it1 = int_ge(i1, 0)
+        guard_true(it1) []
+        it2 = int_gt(i2, 0)
+        guard_true(it2) []
+        ix2 = int_floordiv(i0, i1)
+        ix2t = int_ge(ix2, 0)
+        guard_true(ix2t) []
+        ix3 = int_floordiv(i1, i0)
+        ix3t = int_ge(ix3, 0)
+        guard_true(ix3t) []
+        ix4 = int_floordiv(i1, i2)
+        jump(i0, i1, i2)
+        """
+        expected = """
+        [i0, i1, i2]
+        jump(i0, i1, i2)        
+        """
+        self.optimize_loop(ops, expected, preamble)
+
+    def test_bound_int_is_zero(self):
+        ops = """
+        [i1, i2a, i2b, i2c]
+        i3 = int_is_zero(i1)
+        i4 = int_gt(i2a, 7)
+        guard_true(i4) []
+        i5 = int_is_zero(i2a)
+        guard_false(i5) []
+        i6 = int_le(i2b, -7)
+        guard_true(i6) []
+        i7 = int_is_zero(i2b)
+        guard_false(i7) []
+        i8 = int_gt(i2c, -7)
+        guard_true(i8) []
+        i9 = int_is_zero(i2c)        
+        jump(i1, i2a, i2b, i2c)
+        """
+        preamble = """
+        [i1, i2a, i2b, i2c]
+        i3 = int_is_zero(i1)
+        i4 = int_gt(i2a, 7)
+        guard_true(i4) []
+        i6 = int_le(i2b, -7)
+        guard_true(i6) []
+        i8 = int_gt(i2c, -7)
+        guard_true(i8) []
+        i9 = int_is_zero(i2c)        
+        jump(i1, i2a, i2b, i2c)
+        """
+        expected = """
+        [i0, i1, i2, i3]
+        jump(i0, i1, i2, i3)        
+        """
+        self.optimize_loop(ops, expected, preamble)
+
+    def test_division(self):
+        ops = """
+        [i7, i6, i8]
+        it1 = int_gt(i7, 0)
+        guard_true(it1) []
+        it2 = int_gt(i6, 0)
+        guard_true(it2) []
+        i13 = int_is_zero(i6)
+        guard_false(i13) []
+        i15 = int_and(i8, i6)
+        i17 = int_eq(i15, -1)
+        guard_false(i17) []
+        i18 = int_floordiv(i7, i6)
+        i19 = int_xor(i7, i6)
+        i21 = int_lt(i19, 0)
+        i22 = int_mod(i7, i6)
+        i23 = int_is_true(i22)
+        i24 = int_and(i21, i23)
+        i25 = int_sub(i18, i24)
+        jump(i7, i25, i8)
+        """
+        preamble = """
+        [i7, i6, i8]
+        it1 = int_gt(i7, 0)
+        guard_true(it1) []
+        it2 = int_gt(i6, 0)
+        guard_true(it2) []
+        i15 = int_and(i8, i6)
+        i17 = int_eq(i15, -1)
+        guard_false(i17) []
+        i18 = int_floordiv(i7, i6)
+        i19 = int_xor(i7, i6)
+        i22 = int_mod(i7, i6)
+        i23 = int_is_true(i22)
+        jump(i7, i18, i8)
+        """
+        expected = """
+        [i7, i6, i8]
+        it2 = int_gt(i6, 0)
+        guard_true(it2) []
+        i15 = int_and(i8, i6)
+        i17 = int_eq(i15, -1)
+        guard_false(i17) []
+        i18 = int_floordiv(i7, i6)
+        i19 = int_xor(i7, i6)
+        i22 = int_mod(i7, i6)
+        i23 = int_is_true(i22)
+        jump(i7, i18, i8)
+        """
+        self.optimize_loop(ops, expected, preamble)
+
+
+
     def test_subsub_ovf(self):
         ops = """
         [i0]

File pypy/module/pypyjit/test/test_pypy_c.py

View file
  • Ignore whitespace
         assert call.getarg(1).value == 2.0
         assert call.getarg(2).value == 3.0
 
-    # test_circular
+    def test_xor(self):
+        values = (-4, -3, -2, -1, 0, 1, 2, 3, 4)
+        for a in values:
+            for b in values:
+                if a^b >= 0:
+                    r = 2000
+                else:
+                    r = 0
+                if a > 0 and b > 1:
+                    ops = 0
+                else:
+                    ops = 0
+                
+                self.run_source('''
+                def main(a, b):
+                    i = sa = 0
+                    while i < 2000:
+                        if a > 0: # Specialises the loop
+                            pass
+                        if b > 1:
+                            pass
+                        if a^b >= 0:
+                            sa += 1
+                        i += 1
+                    return sa
+                ''', ops, ([a, b], r))
+        
 
 class AppTestJIT(PyPyCJITTests):
     def setup_class(cls):

File pypy/rpython/rint.py

View file
  • Ignore whitespace
             # return (x/y) - (((x^y)<0)&((x%y)!=0));
             v_xor = hop.genop(prefix + 'xor', vlist,
                             resulttype=repr)
-            v_xor_le = hop.genop(prefix + 'le', [v_xor, c_zero],
+            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 = hop.genop(prefix + 'mod', vlist,