Author: Alex Gaynor <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit