[pypy-commit] pypy default: ll_arraycopy: optimize the case where the dest value is not virtual,
Armin Rigo
noreply at buildbot.pypy.org
Fri Jun 3 12:22:48 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r44660:f75e0d4d5e6d
Date: 2011-06-03 12:16 +0200
http://bitbucket.org/pypy/pypy/changeset/f75e0d4d5e6d/
Log: ll_arraycopy: optimize the case where the dest value is not virtual,
and only the source value is. If the copy is not too long, it can
be done as a sequence of residual SETARRAYITEM_GC.
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
@@ -415,14 +415,22 @@
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()):
- # XXX optimize the case where dest value is not virtual,
- # but we still can avoid a mess
+ and length and (dest_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)
- dest_value.setitem(index + dest_start, val)
+ if dest_value.is_virtual():
+ dest_value.setitem(index + dest_start, val)
+ else:
+ newop = ResOperation(rop.SETARRAYITEM_GC,
+ [op.getarg(2),
+ ConstInt(index + dest_start),
+ val.force_box()], None,
+ descr=source_value.arraydescr)
+ self.emit_operation(newop)
return True
if length and length.getint() == 0:
return True # 0-length arraycopy
diff --git a/pypy/jit/metainterp/test/test_optimizeopt.py b/pypy/jit/metainterp/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/test/test_optimizeopt.py
@@ -3402,6 +3402,56 @@
'''
self.optimize_loop(ops, expected)
+ def test_arraycopy_dest_not_virtual(self):
+ ops = '''
+ []
+ p1 = new_array(3, descr=arraydescr)
+ p2 = new_array(3, descr=arraydescr)
+ setarrayitem_gc(p1, 2, 10, descr=arraydescr)
+ setarrayitem_gc(p2, 2, 13, descr=arraydescr)
+ escape(p2)
+ call(0, p1, p2, 0, 0, 3, descr=arraycopydescr)
+ escape(p2)
+ jump()
+ '''
+ expected = '''
+ []
+ p2 = new_array(3, descr=arraydescr)
+ setarrayitem_gc(p2, 2, 13, descr=arraydescr)
+ escape(p2)
+ setarrayitem_gc(p2, 0, 0, descr=arraydescr)
+ setarrayitem_gc(p2, 1, 0, descr=arraydescr)
+ setarrayitem_gc(p2, 2, 10, descr=arraydescr)
+ escape(p2)
+ jump()
+ '''
+ self.optimize_loop(ops, expected)
+
+ def test_arraycopy_dest_not_virtual_too_long(self):
+ ops = '''
+ []
+ p1 = new_array(10, descr=arraydescr)
+ p2 = new_array(10, descr=arraydescr)
+ setarrayitem_gc(p1, 2, 10, descr=arraydescr)
+ setarrayitem_gc(p2, 2, 13, descr=arraydescr)
+ escape(p2)
+ call(0, p1, p2, 0, 0, 10, descr=arraycopydescr)
+ escape(p2)
+ jump()
+ '''
+ expected = '''
+ []
+ p2 = new_array(10, descr=arraydescr)
+ setarrayitem_gc(p2, 2, 13, descr=arraydescr)
+ escape(p2)
+ p1 = new_array(10, descr=arraydescr)
+ setarrayitem_gc(p1, 2, 10, descr=arraydescr)
+ call(0, p1, p2, 0, 0, 10, descr=arraycopydescr)
+ escape(p2)
+ jump()
+ '''
+ self.optimize_loop(ops, expected)
+
def test_bound_lt(self):
ops = """
[i0]
More information about the pypy-commit
mailing list