Author: Alex Gaynor <[email protected]>
Branch:
Changeset: r67343:886b28486155
Date: 2013-10-13 16:05 +0200
http://bitbucket.org/pypy/pypy/changeset/886b28486155/
Log: make the frontend heapcache smarter, take advantage of usually-
constant indices, and propate known values
diff --git a/rpython/jit/metainterp/heapcache.py
b/rpython/jit/metainterp/heapcache.py
--- a/rpython/jit/metainterp/heapcache.py
+++ b/rpython/jit/metainterp/heapcache.py
@@ -118,20 +118,42 @@
# A special case for ll_arraycopy, because it is so common, and its
# effects are so well defined.
elif effectinfo.oopspecindex == effectinfo.OS_ARRAYCOPY:
- # The destination box
if (
- argboxes[2] in self.new_boxes and
+ isinstance(argboxes[3], ConstInt) and
+ isinstance(argboxes[4], ConstInt) and
+ isinstance(argboxes[5], ConstInt) and
len(effectinfo.write_descrs_arrays) == 1
):
- # Fish the descr out of the effectinfo
- cache =
self.heap_array_cache.get(effectinfo.write_descrs_arrays[0], None)
- if cache is not None:
- # XXX: in theory the indices of the copy could be
- # looked at
- for idx, cache in cache.iteritems():
- for frombox in cache.keys():
- if not self.is_unescaped(frombox):
- del cache[frombox]
+ descr = effectinfo.write_descrs_arrays[0]
+ cache = self.heap_array_cache.get(descr, None)
+ srcstart = argboxes[3].getint()
+ dststart = argboxes[4].getint()
+ length = argboxes[5].getint()
+ for i in xrange(length):
+ value = self.getarrayitem(
+ argboxes[1],
+ ConstInt(srcstart + i),
+ descr,
+ )
+ if value is not None:
+ self.setarrayitem(
+ argboxes[2],
+ ConstInt(dststart + i),
+ value,
+ descr,
+ )
+ elif cache is not None:
+ if argboxes[2] in self.new_boxes:
+ try:
+ idx_cache = cache[dststart + i]
+ except KeyError:
+ pass
+ else:
+ for frombox in idx_cache.keys():
+ if not self.is_unescaped(frombox):
+ del idx_cache[frombox]
+ else:
+ cache[dststart + i].clear()
return
else:
# Only invalidate things that are either escaped or arguments
@@ -210,9 +232,9 @@
return new_d
def getarrayitem(self, box, indexbox, descr):
- box = self._input_indirection(box)
if not isinstance(indexbox, ConstInt):
return
+ box = self._input_indirection(box)
index = indexbox.getint()
cache = self.heap_array_cache.get(descr, None)
if cache:
@@ -221,10 +243,10 @@
return self._output_indirection(indexcache.get(box, None))
def getarrayitem_now_known(self, box, indexbox, valuebox, descr):
+ if not isinstance(indexbox, ConstInt):
+ return
box = self._input_indirection(box)
valuebox = self._input_indirection(valuebox)
- if not isinstance(indexbox, ConstInt):
- return
index = indexbox.getint()
cache = self.heap_array_cache.setdefault(descr, {})
indexcache = cache.get(index, None)
diff --git a/rpython/jit/metainterp/test/test_heapcache.py
b/rpython/jit/metainterp/test/test_heapcache.py
--- a/rpython/jit/metainterp/test/test_heapcache.py
+++ b/rpython/jit/metainterp/test/test_heapcache.py
@@ -372,22 +372,22 @@
h.invalidate_caches(
rop.CALL,
FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE,
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]),
- [None, None, box2, None, None]
+ [None, box5, box2, index1, index1, index1]
)
assert h.getarrayitem(box1, index1, descr1) is box2
h.invalidate_caches(
rop.CALL,
FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE,
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]),
- [None, None, box3, None, None]
+ [None, box5, box3, index1, index1, index1]
)
- assert h.getarrayitem(box1, index1, descr1) is None
+ assert h.getarrayitem(box1, index1, descr1) is box2
h.setarrayitem(box4, index1, box2, descr1)
assert h.getarrayitem(box4, index1, descr1) is box2
h.invalidate_caches(
rop.CALL,
FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE,
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]),
- [None, None, box2, None, None]
+ [None, box3, box5, index1, index1, index2]
)
assert h.getarrayitem(box4, index1, descr1) is None
@@ -399,10 +399,29 @@
h.invalidate_caches(
rop.CALL,
FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE,
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr2]),
- [None, None, box2, None, None]
+ [None, box3, box2, index1, index1, index2]
)
assert h.getarrayitem(box1, index1, descr1) is box2
+ def test_ll_arraycopy_result_propogated(self):
+ h = HeapCache()
+ h.setarrayitem(box1, index1, box2, descr1)
+ h.invalidate_caches(
+ rop.CALL,
+ FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE,
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]),
+ [None, box1, box3, index1, index1, index2]
+ )
+ assert h.getarrayitem(box3, index1, descr1) is box2
+
+ def test_ll_arraycopy_dest_new(self):
+ h = HeapCache()
+ h.new_array(box1, lengthbox1)
+ h.setarrayitem(box3, index1, box4, descr1)
+ h.invalidate_caches(
+ rop.CALL,
+ FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE,
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]),
+ [None, box2, box1, index1, index1, index2]
+ )
def test_unescaped(self):
h = HeapCache()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit