[pypy-commit] pypy default: Merge branch bounds-int-add-or

squeaky noreply at buildbot.pypy.org
Mon Feb 17 23:59:11 CET 2014


Author: Squeaky <squeaky_pl at gmx.com>
Branch: 
Changeset: r69201:2b0a11075c0e
Date: 2014-02-17 23:54 +0100
http://bitbucket.org/pypy/pypy/changeset/2b0a11075c0e/

Log:	Merge branch bounds-int-add-or Propagate appropriate bounds through
	INT_(OR|XOR|AND) operations if the operands are positive to kill
	some guards

diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -78,3 +78,7 @@
 .. branch: optimize-int-and
 Optimize away INT_AND with constant mask of 1s that fully cover the bitrange
 of other operand.
+
+.. branch: bounds-int-add-or
+Propagate appropriate bounds through INT_(OR|XOR|AND) operations if the
+operands are positive to kill some guards
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
@@ -7,6 +7,7 @@
     CONST_0, MODE_ARRAY, MODE_STR, MODE_UNICODE)
 from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
 from rpython.jit.metainterp.resoperation import rop
+from rpython.jit.backend.llsupport import symbolic
 
 
 def get_integer_min(is_unsigned, byte_size):
@@ -23,6 +24,17 @@
         return (1 << ((byte_size << 3) - 1)) - 1
 
 
+def next_pow2_m1(n):
+    """Calculate next power of 2 greater than n minus one."""
+    n |= n >> 1
+    n |= n >> 2
+    n |= n >> 4
+    n |= n >> 8
+    n |= n >> 16
+    n |= n >> 32
+    return n
+
+
 class OptIntBounds(Optimization):
     """Keeps track of the bounds placed on integers by guards and remove
        redundant guards"""
@@ -56,17 +68,24 @@
     optimize_GUARD_FALSE = optimize_GUARD_TRUE
     optimize_GUARD_VALUE = optimize_GUARD_TRUE
 
-    def optimize_INT_XOR(self, op):
+    def optimize_INT_OR_or_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)
+            if op.getopnum() == rop.INT_OR:
+                self.make_equal_to(op.result, v1)
+            else:
+                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))
+            mostsignificant = v1.intbound.upper | v2.intbound.upper
+            r.intbound.intersect(IntBound(0, next_pow2_m1(mostsignificant)))
+
+    optimize_INT_OR = optimize_INT_OR_or_XOR
+    optimize_INT_XOR = optimize_INT_OR_or_XOR
 
     def optimize_INT_AND(self, op):
         v1 = self.getvalue(op.getarg(0))
@@ -82,6 +101,10 @@
             val = v1.box.getint()
             if val >= 0:
                 r.intbound.intersect(IntBound(0, val))
