Author: Alex Gaynor <alex.gay...@gmail.com>
Branch: 
Changeset: r69997:039dd41e5153
Date: 2014-03-16 20:23 -0700
http://bitbucket.org/pypy/pypy/changeset/039dd41e5153/

Log:    merged upstream

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
@@ -105,3 +105,6 @@
 
 .. branch: stdlib-2.7.6
 Update stdlib to v2.7.6
+
+.. branch: virtual-raw-store-load
+Support for virtualizing raw_store/raw_load operations
diff --git a/pypy/module/micronumpy/test/test_zjit.py 
b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -526,7 +526,7 @@
                            'guard_class': 4,
                            'guard_false': 2,
                            'guard_no_exception': 3,
-                           'guard_nonnull': 8,
+                           'guard_nonnull': 12,
                            'guard_nonnull_class': 4,
                            'guard_not_invalidated': 2,
                            'guard_true': 9,
diff --git a/rpython/jit/codewriter/jtransform.py 
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -547,20 +547,18 @@
         track_allocation = d.pop('track_allocation', True)
         if d:
             raise UnsupportedMallocFlags(d)
-        TYPE = op.args[0].value
         if zero:
             name += '_zero'
         if add_memory_pressure:
             name += '_add_memory_pressure'
         if not track_allocation:
             name += '_no_track_allocation'
+        TYPE = op.args[0].value
         op1 = self.prepare_builtin_call(op, name, args, (TYPE,), TYPE)
-        if name == 'raw_malloc_varsize':
-            ITEMTYPE = op.args[0].value.OF
-            if ITEMTYPE == lltype.Char:
-                return self._handle_oopspec_call(op1, args,
-                                                 
EffectInfo.OS_RAW_MALLOC_VARSIZE_CHAR,
-                                                 EffectInfo.EF_CAN_RAISE)
+        if name.startswith('raw_malloc_varsize') and TYPE.OF == lltype.Char:
+            return self._handle_oopspec_call(op1, args,
+                                             
EffectInfo.OS_RAW_MALLOC_VARSIZE_CHAR,
+                                             EffectInfo.EF_CAN_RAISE)
         return self.rewrite_op_direct_call(op1)
 
     def rewrite_op_malloc_varsize(self, op):
@@ -591,7 +589,7 @@
             name += '_no_track_allocation'
         op1 = self.prepare_builtin_call(op, name, [op.args[0]], (STRUCT,),
                                         STRUCT)
-        if name == 'raw_free':
+        if name.startswith('raw_free'):
             return self._handle_oopspec_call(op1, [op.args[0]],
                                              EffectInfo.OS_RAW_FREE,
                                              EffectInfo.EF_CANNOT_RAISE)
@@ -837,8 +835,8 @@
                     RESULT = lltype.Ptr(STRUCT)
                     assert RESULT == op.result.concretetype
                     return self._do_builtin_call(op, 'alloc_with_del', [],
-                                                 extra = (RESULT, vtable),
-                                                 extrakey = STRUCT)
+                                                 extra=(RESULT, vtable),
+                                                 extrakey=STRUCT)
             heaptracker.register_known_gctype(self.cpu, vtable, STRUCT)
             opname = 'new_with_vtable'
         else:
@@ -1237,7 +1235,7 @@
                 op1 = self.prepare_builtin_call(op, "llong_%s", args)
                 op2 = self._handle_oopspec_call(op1, args,
                                                 EffectInfo.OS_LLONG_%s,
-                                           EffectInfo.EF_ELIDABLE_CANNOT_RAISE)
+                                                
EffectInfo.EF_ELIDABLE_CANNOT_RAISE)
                 if %r == "TO_INT":
                     assert op2.result.concretetype == lltype.Signed
                 return op2
