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