Commits

Michael Pavone  committed f23c258 Draft

Added some boundary check propagation for unsigned integers

  • Participants
  • Parent commits 134dd82

Comments (0)

Files changed (2)

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

             self.make_constant_int(op.result, 0)
         else:
             self.emit_operation(op)
+    
+    def optimize_UINT_LT(self, op):
+        v1 = self.getvalue(op.getarg(0))
+        v2 = self.getvalue(op.getarg(1))
+        zero = IntBound(0,0)
+        if v1 is v2:
+            self.make_constant_int(op.result, 0)
+        elif v1.intbound.known_ge(zero) and v2.intbound.known_ge(zero):
+            if v1.intbound.known_lt(v2.intbound):
+                self.make_constant_int(op.result, 1)
+            elif v1.intbound.known_ge(v2.intbound):
+                self.make_constant_int(op.result, 0)
+            else:
+                self.emit_operation(op)
+        else:
+            self.emit_operation(op)
 
     def optimize_INT_GT(self, op):
         v1 = self.getvalue(op.getarg(0))
             self.make_constant_int(op.result, 0)
         else:
             self.emit_operation(op)
+    
+    def optimize_UINT_GT(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)
+        else:
+            self.emit_operation(op)
 
     def optimize_INT_LE(self, op):
         v1 = self.getvalue(op.getarg(0))
             self.make_constant_int(op.result, 0)
         else:
             self.emit_operation(op)
+    
+    def optimize_UINT_LE(self, op):
+        v1 = self.getvalue(op.getarg(0))
+        v2 = self.getvalue(op.getarg(1))
+        if v1 is v2:
+            self.make_constant_int(op.result, 1)
+        else:
+            self.emit_operation(op)
 
     def optimize_INT_GE(self, op):
         v1 = self.getvalue(op.getarg(0))
             self.make_constant_int(op.result, 0)
         else:
             self.emit_operation(op)
+    
+    def optimize_UINT_GE(self, op):
+        v1 = self.getvalue(op.getarg(0))
+        v2 = self.getvalue(op.getarg(1))
+        if v1 is v2:
+            self.make_constant_int(op.result, 1)
+        else:
+            self.emit_operation(op)
 
     def optimize_INT_EQ(self, op):
         v1 = self.getvalue(op.getarg(0))
         if v2.intbound.make_gt(v1.intbound):
             self.propagate_bounds_backward(box2)
 
+    def make_uint_lt(self, box1, box2):
+        v1 = self.getvalue(box1)
+        v2 = self.getvalue(box2)
+        zero = IntBound(0, 0)
+        if v2.intbound.known_ge(zero):
+            upper = v1.intbound.make_lt(v2.intbound)
+            lower = v1.intbound.make_ge(zero)
+            if upper or lower:
+                self.propagate_bounds_backward(box1)
+            if v2.intbound.make_gt(v1.intbound):
+                self.propagate_bounds_backward(box2)
+
     def make_int_le(self, box1, box2):
         v1 = self.getvalue(box1)
         v2 = self.getvalue(box2)
         if v2.intbound.make_ge(v1.intbound):
             self.propagate_bounds_backward(box2)
 
+    def make_uint_le(self, box1, box2):
+        v1 = self.getvalue(box1)
+        v2 = self.getvalue(box2)
+        zero = IntBound(0, 0)
+        if v2.intbound.known_ge(zero):
+            upper = v1.intbound.make_le(v2.intbound)
+            lower = v1.intbound.make_ge(zero)
+            if upper or lower:
+                self.propagate_bounds_backward(box1)
+            if v2.intbound.make_ge(v1.intbound):
+                self.propagate_bounds_backward(box2)
+
     def make_int_gt(self, box1, box2):
         self.make_int_lt(box2, box1)
 
     def make_int_ge(self, box1, box2):
         self.make_int_le(box2, box1)
 
+    def make_uint_ge(self, box1, box2):
+        self.make_uint_le(box2, box1)
+
     def propagate_bounds_INT_LT(self, op):
         r = self.getvalue(op.result)
         if r.is_constant():
                 self.make_int_lt(op.getarg(0), op.getarg(1))
             else:
                 self.make_int_ge(op.getarg(0), op.getarg(1))
+    
+    def propagate_bounds_UINT_LT(self, op):
+        r = self.getvalue(op.result)
+        if r.is_constant():
+            if r.box.same_constant(CONST_1):
+                self.make_uint_lt(op.getarg(0), op.getarg(1))
+            else:
+                self.make_uint_ge(op.getarg(0), op.getarg(1))
 
     def propagate_bounds_INT_GT(self, op):
         r = self.getvalue(op.result)

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

         self.optimize_loop(ops, expected)
 
     def test_compare_with_itself_uint(self):
-        py.test.skip("implement me")
         ops = """
         []
         i0 = escape()
         """
         self.optimize_loop(ops, expected)
 
-
+    def test_redundant_compare_uint(self):
+        ops = """
+        []
+        i0 = escape()
+        i1 = uint_lt(i0, 10)
+        guard_true(i1) []
+        i3 = uint_lt(i0, 20)
+        guard_true(i3) []
+        jump()
+        """
+        expected = """
+        []
+        i0 = escape()
+        i1 = uint_lt(i0, 10)
+        guard_true(i1) []
+        jump()
+        """
+        self.optimize_loop(ops, expected)
 
     def test_p123_simple(self):
         ops = """