[pypy-commit] pypy default: update value in-place instead of creating a new one (for one relatively obscure
fijal
noreply at buildbot.pypy.org
Sun Dec 21 16:34:31 CET 2014
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch:
Changeset: r75046:9a145bb36ced
Date: 2014-12-21 17:34 +0200
http://bitbucket.org/pypy/pypy/changeset/9a145bb36ced/
Log: update value in-place instead of creating a new one (for one
relatively obscure case of promoting to constant anyway)
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -4,7 +4,7 @@
from rpython.jit.metainterp.optimizeopt.util import args_dict
from rpython.jit.metainterp.history import Const
from rpython.jit.metainterp.jitexc import JitException
-from rpython.jit.metainterp.optimizeopt.optimizer import Optimization, MODE_ARRAY, LEVEL_KNOWNCLASS, REMOVED
+from rpython.jit.metainterp.optimizeopt.optimizer import Optimization, MODE_ARRAY, LEVEL_KNOWNCLASS, REMOVED, LEVEL_CONSTANT
from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
from rpython.jit.metainterp.optimize import InvalidLoop
from rpython.jit.metainterp.resoperation import rop, ResOperation
@@ -63,6 +63,17 @@
# cancelling its previous effects with no side effect.
self._lazy_setfield = None
+ def value_updated(self, oldvalue, newvalue):
+ try:
+ fieldvalue = self._cached_fields[oldvalue]
+ except KeyError:
+ pass
+ else:
+ self._cached_fields[newvalue] = fieldvalue
+ op = self._cached_fields_getfield_op[oldvalue].clone()
+ op.setarg(0, newvalue.box)
+ self._cached_fields_getfield_op[newvalue] = op
+
def possible_aliasing(self, optheap, structvalue):
# If lazy_setfield is set and contains a setfield on a different
# structvalue, then we are annoyed, because it may point to either
@@ -117,18 +128,6 @@
self._cached_fields.clear()
self._cached_fields_getfield_op.clear()
- def turned_constant(self, newvalue, value):
- if newvalue not in self._cached_fields and value in self._cached_fields:
- self._cached_fields[newvalue] = self._cached_fields[value]
- op = self._cached_fields_getfield_op[value].clone()
- constbox = value.box
- assert isinstance(constbox, Const)
- op.setarg(0, constbox)
- self._cached_fields_getfield_op[newvalue] = op
- for structvalue in self._cached_fields.keys():
- if self._cached_fields[structvalue] is value:
- self._cached_fields[structvalue] = newvalue
-
def produce_potential_short_preamble_ops(self, optimizer, shortboxes, descr):
if self._lazy_setfield is not None:
return
@@ -186,6 +185,17 @@
self._seen_guard_not_invalidated = False
self.postponed_op = None
+ def setup(self):
+ self.optimizer.optheap = self
+
+ def value_updated(self, oldvalue, newvalue):
+ # XXXX very unhappy about that
+ for cf in self.cached_fields.itervalues():
+ cf.value_updated(oldvalue, newvalue)
+ for submap in self.cached_arrayitems.itervalues():
+ for cf in submap.itervalues():
+ cf.value_updated(oldvalue, newvalue)
+
def force_at_end_of_preamble(self):
self.cached_dict_reads.clear()
self.corresponding_array_descrs.clear()
@@ -360,16 +370,6 @@
# ^^^ we only need to force this field; the other fields
# of virtualref_info and virtualizable_info are not gcptrs.
- def turned_constant(self, value):
- assert value.is_constant()
- newvalue = self.getvalue(value.box)
- if value is not newvalue:
- for cf in self.cached_fields.itervalues():
- cf.turned_constant(newvalue, value)
- for submap in self.cached_arrayitems.itervalues():
- for cf in submap.itervalues():
- cf.turned_constant(newvalue, value)
-
def force_lazy_setfield(self, descr, can_cache=True):
try:
cf = self.cached_fields[descr]
diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -62,7 +62,6 @@
assert self.level <= LEVEL_NONNULL
if other.level == LEVEL_CONSTANT:
self.make_constant(other.get_key_box())
- optimizer.turned_constant(self)
elif other.level == LEVEL_KNOWNCLASS:
self.make_constant_class(other.get_known_class(), None)
else:
@@ -75,6 +74,11 @@
return [op]
return []
+ def copy_from(self, other_value):
+ assert isinstance(other_value, OptValue)
+ self.box = other_value.box
+ self.level = other_value.level
+
def force_box(self, optforce):
return self.box
@@ -204,6 +208,14 @@
if not isinstance(box, Const):
self.known_class = known_class
+ def copy_from(self, other_value):
+ assert isinstance(other_value, PtrOptValue)
+ self.box = other_value.box
+ self.known_class = other_value.known_class
+ self.level = other_value.level
+ self.last_guard = other_value.last_guard
+ self.lenbound = other_value.lenbound
+
def make_len_gt(self, mode, descr, val):
if self.lenbound:
assert self.lenbound.mode == mode
@@ -298,6 +310,12 @@
else:
self.intbound = IntUnbounded()
+ def copy_from(self, other_value):
+ assert isinstance(other_value, IntOptValue)
+ self.box = other_value.box
+ self.intbound = other_value.intbound
+ self.level = other_value.level
+
def make_constant(self, constbox):
"""Replace 'self.box' with a Const box."""
assert isinstance(constbox, ConstInt)
@@ -439,9 +457,6 @@
def setup(self):
pass
- def turned_constant(self, value):
- pass
-
def force_at_end_of_preamble(self):
pass
@@ -492,6 +507,7 @@
self.seen_results = {}
self.optimizer = self
self.optpure = None
+ self.optheap = None
self.optearlyforce = None
if loop is not None:
self.call_pure_results = loop.call_pure_results
@@ -527,10 +543,6 @@
for opt in self.optimizations:
opt.produce_potential_short_preamble_ops(sb)
- def turned_constant(self, value):
- for o in self.optimizations:
- o.turned_constant(value)
-
def forget_numberings(self, virtualbox):
self.metainterp_sd.profiler.count(jitprof.Counters.OPT_FORCINGS)
self.resumedata_memo.forget_numberings(virtualbox)
@@ -593,7 +605,17 @@
def make_equal_to(self, box, value, replace=False):
assert isinstance(value, OptValue)
- assert replace or box not in self.values
+ if replace:
+ try:
+ cur_value = self.values[box]
+ except KeyError:
+ pass
+ else:
+ assert value.level != LEVEL_CONSTANT
+ assert cur_value.level != LEVEL_CONSTANT
+ # replacing with a different box
+ cur_value.copy_from(value)
+ return
self.values[box] = value
def make_constant(self, box, constbox):
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -261,7 +261,8 @@
if emit_operation:
self.emit_operation(op)
value.make_constant(constbox)
- self.optimizer.turned_constant(value)
+ if self.optimizer.optheap:
+ self.optimizer.optheap.value_updated(value, self.getvalue(constbox))
def optimize_GUARD_ISNULL(self, op):
value = self.getvalue(op.getarg(0))
More information about the pypy-commit
mailing list