[pypy-svn] pypy jit-str_in_preamble: proper cloning of values when transferin them to next iteration

hakanardo commits-noreply at bitbucket.org
Sun Mar 27 12:36:20 CEST 2011


Author: Hakan Ardo <hakan at debian.org>
Branch: jit-str_in_preamble
Changeset: r42980:025d79e40a22
Date: 2011-03-27 12:35 +0200
http://bitbucket.org/pypy/pypy/changeset/025d79e40a22/

Log:	proper cloning of values when transferin them to next iteration

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
@@ -90,12 +90,12 @@
             fieldvalue  = optheap.getvalue(op.getarg(1))
             self.remember_field_value(structvalue, fieldvalue)
 
-    def get_reconstructed(self, optimizer, valuemap):
+    def get_cloned(self, optimizer, valuemap):
         assert self._lazy_setfield is None
         cf = CachedField()
         for structvalue, fieldvalue in self._cached_fields.iteritems():
-            structvalue2 = structvalue.get_reconstructed(optimizer, valuemap)
-            fieldvalue2  = fieldvalue .get_reconstructed(optimizer, valuemap)
+            structvalue2 = structvalue.get_cloned(optimizer, valuemap)
+            fieldvalue2  = fieldvalue .get_cloned(optimizer, valuemap)
             cf._cached_fields[structvalue2] = fieldvalue2
         return cf
 
@@ -130,7 +130,7 @@
             assert 0   # was: new.lazy_setfields = self.lazy_setfields
         
         for descr, d in self.cached_fields.items():
-            new.cached_fields[descr] = d.get_reconstructed(optimizer, valuemap)
+            new.cached_fields[descr] = d.get_cloned(optimizer, valuemap)
 
         new.cached_arrayitems = {}
         for descr, d in self.cached_arrayitems.items():
@@ -138,16 +138,17 @@
             new.cached_arrayitems[descr] = newd
             for value, cache in d.items():
                 newcache = CachedArrayItems()
-                newd[value.get_reconstructed(optimizer, valuemap)] = newcache
+                newd[value.get_cloned(optimizer, valuemap)] = newcache
                 if cache.var_index_item:
                     newcache.var_index_item = \
-                          cache.var_index_item.get_reconstructed(optimizer, valuemap)
+                          cache.var_index_item.get_cloned(optimizer, valuemap)
                 if cache.var_index_indexvalue:
                     newcache.var_index_indexvalue = \
-                          cache.var_index_indexvalue.get_reconstructed(optimizer, valuemap)
+                          cache.var_index_indexvalue.get_cloned(optimizer,
+                                                                valuemap)
                 for index, fieldvalue in cache.fixed_index_items.items():
                     newcache.fixed_index_items[index] = \
-                           fieldvalue.get_reconstructed(optimizer, valuemap)
+                           fieldvalue.get_cloned(optimizer, valuemap)
 
         return new
 

diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -32,9 +32,16 @@
     known_class = None
     intbound = None
 
-    def __init__(self, box):
+    def __init__(self, box, level=None, known_class=None, intbound=None):
         self.box = box
-        self.intbound = IntBound(MININT, MAXINT) #IntUnbounded()
+        if level is not None:
+            self.level = level
+        self.known_class = known_class
+        if intbound:
+            self.intbound = intbound
+        else:
+            self.intbound = IntBound(MININT, MAXINT) #IntUnbounded()
+
         if isinstance(box, Const):
             self.make_constant(box)
         # invariant: box is a Const if and only if level == LEVEL_CONSTANT
@@ -51,23 +58,27 @@
             boxes.append(self.force_box())
             already_seen[self.get_key_box()] = None
 
-    def get_reconstructed(self, optimizer, valuemap, force_if_needed=True):
+    def get_cloned(self, optimizer, valuemap, force_if_needed=True):
         if self in valuemap:
             return valuemap[self]
-        new = self.reconstruct_for_next_iteration(optimizer)
+        new = self.clone_for_next_iteration(optimizer)
         if new is None:
             if force_if_needed:
                 new = OptValue(self.force_box())
             else:
                 return None
+        else:
+            assert new.__class__ is self.__class__
+            assert new.is_virtual() == self.is_virtual()            
         valuemap[self] = new
-        self.reconstruct_childs(new, valuemap)
+        self.clone_childs(new, valuemap)
         return new
 
-    def reconstruct_for_next_iteration(self, optimizer):
-        return self
+    def clone_for_next_iteration(self, optimizer):
+        return OptValue(self.box, self.level, self.known_class,
+                        self.intbound.clone())
 
-    def reconstruct_childs(self, new, valuemap):
+    def clone_childs(self, new, valuemap):
         pass
 
     def get_args_for_fail(self, modifier):
