[pypy-commit] pypy release-2.6.x: merge default into release

mattip noreply at buildbot.pypy.org
Fri May 22 16:09:11 CEST 2015


Author: mattip <matti.picus at gmail.com>
Branch: release-2.6.x
Changeset: r77493:ef07e9436442
Date: 2015-05-22 17:04 +0300
http://bitbucket.org/pypy/pypy/changeset/ef07e9436442/

Log:	merge default into release

diff --git a/lib_pypy/cffi/_cffi_include.h b/lib_pypy/cffi/_cffi_include.h
--- a/lib_pypy/cffi/_cffi_include.h
+++ b/lib_pypy/cffi/_cffi_include.h
@@ -7,7 +7,8 @@
 #include "parse_c_type.h"
 
 /* this block of #ifs should be kept exactly identical between
-   c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py */
+   c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py
+   and cffi/_cffi_include.h */
 #if defined(_MSC_VER)
 # include <malloc.h>   /* for alloca() */
 # if _MSC_VER < 1600   /* MSVC < 2010 */
diff --git a/lib_pypy/cffi/parse_c_type.h b/lib_pypy/cffi/parse_c_type.h
--- a/lib_pypy/cffi/parse_c_type.h
+++ b/lib_pypy/cffi/parse_c_type.h
@@ -1,5 +1,5 @@
 
-/* See doc/parse_c_type.rst in the source of CFFI for more information */
+/* See doc/misc/parse_c_type.rst in the source of CFFI for more information */
 
 typedef void *_cffi_opcode_t;
 
diff --git a/pypy/doc/whatsnew-2.6.0.rst b/pypy/doc/whatsnew-2.6.0.rst
--- a/pypy/doc/whatsnew-2.6.0.rst
+++ b/pypy/doc/whatsnew-2.6.0.rst
@@ -126,3 +126,8 @@
 PyPy on windows provides a non-console pypyw.exe as well as pypy.exe.
 Similar to pythonw.exe, any use of stdout, stderr without redirection
 will crash.
+
+.. branch: fold-arith-ops
+
+branch fold-arith-ops
+remove multiple adds on add chains ("1 + 1 + 1 + ...")
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
@@ -3,6 +3,6 @@
 =======================
 
 .. this is a revision shortly after release-2.6.0
-.. startrev: 4c5c81da93e2e3c9df6be64d9bd79c958144de55
+.. startrev: 2ac87a870acf562301840cace411e34c1b96589c
 
 
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
@@ -8,6 +8,7 @@
 from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
 from rpython.jit.metainterp.resoperation import rop
 from rpython.jit.backend.llsupport import symbolic
+from rpython.rlib.rarithmetic import intmask
 
 
 def get_integer_min(is_unsigned, byte_size):
@@ -123,8 +124,44 @@
             r.getintbound().intersect(b)
 
     def optimize_INT_ADD(self, op):
