Author: Carl Friedrich Bolz <[email protected]>
Branch: 
Changeset: r76238:921ec8f176f5
Date: 2015-03-04 11:52 +0100
http://bitbucket.org/pypy/pypy/changeset/921ec8f176f5/

Log:    some more pure op variants for int_add and int_sub where one
        argument is constant

        This allows the optimization of:

        l.append(x) ... y = l[-1]

        because the index manipulation is folded

diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py 
b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -866,13 +866,41 @@
             return
         optpure = self.optpure
         if op.getopnum() == rop.INT_ADD:
-            optpure.pure(rop.INT_ADD, [op.getarg(1), op.getarg(0)], op.result)
+            arg0 = op.getarg(0)
+            arg1 = op.getarg(1)
+            optpure.pure(rop.INT_ADD, [arg1, arg0], op.result)
             # Synthesize the reverse op for optimize_default to reuse
-            optpure.pure(rop.INT_SUB, [op.result, op.getarg(1)], op.getarg(0))
-            optpure.pure(rop.INT_SUB, [op.result, op.getarg(0)], op.getarg(1))
+            optpure.pure(rop.INT_SUB, [op.result, arg1], arg0)
+            optpure.pure(rop.INT_SUB, [op.result, arg0], arg1)
+            if isinstance(arg0, ConstInt):
+                # invert the constant
+                i0 = arg0.getint()
+                inv_arg0 = ConstInt(-i0)
+            elif isinstance(arg1, ConstInt):
+                # commutative
+                i0 = arg1.getint()
+                inv_arg0 = ConstInt(-i0)
+                arg1 = arg0
+            else:
+                return
+            optpure.pure(rop.INT_SUB, [arg1, inv_arg0], op.result)
+            optpure.pure(rop.INT_SUB, [arg1, op.result], inv_arg0)
+            optpure.pure(rop.INT_ADD, [op.result, inv_arg0], arg1)
+            optpure.pure(rop.INT_ADD, [inv_arg0, op.result], arg1)
+
         elif op.getopnum() == rop.INT_SUB:
-            optpure.pure(rop.INT_ADD, [op.result, op.getarg(1)], op.getarg(0))
-            optpure.pure(rop.INT_SUB, [op.getarg(0), op.result], op.getarg(1))
+            arg0 = op.getarg(0)
+            arg1 = op.getarg(1)
+            optpure.pure(rop.INT_ADD, [op.result, arg1], arg0)
+            optpure.pure(rop.INT_SUB, [arg0, op.result], arg1)
+            if isinstance(arg1, ConstInt):
+                # invert the constant
+                i1 = arg1.getint()
+                inv_arg1 = ConstInt(-i1)
+                optpure.pure(rop.INT_ADD, [arg0, inv_arg1], op.result)
+                optpure.pure(rop.INT_ADD, [inv_arg1, arg0], op.result)
+                optpure.pure(rop.INT_SUB, [inv_arg1, op.result], arg0)
+                optpure.pure(rop.INT_SUB, [op.result, arg0], inv_arg1)
         elif op.getopnum() == rop.FLOAT_MUL:
             optpure.pure(rop.FLOAT_MUL, [op.getarg(1), op.getarg(0)], 
op.result)
         elif op.getopnum() == rop.FLOAT_NEG:
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
@@ -3703,6 +3703,52 @@
         """
         self.optimize_loop(ops, expected)
 
+    def test_int_add_sub_constants_inverse(self):
+        ops = """
+        [i0, i10, i11, i12, i13]
+        i2 = int_add(1, i0)
+        i3 = int_add(-1, i2)
+        i4 = int_sub(i0, -1)
+        i5 = int_sub(i0, i2)
+        jump(i0, i2, i3, i4, i5)
+        """
+        expected = """
+        [i0, i10, i11, i12, i13]
+        i2 = int_add(1, i0)
+        jump(i0, i2, i0, i2, -1)
+        """
+        self.optimize_loop(ops, expected)
+        ops = """
+        [i0, i10, i11, i12, i13]
+        i2 = int_add(i0, 1)
+        i3 = int_add(-1, i2)
+        i4 = int_sub(i0, -1)
+        i5 = int_sub(i0, i2)
+        jump(i0, i2, i3, i4, i5)
+        """
+        expected = """
+        [i0, i10, i11, i12, i13]
+        i2 = int_add(i0, 1)
+        jump(i0, i2, i0, i2, -1)
+        """
+        self.optimize_loop(ops, expected)
+
+        ops = """
+        [i0, i10, i11, i12, i13, i14]
+        i2 = int_sub(i0, 1)
+        i3 = int_add(-1, i0)
+        i4 = int_add(i0, -1)
+        i5 = int_sub(-1, i2)
+        i6 = int_sub(i2, i0)
+        jump(i0, i2, i3, i4, i5, i6)
+        """
+        expected = """
+        [i0, i10, i11, i12, i13, i14]
+        i2 = int_sub(i0, 1)
+        jump(i0, i2, i2, i2, i0, -1)
+        """
+        self.optimize_loop(ops, expected)
+
     def test_framestackdepth_overhead(self):
         ops = """
         [p0, i22]
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to