@@ -1269,7 +1267,7 @@
                 op1 = self.prepare_builtin_call(op, "ullong_%s", args)
                 op2 = self._handle_oopspec_call(op1, args,
                                                 EffectInfo.OS_LLONG_%s,
-                                           EffectInfo.EF_ELIDABLE_CANNOT_RAISE)
+                                                
EffectInfo.EF_ELIDABLE_CANNOT_RAISE)
                 return op2
         ''' % (_op, _oopspec.lower(), _oopspec)).compile()
 
diff --git a/rpython/jit/codewriter/test/test_jtransform.py 
b/rpython/jit/codewriter/test/test_jtransform.py
--- a/rpython/jit/codewriter/test/test_jtransform.py
+++ b/rpython/jit/codewriter/test/test_jtransform.py
@@ -60,7 +60,7 @@
 class FakeResidualCallControl:
     def guess_call_kind(self, op):
         return 'residual'
-    def getcalldescr(self, op, **kwds):
+    def getcalldescr(self, op, oopspecindex=None, extraeffect=None):
         return 'calldescr'
     def calldescr_canraise(self, calldescr):
         return True
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
@@ -1729,6 +1729,7 @@
         ops = """
         [i1]
         i2 = call('malloc', 10, descr=raw_malloc_descr)
+        guard_no_exception() []
         setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
         i3 = getarrayitem_raw(i2, 0, descr=rawarraydescr)
         call('free', i2, descr=raw_free_descr)
@@ -1744,6 +1745,7 @@
         ops = """
         [i1]
         i2 = call('malloc', 10, descr=raw_malloc_descr)
+        guard_no_exception() []
         setarrayitem_raw(i2, 0, i1, descr=rawarraydescr_char)
         setarrayitem_raw(i2, 2, 456, descr=rawarraydescr_char)
         setarrayitem_raw(i2, 1, 123, descr=rawarraydescr_char)
@@ -1756,6 +1758,7 @@
         [i1]
         label('foo')
         i2 = call('malloc', 10, descr=raw_malloc_descr)
+        guard_no_exception() []
         setarrayitem_raw(i2, 0, i1, descr=rawarraydescr_char)
         i3 = int_add(i2, 1)
         setarrayitem_raw(i3, 0, 123, descr=rawarraydescr_char)
@@ -1771,6 +1774,7 @@
         ops = """
         [i1]
         i2 = call('malloc', 10, descr=raw_malloc_descr)
+        guard_no_exception() []
         setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
         label('foo') # we expect the buffer to be forced *after* the label
         setarrayitem_raw(i2, 2, 456, descr=rawarraydescr_char) # overlap!
@@ -1781,6 +1785,7 @@
         [i1]
         label('foo')
         i2 = call('malloc', 10, descr=raw_malloc_descr)
+        guard_no_exception() []
         setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
         setarrayitem_raw(i2, 2, 456, descr=rawarraydescr_char)
         call('free', i2, descr=raw_free_descr)
@@ -1792,6 +1797,7 @@
         ops = """
         [i1]
         i2 = call('malloc', 10, descr=raw_malloc_descr)
+        guard_no_exception() []
         setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
         label('foo') # we expect the buffer to be forced *after* the label
         i3 = getarrayitem_raw(i2, 0, descr=rawarraydescr_char)
@@ -1802,6 +1808,7 @@
         [i1]
         label('foo')
         i2 = call('malloc', 10, descr=raw_malloc_descr)
+        guard_no_exception() []
         setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
         i3 = getarrayitem_raw(i2, 0, descr=rawarraydescr_char)
         call('free', i2, descr=raw_free_descr)
@@ -1813,6 +1820,7 @@
         ops = """
         [i0, i1]
         i2 = call('malloc', 10, descr=raw_malloc_descr)
+        guard_no_exception() []
         setarrayitem_raw(i2, 0, 42, descr=rawarraydescr_char)
         i3 = int_add(i2, 1) # get a slice of the original buffer
         setarrayitem_raw(i3, 0, 4242, descr=rawarraydescr) # write to the slice
@@ -1832,6 +1840,7 @@
         ops = """
         [i0, i1]
         i2 = call('malloc', 10, descr=raw_malloc_descr)
+        guard_no_exception() []
         i3 = int_add(i2, 1) # get a slice of the original buffer
         i4 = int_add(i3, 1) # get a slice of a slice
         setarrayitem_raw(i4, 0, i1, descr=rawarraydescr_char) # write to the 
slice
@@ -1849,6 +1858,7 @@
         ops = """
         [i0, i1]
         i2 = call('malloc', 10, descr=raw_malloc_descr)
+        guard_no_exception() []
         setarrayitem_raw(i2, 0, 42, descr=rawarraydescr_char)
         i3 = int_add(i2, 1) # get a slice of the original buffer
         setarrayitem_raw(i3, 4, 4242, descr=rawarraydescr_char) # write to the 
slice
@@ -1861,6 +1871,7 @@
         label('foo')
         # these ops are generated by VirtualRawBufferValue._really_force
         i2 = call('malloc', 10, descr=raw_malloc_descr)
+        guard_no_exception() []
         setarrayitem_raw(i2, 0, 42, descr=rawarraydescr_char)
         i3 = int_add(i2, 5) # 1+4*sizeof(char)
         setarrayitem_raw(i3, 0, 4242, descr=rawarraydescr_char)
@@ -1878,6 +1889,7 @@
         i2 = int_add(i1, 1)
         call('free', i0, descr=raw_free_descr)
         i3 = call('malloc', 10, descr=raw_malloc_descr)
+        guard_no_exception() []
         setarrayitem_raw(i3, 0, i2, descr=rawarraydescr)
         label('foo')
         jump(i3)
@@ -1889,11 +1901,48 @@
         call('free', i0, descr=raw_free_descr)
         label('foo')
         i3 = call('malloc', 10, descr=raw_malloc_descr)
+        guard_no_exception() []
         setarrayitem_raw(i3, 0, i2, descr=rawarraydescr)
         jump(i3)
         """
         self.optimize_loop(ops, expected)
 
+    def test_virtual_raw_store_raw_load(self):
+        ops = """
+        [i1]
+        i0 = call('malloc', 10, descr=raw_malloc_descr)
+        guard_no_exception() []
+        raw_store(i0, 0, i1, descr=rawarraydescr)
+        i2 = raw_load(i0, 0, descr=rawarraydescr)
+        i3 = int_add(i1, i2)
+        call('free', i0, descr=raw_free_descr)
+        jump(i3)
+        """
+        expected = """
+        [i1]
+        i2 = int_add(i1, i1)
+        jump(i2)
+        """
+        self.optimize_loop(ops, expected)
+
+    def test_virtual_raw_store_getarrayitem_raw(self):
+        ops = """
+        [f1]
+        i0 = call('malloc', 16, descr=raw_malloc_descr)
+        guard_no_exception() []
+        raw_store(i0, 8, f1, descr=rawarraydescr_float)
+        f2 = getarrayitem_raw(i0, 1, descr=rawarraydescr_float)
+        f3 = float_add(f1, f2)
+        call('free', i0, descr=raw_free_descr)
+        jump(f3)
+        """
+        expected = """
+        [f1]
+        f2 = float_add(f1, f1)
+        jump(f2)
+        """
+        self.optimize_loop(ops, expected)
+
     def test_duplicate_getfield_1(self):
         ops = """
         [p1, p2]
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_rawbuffer.py 
b/rpython/jit/metainterp/optimizeopt/test/test_rawbuffer.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_rawbuffer.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_rawbuffer.py
@@ -17,8 +17,7 @@
         ( 4, 2, 'descr2', 'two'),
         ( 8, 4, 'descr3', 'three'),
         (12, 2, 'descr4', 'four'),
-        ]
-    #
+    ]
 
 def test_write_value_update():
     buf = RawBuffer(FakeCPU())
@@ -28,7 +27,7 @@
     assert buf._get_memory() == [
         ( 0, 4, 'descr', 'ONE'),
         ( 4, 2, 'descr', 'two'),
-        ]
+    ]
 
 def test_write_value_invalid_length():
     buf = RawBuffer(FakeCPU())
@@ -38,7 +37,6 @@
     with py.test.raises(InvalidRawWrite):
         buf.write_value(0, 4, 'descr2', 'two')
 
-    
 def test_write_value_overlapping_next():
     buf = RawBuffer(FakeCPU())
     buf.write_value(0, 4, 'descr', 'one')
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py 
b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -226,6 +226,8 @@
                                                   hints={'nolength': True}))
     rawarraydescr_char = cpu.arraydescrof(lltype.Array(lltype.Char,
                                                        hints={'nolength': 
True}))
+    rawarraydescr_float = cpu.arraydescrof(lltype.Array(lltype.Float,
+                                                        hints={'nolength': 
True}))
 
     fc_array = lltype.GcArray(
         lltype.Struct(
diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py 
b/rpython/jit/metainterp/optimizeopt/virtualize.py
--- a/rpython/jit/metainterp/optimizeopt/virtualize.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualize.py
@@ -705,6 +705,7 @@
             return
         size = sizebox.value
         self.make_virtual_raw_memory(size, op.result, op)
+        self.last_emitted_operation = REMOVED
 
     def do_RAW_FREE(self, op):
         value = self.getvalue(op.getarg(1))
@@ -779,11 +780,12 @@
                 offset, itemsize, descr = self._unpack_arrayitem_raw_op(op, 
indexbox)
                 try:
                     itemvalue = value.getitem_raw(offset, itemsize, descr)
-                    self.make_equal_to(op.result, itemvalue)
                 except InvalidRawOperation:
                     box = value.force_box(self)
                     op.setarg(0, box)
                     self.emit_operation(op)
+                else:
+                    self.make_equal_to(op.result, itemvalue)
                 return
         value.ensure_nonnull()
         self.emit_operation(op)
@@ -805,6 +807,48 @@
         value.ensure_nonnull()
         self.emit_operation(op)
 
+    def _unpack_raw_load_store_op(self, op, offsetbox):
+        offset = offsetbox.getint()
+        cpu = self.optimizer.cpu
+        descr = op.getdescr()
+        itemsize = cpu.unpack_arraydescr_size(descr)[1]
+        return offset, itemsize, descr
+
+    def optimize_RAW_LOAD(self, op):
+        value = self.getvalue(op.getarg(0))
+        if value.is_virtual():
+            offsetbox = self.get_constant_box(op.getarg(1))
+            if offsetbox is not None:
+                offset, itemsize, descr = self._unpack_raw_load_store_op(op, 
offsetbox)
+                try:
+                    itemvalue = value.getitem_raw(offset, itemsize, descr)
+                except InvalidRawOperation:
+                    box = value.force_box(self)
+                    op.setarg(0, box)
+                    self.emit_operation(op)
+                else:
+                    self.make_equal_to(op.result, itemvalue)
+                return
+        value.ensure_nonnull()
+        self.emit_operation(op)
+
+    def optimize_RAW_STORE(self, op):
+        value = self.getvalue(op.getarg(0))
+        if value.is_virtual():
+            offsetbox = self.get_constant_box(op.getarg(1))
+            if offsetbox is not None:
+                offset, itemsize, descr = self._unpack_raw_load_store_op(op, 
offsetbox)
+                itemvalue = self.getvalue(op.getarg(2))
+                try:
+                    value.setitem_raw(offset, itemsize, descr, itemvalue)
+                except InvalidRawOperation:
+                    box = value.force_box(self)
+                    op.setarg(0, box)
+                    self.emit_operation(op)
+                return
+        value.ensure_nonnull()
+        self.emit_operation(op)
+
     def optimize_GETINTERIORFIELD_GC(self, op):
         value = self.getvalue(op.getarg(0))
         if value.is_virtual():
diff --git a/rpython/jit/metainterp/test/test_rawmem.py 
b/rpython/jit/metainterp/test/test_rawmem.py
--- a/rpython/jit/metainterp/test/test_rawmem.py
+++ b/rpython/jit/metainterp/test/test_rawmem.py
@@ -1,7 +1,8 @@
 from rpython.jit.metainterp.test.support import LLJitMixin
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rlib.rawstorage import (alloc_raw_storage, raw_storage_setitem,
-                                  free_raw_storage, raw_storage_getitem)
+                                     free_raw_storage, raw_storage_getitem)
+
 
 class RawMemTests(object):
     def test_cast_void_ptr(self):
@@ -44,6 +45,7 @@
         self.check_operations_history({'call': 2, 'guard_no_exception': 1,
                                        'raw_store': 1, 'raw_load': 1,
                                        'finish': 1})
+        self.metainterp.staticdata.stats.check_resops({'finish': 1}, 
omit_finish=False)
 
     def test_raw_storage_float(self):
         def f():
@@ -57,6 +59,7 @@
         self.check_operations_history({'call': 2, 'guard_no_exception': 1,
                                        'raw_store': 1, 'raw_load': 1,
                                        'finish': 1})
+        self.metainterp.staticdata.stats.check_resops({'finish': 1}, 
omit_finish=False)
 
     def test_raw_storage_byte(self):
         def f():
@@ -70,6 +73,21 @@
         self.check_operations_history({'call': 2, 'guard_no_exception': 1,
                                        'raw_store': 1, 'raw_load': 1,
                                        'finish': 1})
+        self.metainterp.staticdata.stats.check_resops({'finish': 1}, 
omit_finish=False)
+
+    def test_raw_storage_options(self):
+        def f():
+            p = alloc_raw_storage(15, track_allocation=False, zero=True)
+            raw_storage_setitem(p, 3, 24)
+            res = raw_storage_getitem(lltype.Signed, p, 3)
+            free_raw_storage(p, track_allocation=False)
+            return res
+        res = self.interp_operations(f, [])
+        assert res == 24
+        self.check_operations_history({'call': 2, 'guard_no_exception': 1,
+                                       'raw_store': 1, 'raw_load': 1,
+                                       'finish': 1})
+        self.metainterp.staticdata.stats.check_resops({'finish': 1}, 
omit_finish=False)
 
 
 class TestRawMem(RawMemTests, LLJitMixin):
diff --git a/rpython/jit/metainterp/test/test_virtual.py 
b/rpython/jit/metainterp/test/test_virtual.py
--- a/rpython/jit/metainterp/test/test_virtual.py
+++ b/rpython/jit/metainterp/test/test_virtual.py
@@ -1150,7 +1150,7 @@
         res = self.meta_interp(f, [10])
         assert res == 55
         self.check_trace_count(1)
-        self.check_resops(setarrayitem_raw=0, getarrayitem_raw=0)
+        self.check_resops({'guard_true': 2, 'int_add': 4, 'int_lt': 2, 'jump': 
1})
 
     def test_raw_malloc_resume(self):
         mydriver = JitDriver(greens=[], reds = 'auto')
@@ -1171,8 +1171,10 @@
         assert f(10) == 4000+55
         res = self.meta_interp(f, [10])
         assert res == 4000+55
-        # the getarrayitem_raw is in the bridge
-        self.check_resops(getarrayitem_raw=1, setarrayitem_raw=0)
+        self.check_trace_count(2)
+        self.check_resops({'guard_false': 2, 'guard_true': 5,
+                           'int_add': 8, 'int_gt': 3, 'int_lt': 4, 'int_mul': 
2,
+                           'jump': 2})
 
     def test_raw_malloc_no_virtualstate(self):
         mydriver = JitDriver(greens=[], reds = 'auto')
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to