+        elif v1.intbound.known_ge(IntBound(0, 0)) and \
+          v2.intbound.known_ge(IntBound(0, 0)):
+            lesser = min(v1.intbound.upper, v2.intbound.upper)
+            r.intbound.intersect(IntBound(0, next_pow2_m1(lesser)))
 
     def optimize_INT_SUB(self, op):
         v1 = self.getvalue(op.getarg(0))
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_intbounds.py b/rpython/jit/metainterp/optimizeopt/test/test_intbounds.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/metainterp/optimizeopt/test/test_intbounds.py
@@ -0,0 +1,12 @@
+from rpython.jit.metainterp.optimizeopt.intbounds import next_pow2_m1
+
+
+def test_next_pow2_m1():
+    assert next_pow2_m1(0) == 0
+    assert next_pow2_m1(1) == 1
+    assert next_pow2_m1(7) == 7
+    assert next_pow2_m1(256) == 511
+    assert next_pow2_m1(255) == 255
+    assert next_pow2_m1(80) == 127
+    assert next_pow2_m1((1 << 32) - 5) == (1 << 32) - 1
+    assert next_pow2_m1((1 << 64) - 1) == (1 << 64) - 1
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
@@ -5326,6 +5326,114 @@
         """
         self.optimize_loop(ops, ops)
 
+    def test_int_and_cmp_above_bounds(self):
+        ops = """
+        [p0,p1]
+        i0 = getarrayitem_gc(p0, 0, descr=chararraydescr)
+        i1 = getarrayitem_gc(p1, 0, descr=u2arraydescr)
+        i2 = int_and(i0, i1)
+        i3 = int_le(i2, 255)
+        guard_true(i3) []
+        jump(i2)
+        """
+
+        expected = """
+        [p0,p1]
+        i0 = getarrayitem_gc(p0, 0, descr=chararraydescr)
+        i1 = getarrayitem_gc(p1, 0, descr=u2arraydescr)
+        i2 = int_and(i0, i1)
+        jump(i2)
+        """
+        self.optimize_loop(ops, expected)
+
+    def test_int_and_cmp_below_bounds(self):
+        ops = """
+        [p0,p1]
+        i0 = getarrayitem_gc(p0, 0, descr=chararraydescr)
+        i1 = getarrayitem_gc(p1, 0, descr=u2arraydescr)
+        i2 = int_and(i0, i1)
+        i3 = int_lt(i2, 255)
+        guard_true(i3) []
+        jump(i2)
+        """
+        self.optimize_loop(ops, ops)
+
+    def test_int_or_cmp_above_bounds(self):
+        ops = """
+        [p0,p1]
+        i0 = getarrayitem_gc(p0, 0, descr=chararraydescr)
+        i1 = getarrayitem_gc(p1, 0, descr=u2arraydescr)
+        i2 = int_or(i0, i1)
+        i3 = int_le(i2, 65535)
+        guard_true(i3) []
+        jump(i2)
+        """
+
+        expected = """
+        [p0,p1]
+        i0 = getarrayitem_gc(p0, 0, descr=chararraydescr)
+        i1 = getarrayitem_gc(p1, 0, descr=u2arraydescr)
+        i2 = int_or(i0, i1)
+        jump(i2)
+        """
+        self.optimize_loop(ops, expected)
+
+    def test_int_or_cmp_below_bounds(self):
+        ops = """
+        [p0,p1]
+        i0 = getarrayitem_gc(p0, 0, descr=chararraydescr)
+        i1 = getarrayitem_gc(p1, 0, descr=u2arraydescr)
+        i2 = int_or(i0, i1)
+        i3 = int_lt(i2, 65535)
+        guard_true(i3) []
+        jump(i2)
+        """
+        self.optimize_loop(ops, ops)
+
+    def test_int_xor_cmp_above_bounds(self):
+        ops = """
+        [p0,p1]
+        i0 = getarrayitem_gc(p0, 0, descr=chararraydescr)
+        i1 = getarrayitem_gc(p1, 0, descr=u2arraydescr)
+        i2 = int_xor(i0, i1)
+        i3 = int_le(i2, 65535)
+        guard_true(i3) []
+        jump(i2)
+        """
+
+        expected = """
+        [p0,p1]
+        i0 = getarrayitem_gc(p0, 0, descr=chararraydescr)
+        i1 = getarrayitem_gc(p1, 0, descr=u2arraydescr)
+        i2 = int_xor(i0, i1)
+        jump(i2)
+        """
+        self.optimize_loop(ops, expected)
+
+    def test_int_xor_cmp_below_bounds(self):
+        ops = """
+        [p0,p1]
+        i0 = getarrayitem_gc(p0, 0, descr=chararraydescr)
+        i1 = getarrayitem_gc(p1, 0, descr=u2arraydescr)
+        i2 = int_xor(i0, i1)
+        i3 = int_lt(i2, 65535)
+        guard_true(i3) []
+        jump(i2)
+        """
+        self.optimize_loop(ops, ops)
+
+    def test_int_or_same_arg(self):
+        ops = """
+        [i0]
+        i1 = int_or(i0, i0)
+        jump(i1)
+        """
+        expected = """
+        [i0]
+        jump(i0)
+        """
+        self.optimize_loop(ops, expected)
+
 
 class TestLLtype(BaseTestOptimizeBasic, LLtypeMixin):
     pass
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -1,6 +1,6 @@
 import py, random
 
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rstr
+from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rstr, rffi
 from rpython.rtyper.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
 from rpython.rtyper.rclass import FieldListAccessor, IR_QUASIIMMUTABLE
 
@@ -208,6 +208,8 @@
 
     chararray = lltype.GcArray(lltype.Char)
     chararraydescr = cpu.arraydescrof(chararray)
+    u2array = lltype.GcArray(rffi.USHORT)
+    u2arraydescr = cpu.arraydescrof(u2array)
 
     # array of structs (complex data)
     complexarray = lltype.GcArray(


More information about the pypy-commit mailing list