-        v1 = self.getvalue(op.getarg(0))
-        v2 = self.getvalue(op.getarg(1))
+        arg1 = op.getarg(0)
+        arg2 = op.getarg(1)
+        v1 = self.getvalue(arg1)
+        v2 = self.getvalue(arg2)
+
+        # Optimize for addition chains in code "b = a + 1; c = b + 1" by
+        # detecting the int_add chain, and swapping with "b = a + 1;
+        # c = a + 2". If b is not used elsewhere, the backend eliminates
+        # it.
+
+        # either v1 or v2 can be a constant, swap the arguments around if
+        # v1 is the constant
+        if v1.is_constant():
+            arg1, arg2 = arg2, arg1
+            v1, v2 = v2, v1
+        if v2.is_constant():
+            try:
+                prod_op = self.optimizer.producer[arg1]
+            except KeyError:
+                pass
+            else:
+                if prod_op.getopnum() == rop.INT_ADD:
+                    prod_arg1 = prod_op.getarg(0)
+                    prod_arg2 = prod_op.getarg(1)
+                    prod_v1 = self.getvalue(prod_arg1)
+                    prod_v2 = self.getvalue(prod_arg2)
+
+                    # same thing here: prod_v1 or prod_v2 can be a
+                    # constant
+                    if prod_v1.is_constant():
+                        prod_arg1, prod_arg2 = prod_arg2, prod_arg1
+                        prod_v1, prod_v2 = prod_v2, prod_v1
+                    if prod_v2.is_constant():
+                        sum = intmask(v2.box.getint() + prod_v2.box.getint())
+                        arg1 = prod_arg1
+                        arg2 = ConstInt(sum)
+                        op = op.copy_and_change(rop.INT_ADD, args=[arg1, arg2])
+
         self.emit_operation(op)
         r = self.getvalue(op.result)
         b = v1.getintbound().add_bound(v2.getintbound())
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
@@ -3756,7 +3756,13 @@
         i4 = int_sub(i0, %s)
         jump(i0, i2, i3, i4)
         """ % ((-sys.maxint - 1, ) * 3)
-        self.optimize_loop(ops, ops) # does not crash
+        expected = """
+        [i0, i10, i11, i12]
+        i2 = int_add(%s, i0)
+        i4 = int_sub(i0, %s)
+        jump(i0, i2, i0, i4)
+        """ % ((-sys.maxint - 1, ) * 2)
+        self.optimize_loop(ops, expected)
 
     def test_framestackdepth_overhead(self):
         ops = """
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -1278,7 +1278,7 @@
         preamble = """
         [i0, p1, p3]
         i28 = int_add(i0, 1)
-        i29 = int_add(i28, 1)
+        i29 = int_add(i0, 2)
         p30 = new_with_vtable(ConstClass(node_vtable))
         setfield_gc(p30, i28, descr=nextdescr)
         setfield_gc(p3, p30, descr=valuedescr)
@@ -1288,7 +1288,7 @@
         expected = """
         [i0, p1, p3]
         i28 = int_add(i0, 1)
-        i29 = int_add(i28, 1)
+        i29 = int_add(i0, 2)
         p30 = new_with_vtable(ConstClass(node_vtable))
         setfield_gc(p30, i28, descr=nextdescr)
         setfield_gc(p3, p30, descr=valuedescr)
@@ -3079,6 +3079,69 @@
         """
         self.optimize_loop(ops, expected, preamble)
 
+    def test_remove_multiple_add_1(self):
+        ops = """
+        [i0]
+        i1 = int_add(i0, 1)
+        i2 = int_add(i1, 2)
+        i3 = int_add(i2, 1)
+        jump(i3)
+        """
+        expected = """
+        [i0]
+        i1 = int_add(i0, 1)
+        i2 = int_add(i0, 3)
+        i3 = int_add(i0, 4)
+        jump(i3)
+        """
+        self.optimize_loop(ops, expected)
+
+    def test_remove_multiple_add_2(self):
+        ops = """
+        [i0]
+        i1 = int_add(i0, 1)
+        i2 = int_add(2, i1)
+        i3 = int_add(i2, 1)
+        i4 = int_mul(i3, 5)
+        i5 = int_add(5, i4)
+        i6 = int_add(1, i5)
+        i7 = int_add(i2, i6)
+        i8 = int_add(i7, 1)
+        jump(i8)
+        """
+        expected = """
+        [i0]
+        i1 = int_add(i0, 1)
+        i2 = int_add(i0, 3)
+        i3 = int_add(i0, 4)
+        i4 = int_mul(i3, 5)
+        i5 = int_add(5, i4)
+        i6 = int_add(i4, 6)
+        i7 = int_add(i2, i6)
+        i8 = int_add(i7, 1)
+        jump(i8)
+        """
+        self.optimize_loop(ops, expected)
+
+    def test_remove_multiple_add_3(self):
+        ops = """
+        [i0]
+        i1 = int_add(i0, %s)
+        i2 = int_add(i1, %s)
+        i3 = int_add(i0, %s)
+        i4 = int_add(i3, %s)
+        jump(i4)
+        """ % (sys.maxint - 1, sys.maxint - 2, -sys.maxint, -sys.maxint + 1)
+        expected = """
+        [i0]
+        i1 = int_add(i0, %s)
+        i2 = int_add(i0, %s)
+        i3 = int_add(i0, %s)
+        i4 = int_add(i0, %s)
+        jump(i4)
+        """ % (sys.maxint - 1, -5, -sys.maxint, 3)
+        self.optimize_loop(ops, expected)
+
     def test_remove_duplicate_pure_op(self):
         ops = """
         [p1, p2]


More information about the pypy-commit mailing list