[pypy-svn] pypy jit-short-preamble: chain lazy setfields following a getfield
hakanardo
commits-noreply at bitbucket.org
Fri Jan 14 08:36:47 CET 2011
Author: Hakan Ardo <hakan at debian.org>
Branch: jit-short-preamble
Changeset: r40655:a6dbb0663618
Date: 2011-01-14 08:36 +0100
http://bitbucket.org/pypy/pypy/changeset/a6dbb0663618/
Log: chain lazy setfields following a getfield
diff --git a/pypy/jit/metainterp/test/test_optimizeopt.py b/pypy/jit/metainterp/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/test/test_optimizeopt.py
@@ -4609,6 +4609,26 @@
"""
self.optimize_loop(ops, expected, preamble)
+ def test_let_getfield_kill_chained_setfields(self):
+ ops = """
+ [p0]
+ p1 = getfield_gc(p0, descr=valuedescr)
+ setfield_gc(p0, p0, descr=valuedescr)
+ setfield_gc(p0, p1, descr=valuedescr)
+ setfield_gc(p0, p1, descr=valuedescr)
+ jump(p0)
+ """
+ preamble = """
+ [p0]
+ p1 = getfield_gc(p0, descr=valuedescr)
+ jump(p0)
+ """
+ expected = """
+ [p0]
+ jump(p0)
+ """
+ self.optimize_loop(ops, expected, preamble)
+
def test_inputargs_added_by_forcing_jumpargs(self):
# FXIME: Can this occur?
ops = """
diff --git a/pypy/jit/metainterp/optimizeopt/heap.py b/pypy/jit/metainterp/optimizeopt/heap.py
--- a/pypy/jit/metainterp/optimizeopt/heap.py
+++ b/pypy/jit/metainterp/optimizeopt/heap.py
@@ -17,6 +17,7 @@
def __init__(self):
# cached fields: {descr: {OptValue_instance: OptValue_fieldvalue}}
self.cached_fields = {}
+ self.known_heap_fields = {}
# cached array items: {descr: CachedArrayItems}
self.cached_arrayitems = {}
# lazily written setfields (at most one per descr): {descr: op}
@@ -41,6 +42,13 @@
newd[value.get_reconstructed(optimizer, valuemap)] = \
fieldvalue.get_reconstructed(optimizer, valuemap)
+ for descr, d in self.known_heap_fields.items():
+ newd = {}
+ new.known_heap_fields[descr] = newd
+ for value, fieldvalue in d.items():
+ newd[value.get_reconstructed(optimizer, valuemap)] = \
+ fieldvalue.get_reconstructed(optimizer, valuemap)
+
new.cached_arrayitems = {}
for descr, d in self.cached_arrayitems.items():
newd = {}
@@ -62,6 +70,7 @@
def clean_caches(self):
self.cached_fields.clear()
+ self.known_heap_fields.clear()
self.cached_arrayitems.clear()
def cache_field_value(self, descr, value, fieldvalue, write=False):
@@ -166,6 +175,7 @@
self.force_lazy_setfield(fielddescr)
try:
del self.cached_fields[fielddescr]
+ del self.known_heap_fields[fielddescr]
except KeyError:
pass
for arraydescr in effectinfo.write_descrs_arrays:
@@ -202,9 +212,16 @@
except KeyError:
return
del self.lazy_setfields[descr]
- ###self.optimizer._emit_operation(op)
+ value = self.getvalue(op.getarg(0))
+ fieldvalue = self.getvalue(op.getarg(1))
+ try:
+ heapvalue = self.known_heap_fields[op.getdescr()][value]
+ if fieldvalue is heapvalue:
+ return
+ except KeyError:
+ pass
self.next_optimization.propagate_forward(op)
- #
+
# hackish: reverse the order of the last two operations if it makes
# sense to avoid a situation like "int_eq/setfield_gc/guard_true",
# which the backend (at least the x86 backend) does not handle well.
@@ -272,10 +289,13 @@
# default case: produce the operation
value.ensure_nonnull()
###self.optimizer.optimize_default(op)
- self.emit_operation(op) # FIXME: These might need constant propagation?
+ self.emit_operation(op)
# then remember the result of reading the field
fieldvalue = self.getvalue(op.result)
self.cache_field_value(op.getdescr(), value, fieldvalue)
+ # keep track of what's on the heap
+ d = self.known_heap_fields.setdefault(op.getdescr(), {})
+ d[value] = fieldvalue
def optimize_SETFIELD_GC(self, op):
value = self.getvalue(op.getarg(0))
@@ -295,7 +315,7 @@
self.make_equal_to(op.result, fieldvalue)
return
###self.optimizer.optimize_default(op)
- self.emit_operation(op) # FIXME: These might need constant propagation?
+ self.emit_operation(op)
fieldvalue = self.getvalue(op.result)
self.cache_arrayitem_value(op.getdescr(), value, indexvalue, fieldvalue)
More information about the Pypy-commit
mailing list