Author: Carl Friedrich Bolz-Tereick <[email protected]>
Branch: intbound-improvements
Changeset: r93273:52f8b0936b0d
Date: 2017-12-03 22:24 +0100
http://bitbucket.org/pypy/pypy/changeset/52f8b0936b0d/

Log:    bounds propagation through int_invert

diff --git a/rpython/jit/metainterp/optimizeopt/intbounds.py 
b/rpython/jit/metainterp/optimizeopt/intbounds.py
--- a/rpython/jit/metainterp/optimizeopt/intbounds.py
+++ b/rpython/jit/metainterp/optimizeopt/intbounds.py
@@ -62,6 +62,15 @@
     postprocess_GUARD_FALSE = _postprocess_guard_true_false_value
     postprocess_GUARD_VALUE = _postprocess_guard_true_false_value
 
+    def optimize_INT_INVERT(self, op):
+        return self.emit(op)
+
+    def postprocess_INT_INVERT(self, op):
+        v1 = self.get_box_replacement(op.getarg(0))
+        b1 = self.getintbound(v1)
+        b = b1.invert_bound()
+        self.getintbound(op).intersect(b)
+
     def optimize_INT_OR(self, op):
         v1 = self.get_box_replacement(op.getarg(0))
         v2 = self.get_box_replacement(op.getarg(1))
@@ -684,6 +693,13 @@
         if b1.intersect(b):
             self.propagate_bounds_backward(op.getarg(0))
 
+    def propagate_bounds_INT_INVERT(self, op):
+        b1 = self.getintbound(op.getarg(0))
+        r = self.getintbound(op)
+        b = r.invert_bound()
+        if b1.intersect(b):
+            self.propagate_bounds_backward(op.getarg(0))
+
     propagate_bounds_INT_ADD_OVF = propagate_bounds_INT_ADD
     propagate_bounds_INT_SUB_OVF = propagate_bounds_INT_SUB
     propagate_bounds_INT_MUL_OVF = propagate_bounds_INT_MUL
diff --git a/rpython/jit/metainterp/optimizeopt/intutils.py 
b/rpython/jit/metainterp/optimizeopt/intutils.py
--- a/rpython/jit/metainterp/optimizeopt/intutils.py
+++ b/rpython/jit/metainterp/optimizeopt/intutils.py
@@ -324,6 +324,15 @@
                 r.make_ge_const(0)
         return r
 
+    def invert_bound(self):
+        r = IntUnbounded()
+        if self.has_upper:
+            r.has_lower = True
+            r.lower = ~self.upper
+        if self.has_lower:
+            r.has_upper = True
+            r.upper = ~self.lower
+        return r
 
     def contains(self, val):
         if not we_are_translated():
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_intbound.py 
b/rpython/jit/metainterp/optimizeopt/test/test_intbound.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_intbound.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_intbound.py
@@ -455,6 +455,20 @@
                         assert b3.contains(n1 ^ n2)
 
 
+def test_invert_bound_explicit():
+    r = bound(-6, 12)
+    c = r.invert_bound()
+    assert c.upper == ~-6
+    assert c.lower == ~12
+    assert c.has_upper and c.has_lower
+
+def test_invert_bound():
+    for _, _, b1 in some_bounds():
+        b2 = b1.invert_bound()
+        for n in nbr:
+            if b1.contains(n):
+                assert b2.contains(~n)
+
 def test_next_pow2_m1():
     assert next_pow2_m1(0) == 0
     assert next_pow2_m1(1) == 1
@@ -549,3 +563,9 @@
     b3 = b1.xor_bound(b2)
     r = n1 ^ n2
     assert b3.contains(r)
+
+@given(bound_with_contained_number)
+def test_invert_bound_random(t1):
+    b1, n1 = t1
+    b2 = b1.invert_bound()
+    assert b2.contains(~n1)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py 
b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -3447,6 +3447,57 @@
         """
         self.optimize_loop(ops, expected)
 
+    def test_int_invert_bound(self):
+        ops = """
+        [i0]
+        i1 = int_gt(i0, -5)
+        guard_true(i1) []
+        i2 = int_lt(i0, 100)
+        guard_true(i2) []
+        i3 = int_invert(i0)
+        i4 = int_gt(i3, -101)
+        guard_true(i4) []
+        i5 = int_lt(i3, 4)
+        guard_true(i5) []
+        jump(i3)
+        """
+        expected = """
+        [i0]
+        i1 = int_gt(i0, -5)
+        guard_true(i1) []
+        i2 = int_lt(i0, 100)
+        guard_true(i2) []
+        i3 = int_invert(i0)
+        jump(i3)
+        """
+        self.optimize_loop(ops, expected)
+
+    def test_int_invert_bound_backwards(self):
+        ops = """
+        [i0]
+        i3 = int_invert(i0)
+        i4 = int_gt(i3, -101)
+        guard_true(i4) []
+        i5 = int_lt(i3, 4)
+        guard_true(i5) []
+
+        i1 = int_gt(i0, -5)
+        guard_true(i1) []
+        i2 = int_lt(i0, 100)
+        guard_true(i2) []
+        jump(i3)
+        """
+        expected = """
+        [i0]
+        i3 = int_invert(i0)
+        i4 = int_gt(i3, -101)
+        guard_true(i4) []
+        i5 = int_lt(i3, 4)
+        guard_true(i5) []
+        jump(i3)
+        """
+        self.optimize_loop(ops, expected)
+
     def test_int_add_sub_constants_inverse(self):
         py.test.skip("reenable")
         import sys
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to