[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