@@ -166,6 +177,9 @@
     def __init__(self, box):
         self.make_constant(box)
 
+    def clone_for_next_iteration(self, optimizer):
+        return self
+
 CONST_0      = ConstInt(0)
 CONST_1      = ConstInt(1)
 CVAL_ZERO    = ConstantValue(CONST_0)
@@ -305,13 +319,13 @@
         new.interned_refs = self.interned_refs
         new.bool_boxes = {}
         for value in new.bool_boxes.keys():
-            new.bool_boxes[value.get_reconstructed(new, valuemap)] = None
+            new.bool_boxes[value.get_cloned(new, valuemap)] = None
 
         # FIXME: Move to rewrite.py
         new.loop_invariant_results = {}
         for key, value in self.loop_invariant_results.items():
             new.loop_invariant_results[key] = \
-                                 value.get_reconstructed(new, valuemap)
+                                 value.get_cloned(new, valuemap)
 
         new.pure_operations = self.pure_operations
         new.producer = self.producer
@@ -320,8 +334,8 @@
         for box, value in self.values.items():
             box = new.getinterned(box)
             force = box in surviving_boxes
-            value = value.get_reconstructed(new, valuemap,
-                                            force_if_needed=force)
+            value = value.get_cloned(new, valuemap,
+                                     force_if_needed=force)
             if value is not None:
                 new.values[box] = value
             

diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py
--- a/pypy/jit/metainterp/optimizeopt/virtualize.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualize.py
@@ -46,7 +46,7 @@
     def _really_force(self):
         raise NotImplementedError("abstract base")
 
-    def reconstruct_for_next_iteration(self, _optimizer):
+    def clone_for_next_iteration(self, _optimizer):
         return None
 
 def get_fielddescrlist_cache(cpu):
@@ -144,17 +144,16 @@
         else:
             boxes.append(self.box)
 
-    def reconstruct_for_next_iteration(self, optimizer):
-        self.optimizer = optimizer
-        return self
+    def clone_for_next_iteration(self, optimizer):
+        raise NotImplementedError
 
-    def reconstruct_childs(self, new, valuemap):
+    def clone_childs(self, new, valuemap):
         assert isinstance(new, AbstractVirtualStructValue)
         if new.box is None:
             lst = self._get_field_descr_list()
             for ofs in lst:
                 new._fields[ofs] = \
-                      self._fields[ofs].get_reconstructed(new.optimizer, valuemap)
+                      self._fields[ofs].get_cloned(new.optimizer, valuemap)
 
 class VirtualValue(AbstractVirtualStructValue):
     level = optimizer.LEVEL_KNOWNCLASS
@@ -175,6 +174,12 @@
         field_names = [field.name for field in self._fields]
         return "<VirtualValue cls=%s fields=%s>" % (cls_name, field_names)
 
+    def clone_for_next_iteration(self, optimizer):
+        new = VirtualValue(optimizer, self.known_class, self.keybox,
+                           self.source_op)
+        new.box = self.box
+        return new
+
 class VStructValue(AbstractVirtualStructValue):
 
     def __init__(self, optimizer, structdescr, keybox, source_op=None):
@@ -185,6 +190,12 @@
         fielddescrs = self._get_field_descr_list()
         return modifier.make_vstruct(self.structdescr, fielddescrs)
 
+    def clone_for_next_iteration(self, optimizer):
+        new = VStructValue(optimizer, self.structdescr, self.keybox,
+                           self.source_op)
+        new.box = self.box
+        return new
+
 class VArrayValue(AbstractVirtualValue):
 
     def __init__(self, optimizer, arraydescr, size, keybox, source_op=None):
@@ -247,16 +258,18 @@
         else:
             boxes.append(self.box)
 
-    def reconstruct_for_next_iteration(self, optimizer):
-        self.optimizer = optimizer
-        return self
+    def clone_for_next_iteration(self, optimizer):
+        new = VArrayValue(optimizer, self.arraydescr, len(self._items),
+                          self.keybox, self.source_op)
+        new.box = self.box
+        return new        
 
-    def reconstruct_childs(self, new, valuemap):
+    def clone_childs(self, new, valuemap):
         assert isinstance(new, VArrayValue)
         if new.box is None:
             for i in range(len(self._items)):
-                new._items[i] = self._items[i].get_reconstructed(new.optimizer,
-                                                                 valuemap)
+                new._items[i] = self._items[i].get_cloned(new.optimizer,
+                                                          valuemap)
 
 class OptVirtualize(optimizer.Optimization):
     "Virtualize objects until they escape."


More information about the Pypy-commit mailing list