[pypy-commit] pypy default: implement unrolling of arraycopy over non-virtual and small sources

fijal noreply at buildbot.pypy.org
Sun Oct 28 15:25:15 CET 2012


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: 
Changeset: r58530:a2711f030e6c
Date: 2012-10-28 15:24 +0100
http://bitbucket.org/pypy/pypy/changeset/a2711f030e6c/

Log:	implement unrolling of arraycopy over non-virtual and small sources

diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py
--- a/pypy/jit/metainterp/optimizeopt/rewrite.py
+++ b/pypy/jit/metainterp/optimizeopt/rewrite.py
@@ -426,14 +426,31 @@
         source_start_box = self.get_constant_box(op.getarg(3))
         dest_start_box = self.get_constant_box(op.getarg(4))
         length = self.get_constant_box(op.getarg(5))
-        if (source_value.is_virtual() and source_start_box and dest_start_box
-            and length and (dest_value.is_virtual() or length.getint() <= 8)):
+        if (source_start_box and dest_start_box
+            and length and (dest_value.is_virtual() or length.getint() <= 8) and
+            (source_value.is_virtual() or length.getint() <= 8)):
             from pypy.jit.metainterp.optimizeopt.virtualize import VArrayValue
-            assert isinstance(source_value, VArrayValue)
             source_start = source_start_box.getint()
             dest_start = dest_start_box.getint()
             for index in range(length.getint()):
-                val = source_value.getitem(index + source_start)
+                # XXX fish fish fish
+                arraydescr = op.getdescr().get_extra_info().write_descrs_arrays[0]
+                if source_value.is_virtual():
+                    assert isinstance(source_value, VArrayValue)
+                    val = source_value.getitem(index + source_start)
+                else:
+                    if arraydescr.is_array_of_pointers():
+                        resbox = BoxPtr()
+                    elif arraydescr.is_array_of_floats():
+                        resbox = BoxFloat()
+                    else:
+                        resbox = BoxInt()
+                    newop = ResOperation(rop.GETARRAYITEM_GC,
+                                      [op.getarg(1),
+                                       ConstInt(index + source_start)], resbox,
+                                       descr=arraydescr)
+                    self.optimizer.propagate_forward(newop)
+                    val = self.getvalue(resbox)
                 if dest_value.is_virtual():
                     dest_value.setitem(index + dest_start, val)
                 else:
@@ -441,7 +458,7 @@
                                          [op.getarg(2),
                                           ConstInt(index + dest_start),
                                           val.get_key_box()], None,
-                                         descr=source_value.arraydescr)
+                                         descr=arraydescr)
                     self.emit_operation(newop)
             return True
         if length and length.getint() == 0:
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -3239,6 +3239,42 @@
         '''
         self.optimize_loop(ops, expected)
 
+    def test_arraycopy_not_virtual_2(self):
+        ops = '''
+        [p0]
+        p1 = new_array(3, descr=arraydescr)
+        call(0, p0, p1, 0, 0, 3, descr=arraycopydescr)
+        i0 = getarrayitem_gc(p1, 0, descr=arraydescr)
+        jump(i0)
+        '''
+        expected = '''
+        [p0]
+        i0 = getarrayitem_gc(p0, 0, descr=arraydescr)
+        i1 = getarrayitem_gc(p0, 1, descr=arraydescr) # removed by the backend
+        i2 = getarrayitem_gc(p0, 2, descr=arraydescr) # removed by the backend
+        jump(i0)
+        '''
+        self.optimize_loop(ops, expected)
+
+    def test_arraycopy_not_virtual_3(self):
+        ops = '''
+        [p0, p1]
+        call(0, p0, p1, 0, 0, 3, descr=arraycopydescr)
+        i0 = getarrayitem_gc(p1, 0, descr=arraydescr)
+        jump(i0)
+        '''
+        expected = '''
+        [p0, p1]
+        i0 = getarrayitem_gc(p0, 0, descr=arraydescr)
+        i1 = getarrayitem_gc(p0, 1, descr=arraydescr)
+        i2 = getarrayitem_gc(p0, 2, descr=arraydescr)
+        setarrayitem_gc(p1, 0, i0, descr=arraydescr)
+        setarrayitem_gc(p1, 1, i1, descr=arraydescr)
+        setarrayitem_gc(p1, 2, i2, descr=arraydescr)
+        jump(i0)
+        '''
+        self.optimize_loop(ops, expected)
+
     def test_arraycopy_no_elem(self):
         """ this was actually observed in the wild
         """


More information about the pypy-commit mailing list