[pypy-svn] r72213 - in pypy/trunk/pypy: jit/backend jit/backend/llgraph jit/metainterp jit/metainterp/test rlib

fijal at codespeak.net fijal at codespeak.net
Sun Mar 14 01:13:15 CET 2010


Author: fijal
Date: Sun Mar 14 01:13:13 2010
New Revision: 72213

Modified:
   pypy/trunk/pypy/jit/backend/llgraph/runner.py
   pypy/trunk/pypy/jit/backend/model.py
   pypy/trunk/pypy/jit/metainterp/codewriter.py
   pypy/trunk/pypy/jit/metainterp/optimizeopt.py
   pypy/trunk/pypy/jit/metainterp/pyjitpl.py
   pypy/trunk/pypy/jit/metainterp/resoperation.py
   pypy/trunk/pypy/jit/metainterp/simple_optimize.py
   pypy/trunk/pypy/jit/metainterp/support.py
   pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py
   pypy/trunk/pypy/jit/metainterp/test/test_list.py
   pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py
   pypy/trunk/pypy/rlib/rgc.py
Log:
Merge arraycopy branch, part of it. It's the simplest way to run benchmarks
until we have per-branch run


Modified: pypy/trunk/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/llgraph/runner.py	(original)
+++ pypy/trunk/pypy/jit/backend/llgraph/runner.py	Sun Mar 14 01:13:13 2010
@@ -15,6 +15,7 @@
 from pypy.jit.backend import model
 from pypy.jit.backend.llgraph import llimpl, symbolic
 from pypy.jit.metainterp.typesystem import llhelper, oohelper
+from pypy.rlib import rgc
 
 class MiniStats:
     pass

Modified: pypy/trunk/pypy/jit/backend/model.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/model.py	(original)
+++ pypy/trunk/pypy/jit/backend/model.py	Sun Mar 14 01:13:13 2010
@@ -175,6 +175,11 @@
 
     def do_getarrayitem_gc(self, arraybox, indexbox, arraydescr):
         raise NotImplementedError
+
+    def do_arraycopy(self, calldescr, fnptr, sourcebox, destbox,
+                     source_startbox, dest_startbox, lengthbox, arraydescr):
+        return self.do_call([fnptr, sourcebox, destbox, source_startbox,
+                             dest_startbox, lengthbox], calldescr)
     
     def do_getfield_gc(self, structbox, fielddescr):
         raise NotImplementedError

Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/codewriter.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/codewriter.py	Sun Mar 14 01:13:13 2010
@@ -1452,6 +1452,8 @@
             self.register_var(op.result)
             return True
         #
+        if oopspec_name == 'list.ll_arraycopy':
+            return self.handle_arraycopy(op, arraydescr, args)
         if oopspec_name == 'list.getitem':
             return self.handle_list_getitem(op, arraydescr, args,
                                             'getarrayitem_gc')
@@ -1534,6 +1536,18 @@
         self.register_var(op.result)
         return True
 
