Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r80608:47e7d26dea93
Date: 2015-11-09 12:58 +0100
http://bitbucket.org/pypy/pypy/changeset/47e7d26dea93/

Log:    A missing optimization: it's hard to test but the front-end doesn't
        always manage to avoid this:

         i5 = int_le(...); guard_true(i5) [... i5 ...]

         So in rewrite.py, change it to:

         i0 = same_as_i(0); i5 = int_le(...); guard_true(i5) [... i0
        ...]

diff --git a/rpython/jit/backend/llsupport/rewrite.py 
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -181,13 +181,35 @@
             return op.is_ovf()    # int_xxx_ovf() / guard_no_overflow()
         if i + 1 >= len(operations):
             return False
-        if (operations[i + 1].getopnum() != rop.GUARD_TRUE and
-            operations[i + 1].getopnum() != rop.GUARD_FALSE):
+        next_op = operations[i + 1]
+        opnum = next_op.getopnum()
+        if not (opnum == rop.GUARD_TRUE or
+                opnum == rop.GUARD_FALSE or
+                opnum == rop.COND_CALL):
             return False
-        if operations[i + 1].getarg(0) is not op:
+        if next_op.getarg(0) is not op:
             return False
+        self.remove_tested_failarg(next_op)
         return True
 
+    def remove_tested_failarg(self, op):
+        opnum = op.getopnum()
+        if not (opnum == rop.GUARD_TRUE or opnum == rop.GUARD_FALSE):
+            return
+        try:
+            i = op.getfailargs().index(op.getarg(0))
+        except ValueError:
+            return
+        # The checked value is also in the failargs.  The front-end
+        # tries not to produce it, but doesn't always succeed (and
+        # it's hard to test all cases).  Rewrite it away.
+        value = (opnum == rop.GUARD_FALSE)
+        op1 = ResOperation(rop.SAME_AS_I, [ConstInt(value)])
+        self.emit_op(op1)
+        lst = op.getfailargs()[:]
+        lst[i] = op1
+        op.setfailargs(lst)
+
     # ----------
 
     def handle_getfield_gc(self, op):
diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py 
b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -1055,3 +1055,29 @@
             p1 = getfield_gc_r(p0, descr=tdescr)
             jump(p1)
         """)
+
+    def test_remove_tested_failarg(self):
+        self.check_rewrite("""
+            [i5]
+            i2 = int_ge(i5, 10)
+            guard_true(i2) [i5, i2]
+            jump()
+        """, """
+            [i5]
+            i0 = same_as_i(0)
+            i2 = int_ge(i5, 10)
+            guard_true(i2) [i5, i0]
+            jump()
+        """)
+        self.check_rewrite("""
+            [i5]
+            i2 = int_ge(i5, 10)
+            guard_false(i2) [i5, i2]
+            jump()
+        """, """
+            [i5]
+            i0 = same_as_i(1)
+            i2 = int_ge(i5, 10)
+            guard_false(i2) [i5, i0]
+            jump()
+        """)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to