+    def handle_arraycopy(self, op, arraydescr, args):
+        self.emit('arraycopy')
+        calldescr, _ = self.codewriter.getcalldescr(op.args[0], args, op.result,
+                                                    consider_effects_of=op)
+        self.emit(self.get_position(calldescr))
+        self.emit(self.var_position(op.args[0]))
+        for arg in args:
+            self.emit(self.var_position(arg))
+        self.emit(self.get_position(arraydescr))
+        self.register_var(op.result)
+        return True
+
     def prepare_list_getset(self, op, descr, args, checkname):
         if op.opname == 'oosend':
             SELFTYPE, _, meth = support.lookup_oosend_method(op)

Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/optimizeopt.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py	Sun Mar 14 01:13:13 2010
@@ -16,6 +16,7 @@
 from pypy.jit.metainterp.typesystem import llhelper, oohelper
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rpython.lltypesystem import lltype
+from pypy.jit.metainterp.history import AbstractDescr
 
 def optimize_loop_1(metainterp_sd, loop):
     """Optimize loop.operations to make it match the input of loop.specnodes
@@ -910,6 +911,27 @@
         fieldvalue = self.getvalue(op.args[2])
         self.heap_op_optimizer.optimize_SETARRAYITEM_GC(op, value, fieldvalue)
 
+    def optimize_ARRAYCOPY(self, op):
+        source_value = self.getvalue(op.args[2])
+        dest_value = self.getvalue(op.args[3])
+        source_start_box = self.get_constant_box(op.args[4])
+        dest_start_box = self.get_constant_box(op.args[5])
+        length = self.get_constant_box(op.args[6])
+        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
+            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)
+            return
+        descr = op.args[0]
+        assert isinstance(descr, AbstractDescr)
+        self.emit_operation(ResOperation(rop.CALL, op.args[1:], op.result,
+                                         descr))
+
     def optimize_INSTANCEOF(self, op):
         value = self.getvalue(op.args[0])
         realclassbox = value.get_constant_class(self.cpu)

Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py	Sun Mar 14 01:13:13 2010
@@ -360,6 +360,13 @@
     def opimpl_arraylen_gc(self, arraybox, arraydesc):
         self.execute_with_descr(rop.ARRAYLEN_GC, arraydesc, arraybox)
 
+    @arguments("descr", "box", "box", "box", "box", "box", "box", "descr")
+    def opimpl_arraycopy(self, calldescr, fnptr, sourcebox, destbox,
+                         source_startbox, dest_startbox, lengthbox, arraydescr):
+        self.execute_with_descr(rop.ARRAYCOPY, arraydescr, calldescr, fnptr,
+                                sourcebox, destbox, source_startbox,
+                                dest_startbox, lengthbox)
+
     @arguments("orgpc", "box", "descr", "box")
     def opimpl_check_neg_index(self, pc, arraybox, arraydesc, indexbox):
         negbox = self.metainterp.execute_and_record(

Modified: pypy/trunk/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/resoperation.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/resoperation.py	Sun Mar 14 01:13:13 2010
@@ -216,6 +216,7 @@
     'SETARRAYITEM_RAW/3d',#only added by backend.llsupport.gc.rewrite_assembler
     'SETFIELD_GC/2d',
     'SETFIELD_RAW/2d',
+    'ARRAYCOPY/7d',
     'NEWSTR/1',
     'STRSETITEM/3',
     'UNICODESETITEM/3',

Modified: pypy/trunk/pypy/jit/metainterp/simple_optimize.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/simple_optimize.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/simple_optimize.py	Sun Mar 14 01:13:13 2010
@@ -2,11 +2,21 @@
 """ Simplified optimize.py
 """
 
-from pypy.jit.metainterp.resoperation import rop
+from pypy.jit.metainterp.resoperation import rop, ResOperation
 from pypy.jit.metainterp import resume, compile
 
 EMPTY_VALUES = {}
 
+def transform(op):
+    from pypy.jit.metainterp.history import AbstractDescr
+    # change ARRAYCOPY to call, so we don't have to pass around
+    # unnecessary information to the backend
+    if op.opnum == rop.ARRAYCOPY:
+        descr = op.args[0]
+        assert isinstance(descr, AbstractDescr)
+        return ResOperation(rop.CALL, op.args[1:], op.result, descr=descr)
+    return op
+
 def optimize_loop(metainterp_sd, old_loops, loop):
     if old_loops:
         assert len(old_loops) == 1
@@ -25,7 +35,7 @@
                 modifier = resume.ResumeDataVirtualAdder(descr, memo)
                 newboxes = modifier.finish(EMPTY_VALUES)
                 descr.store_final_boxes(op, newboxes)
-            newoperations.append(op)
+            newoperations.append(transform(op))
         loop.operations = newoperations
         return None
 

Modified: pypy/trunk/pypy/jit/metainterp/support.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/support.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/support.py	Sun Mar 14 01:13:13 2010
@@ -17,6 +17,7 @@
 from pypy.rpython.annlowlevel import MixLevelHelperAnnotator
 from pypy.rpython.extregistry import ExtRegistryEntry
 from pypy.jit.metainterp.typesystem import deref
+from pypy.rlib import rgc
 
 def getargtypes(annotator, values):
     if values is None:    # for backend tests producing stand-alone exe's
@@ -134,6 +135,8 @@
 _ll_2_list_getitem_foldable = _ll_2_list_getitem
 _ll_1_list_len_foldable     = _ll_1_list_len
 
+_ll_5_list_ll_arraycopy = rgc.ll_arraycopy
+
 def _ll_1_gc_identityhash(x):
     return lltype.identityhash(x)
 

Modified: pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py	Sun Mar 14 01:13:13 2010
@@ -150,6 +150,8 @@
                 return ('typedescr', CLASS)
             def methdescrof(self, CLASS, methname):
                 return FakeMethDescr(CLASS, methname)
+            def arraydescrof(self, ARRAY):
+                return ('arraydescr', ARRAY)
             def sizeof(self, STRUCT):
                 return ('sizeof', STRUCT)
 
@@ -512,6 +514,28 @@
         assert ConstInt(55) in jitcode.constants
         assert ConstInt(66) not in jitcode.constants
 
+    def test_ll_arraycopy(self):
+        from pypy.rlib import rgc
+        from pypy.rpython.lltypesystem import lltype
+
+        A = lltype.GcArray(lltype.Signed)
+        
+        def f():
+            l = lltype.malloc(A, 3)
+            l[0] = 1
+            l[1] = 2
+            l[3] = 3
+            l2 = lltype.malloc(A, 3)
+            rgc.ll_arraycopy(l, l2, 0, 0, 3)
+            return l2[0] + l2[1] + l2[3]
+
+        graphs = self.make_graphs(f, [])
+        cw = CodeWriter(self.rtyper)
+        cw.candidate_graphs = [graphs[0]]
+        cw._start(self.metainterp_sd, None)
+        jitcode = cw.make_one_bytecode((graphs[0], None), False)
+        assert 'residual_call' not in jitcode._source
+        assert 'arraycopy' in jitcode._source
 
 class ImmutableFieldsTests:
 

Modified: pypy/trunk/pypy/jit/metainterp/test/test_list.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_list.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_list.py	Sun Mar 14 01:13:13 2010
@@ -118,6 +118,32 @@
         assert res == f(10)
         py.test.skip("'[non-null] * n' gives a residual call so far")
         self.check_loops(setarrayitem_gc=0, getarrayitem_gc=0, call=0)
+    
+    def test_arraycopy_simpleoptimize(self):
+        def f():
+            l = [1, 2, 3, 4]
+            l2 = l[:]
+            return l2[0] + l2[1] + l2[2] + l2[3]
+
+        res = self.interp_operations(f, [], listops=True)
+        assert res == 10
+
+    def test_arraycopy_full(self):
+        jitdriver = JitDriver(greens = [], reds = ['n'])
+        def f(n):
+            l = []
+            l2 = []
+            while n > 0:
+                jitdriver.can_enter_jit(n=n)
+                jitdriver.jit_merge_point(n=n)
+                l = [1, 2, 3, n]
+                l2 = l[:]
+                n -= 1
+            return l2[0] + l2[1] + l2[2] + l2[3]
+
+        res = self.meta_interp(f, [5], listops=True)
+        assert res == 7
+        self.check_loops(call=0)
 
 class TestOOtype(ListTests, OOJitMixin):
     pass

Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py	Sun Mar 14 01:13:13 2010
@@ -2723,6 +2723,8 @@
         """
         self.optimize_loop(ops, 'Not, Not', expected)
 
+    def test_arraycopy_1(self):
+        pass
 
 class TestOOtype(BaseTestOptimizeOpt, OOtypeMixin):
 

Modified: pypy/trunk/pypy/rlib/rgc.py
==============================================================================
--- pypy/trunk/pypy/rlib/rgc.py	(original)
+++ pypy/trunk/pypy/rlib/rgc.py	Sun Mar 14 01:13:13 2010
@@ -276,7 +276,7 @@
     keepalive_until_here(dest)
 ll_arraycopy._annenforceargs_ = [None, None, int, int, int]
 ll_arraycopy._annspecialcase_ = 'specialize:ll'
-ll_arraycopy._jit_look_inside_ = False
+ll_arraycopy.oopspec = 'list.ll_arraycopy(source, dest, source_start, dest_start, length)'
 
 def ll_shrink_array(p, smallerlength):
     from pypy.rpython.lltypesystem.lloperation import llop
@@ -310,7 +310,6 @@
 ll_shrink_array._annspecialcase_ = 'specialize:ll'
 ll_shrink_array._jit_look_inside_ = False
 
-
 def no_collect(func):
     func._dont_inline_ = True
     func._gc_no_collect_ = True



More information about the Pypy-commit mailing list