[pypy-commit] pypy optresult: fixes to vstring, we need unrolling otherwise it's chasing a wild goose :/

fijal noreply at buildbot.pypy.org
Thu Jun 4 17:42:04 CEST 2015


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: optresult
Changeset: r77862:17aa2869ed86
Date: 2015-06-04 17:42 +0200
http://bitbucket.org/pypy/pypy/changeset/17aa2869ed86/

Log:	fixes to vstring, we need unrolling otherwise it's chasing a wild
	goose :/

diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -150,6 +150,8 @@
         start_state = optimize_trace(metainterp_sd, jitdriver_sd, part,
                                      enable_opts, export_state=True)
     except InvalidLoop:
+        forget_optimization_info(part.operations)
+        forget_optimization_info(part.inputargs)
         return None
     target_token = part.operations[0].getdescr()
     assert isinstance(target_token, TargetToken)
@@ -238,6 +240,7 @@
                        jitdriver_sd.warmstate.enable_opts,
                        start_state=start_state, export_state=False)
     except InvalidLoop:
+        xxx # XXX forget optimizations
         # Fall back on jumping to preamble
         target_token = label.getdescr()
         assert isinstance(target_token, TargetToken)
@@ -250,6 +253,7 @@
                            inline_short_preamble=False, start_state=start_state,
                            export_state=False)
         except InvalidLoop:
+            xxx # XXX forget optimizations
             return None
     assert part.operations[-1].getopnum() != rop.LABEL
     target_token = label.getdescr()
@@ -374,12 +378,13 @@
                                             original_loop_token, log=log,
                                             logger=metainterp_sd.logger_ops)
 
-def forget_optimization_info(lst):
+def forget_optimization_info(lst, reset_values=False):
     for item in lst:
         item.set_forwarded(None)
         # XXX we should really do it, but we need to remember the values
         #     somehoe for ContinueRunningNormally
-        #item.reset_value()
+        if reset_values:
+            item.reset_value()
 
 def send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, type):
     forget_optimization_info(loop.operations)
@@ -916,6 +921,8 @@
                                state.enable_opts,
                                inline_short_preamble, export_state=True)
     except InvalidLoop:
+        forget_optimization_info(new_trace.operations)
+        forget_optimization_info(new_trace.inputargs)
         debug_print("compile_new_bridge: got an InvalidLoop")
         # XXX I am fairly convinced that optimize_bridge cannot actually raise
         # InvalidLoop
diff --git a/rpython/jit/metainterp/optimizeopt/info.py b/rpython/jit/metainterp/optimizeopt/info.py
--- a/rpython/jit/metainterp/optimizeopt/info.py
+++ b/rpython/jit/metainterp/optimizeopt/info.py
@@ -476,6 +476,11 @@
     @specialize.arg(2)
     def get_constant_string_spec(self, optforce, mode):
         return self._unpack_str(mode)
+
+    def getlenbound(self, mode):
+        from rpython.jit.metainterp.optimizeopt.intutils import ConstIntBound
+        
+        return ConstIntBound(self.getstrlen(None, None, mode))
     
     def getstrlen(self, op, string_optimizer, mode, create_ops=True):
         from rpython.jit.metainterp.optimizeopt import vstring
diff --git a/rpython/jit/metainterp/optimizeopt/intbounds.py b/rpython/jit/metainterp/optimizeopt/intbounds.py
--- a/rpython/jit/metainterp/optimizeopt/intbounds.py
+++ b/rpython/jit/metainterp/optimizeopt/intbounds.py
@@ -384,13 +384,17 @@
         self.emit_operation(op)
         self.make_nonnull_str(op.getarg(0), vstring.mode_string)
         array = self.getptrinfo(op.getarg(0))
-        self.get_box_replacement(op).set_forwarded(array.getlenbound())
+        new_op = self.get_box_replacement(op)
+        if not new_op.is_constant():
+            new_op.set_forwarded(array.getlenbound(vstring.mode_string))
 
     def optimize_UNICODELEN(self, op):
         self.emit_operation(op)
         self.make_nonnull_str(op.getarg(0), vstring.mode_unicode)
         array = self.getptrinfo(op.getarg(0))
-        self.get_box_replacement(op).set_forwarded(array.getlenbound())
+        new_op = self.get_box_replacement(op)
+        if not new_op.is_constant():
+            new_op.set_forwarded(array.getlenbound(vstring.mode_unicode))
 
     def optimize_STRGETITEM(self, op):
         self.emit_operation(op)
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
@@ -27,229 +27,6 @@
                 self.bound.contains_bound(other.bound))
 
 
-## class OptInfo(object):
-
-##     def getlevel(self):
-##         return self._tag & 0x3
-
-##     def setlevel(self, level):
-##         self._tag = (self._tag & (~0x3)) | level
-
-##     def import_from(self, other, optimizer):
-##         if self.getlevel() == LEVEL_CONSTANT:
-##             assert other.getlevel() == LEVEL_CONSTANT
-##             assert other.box.same_constant(self.box)
-##             return
-##         assert self.getlevel() <= LEVEL_NONNULL
-##         if other.getlevel() == LEVEL_CONSTANT:
-##             self.make_constant(other.get_key_box())
-##         elif other.getlevel() == LEVEL_KNOWNCLASS:
-##             self.make_constant_class(None, other.get_known_class())
-##         else:
-##             if other.getlevel() == LEVEL_NONNULL:
-##                 self.ensure_nonnull()
-
-##     def make_guards(self, box):
-##         if self.getlevel() == LEVEL_CONSTANT:
-##             op = ResOperation(rop.GUARD_VALUE, [box, self.box], None)
-##             return [op]
-##         return []
-
-##     def copy_from(self, other_value):
-##         assert isinstance(other_value, OptValue)
-##         self.box = other_value.box
-##         self._tag = other_value._tag
-
-##     def force_box(self, optforce):
-##         xxx
-##         return self.box
-
-##     def force_at_end_of_preamble(self, already_forced, optforce):
-##         return self
-
-##     # visitor API
-
-##     def visitor_walk_recursive(self, visitor):
-##         pass
-
-##     @specialize.argtype(1)
-##     def visitor_dispatch_virtual_type(self, visitor):
-##         if self.is_virtual():
-##             return self._visitor_dispatch_virtual_type(visitor)
-##         else:
-##             return visitor.visit_not_virtual(self)
-
-##     @specialize.argtype(1)
-##     def _visitor_dispatch_virtual_type(self, visitor):
-##         assert 0, "unreachable"
-
-##     def is_constant(self):
-##         return self.getlevel() == LEVEL_CONSTANT
-
-##     def is_null(self):
-##         if self.is_constant():
-##             box = self.box
-##             assert isinstance(box, Const)
-##             return not box.nonnull()
-##         return False
-
-##     def same_value(self, other):
-##         if not other:
-##             return False
-##         if self.is_constant() and other.is_constant():
-##             return self.box.same_constant(other.box)
-##         return self is other
-
-##     def is_nonnull(self):
-##         level = self.getlevel()
-##         if level == LEVEL_NONNULL or level == LEVEL_KNOWNCLASS:
-##             return True
-##         elif level == LEVEL_CONSTANT:
-##             box = self.box
-##             assert isinstance(box, Const)
-##             return box.nonnull()
-##         else:
-##             return False
-
-##     def ensure_nonnull(self):
-##         if self.getlevel() < LEVEL_NONNULL:
-##             self.setlevel(LEVEL_NONNULL)
-
-##     def get_constant_int(self):
-##         assert self.is_constant()
-##         box = self.box
-##         assert isinstance(box, ConstInt)
-##         return box.getint()
-
-##     def is_virtual(self):
-##         return False # overwridden in VirtualInfo
-
-##     def is_forced_virtual(self):
-##         return False
-
-##     def getfield(self, ofs, default):
-##         raise NotImplementedError
-
-##     def setfield(self, ofs, value):
-##         raise NotImplementedError
-
-##     def getlength(self):
-##         raise NotImplementedError
-
-##     def getitem(self, index):
-##         raise NotImplementedError
-
-##     def setitem(self, index, value):
-##         raise NotImplementedError
-
-##     def getitem_raw(self, offset, length, descr):
-##         raise NotImplementedError
-
-##     def setitem_raw(self, offset, length, descr, value):
-##         raise NotImplementedError
-
-##     def getinteriorfield(self, index, ofs, default):
-##         raise NotImplementedError
-
-##     def setinteriorfield(self, index, ofs, value):
-##         raise NotImplementedError
-
-##     def get_missing_null_value(self):
-##         raise NotImplementedError    # only for VArrayValue
-
-##     def make_constant(self, constbox):
-##         """Replace 'self.box' with a Const box."""
-##         assert isinstance(constbox, Const)
-##         self.box = constbox
-##         self.setlevel(LEVEL_CONSTANT)
-
-##     def get_last_guard(self, optimizer):
-##         return None
-
-##     def get_known_class(self):
-##         return None
-
-##     def getlenbound(self):
-##         return None
-
-##     def getintbound(self):
-##         return None
-
-##     def get_constant_class(self, cpu):
-##         return None
-
-
-## class IntOptInfo(OptInfo):
-##     _attrs_ = ('intbound',)
-
-##     def __init__(self, level=LEVEL_UNKNOWN, known_class=None, intbound=None):
-##         OptInfo.__init__(self, level, None, None)
-##         if intbound:
-##             self.intbound = intbound
-##         else:
-##             self.intbound = IntBound(MININT, MAXINT)
-
-##     def copy_from(self, other_value):
-##         assert isinstance(other_value, IntOptValue)
-##         self.box = other_value.box
-##         self.intbound = other_value.intbound
-##         self._tag = other_value._tag
-
-##     def make_constant(self, constbox):
-##         """Replace 'self.box' with a Const box."""
-##         assert isinstance(constbox, ConstInt)
-##         self.box = constbox
-##         self.setlevel(LEVEL_CONSTANT)
-##         val = constbox.getint()
-##         self.intbound = IntBound(val, val)
-
-##     def is_nonnull(self):
-##         if OptValue.is_nonnull(self):
-##             return True
-##         if self.intbound:
-##             if self.intbound.known_gt(IntBound(0, 0)) or \
-##                self.intbound.known_lt(IntBound(0, 0)):
-##                 return True
-##         return False
-
-##     def make_nonnull(self, optimizer):
-##         assert self.getlevel() < LEVEL_NONNULL
-##         self.setlevel(LEVEL_NONNULL)
-
-##     def import_from(self, other, optimizer):
-##         OptValue.import_from(self, other, optimizer)
-##         if self.getlevel() != LEVEL_CONSTANT:
-##             if other.getintbound() is not None: # VRawBufferValue
-##                 self.intbound.intersect(other.getintbound())
-
-##     def make_guards(self, box):
-##         guards = []
-##         level = self.getlevel()
-##         if level == LEVEL_CONSTANT:
-##             op = ResOperation(rop.GUARD_VALUE, [box, self.box], None)
-##             guards.append(op)
-##         elif level == LEVEL_KNOWNCLASS:
-##             op = ResOperation(rop.GUARD_NONNULL, [box], None)
-##             guards.append(op)
-##         else:
-##             if level == LEVEL_NONNULL:
-##                 op = ResOperation(rop.GUARD_NONNULL, [box], None)
-##                 guards.append(op)
-##             self.intbound.make_guards(box, guards)
-##         return guards
-
-##     def getintbound(self):
-##         return self.intbound
-
-##     def get_last_guard(self, optimizer):
-##         return None
-
-##     def get_known_class(self):
-##         return None
-
-##     def getlenbound(self):
-##         return None
-
 
 CONST_0      = ConstInt(0)
 CONST_1      = ConstInt(1)
diff --git a/rpython/jit/metainterp/optimizeopt/vstring.py b/rpython/jit/metainterp/optimizeopt/vstring.py
--- a/rpython/jit/metainterp/optimizeopt/vstring.py
+++ b/rpython/jit/metainterp/optimizeopt/vstring.py
@@ -62,7 +62,7 @@
         self.mode = mode
         self.length = length
 
-    def getlenbound(self):
+    def getlenbound(self, mode):
         from rpython.jit.metainterp.optimizeopt import intutils
 
         if self.lenbound is None:
@@ -123,7 +123,7 @@
         if not create_ops:
             return None
         lengthop = ResOperation(mode.STRLEN, [op])
-        lengthop.set_forwarded(self.getlenbound())
+        lengthop.set_forwarded(self.getlenbound(mode))
         self.lgtop = lengthop
         string_optimizer.emit_operation(lengthop)
         return lengthop
@@ -153,6 +153,7 @@
 
     def shrink(self, length):
         assert length >= 0
+        self.length = length
         del self._chars[length:]
 
     def setup_slice(self, longerlist, start, stop):
@@ -522,16 +523,8 @@
     def _optimize_NEWSTR(self, op, mode):
         length_box = self.get_constant_box(op.getarg(0))
         if length_box and length_box.getint() <= MAX_CONST_LEN:
-            # if the original 'op' did not have a ConstInt as argument,
-            # build a new one with the ConstInt argument
-            if not isinstance(op.getarg(0), ConstInt):
-                old_op = op
-                op = op.copy_and_change(mode.NEWSTR, [length_box])
-            else:
-                old_op = None
-            vvalue = self.make_vstring_plain(op, mode, length_box.getint())
-            if old_op is not None:
-                self.optimizer.make_equal_to(old_op, vvalue)
+            assert not op.get_forwarded()
+            self.make_vstring_plain(op, mode, length_box.getint())
         else:
             self.make_nonnull_str(op, mode)
             self.emit_operation(op)
@@ -601,12 +594,12 @@
         self._optimize_STRLEN(op, mode_unicode)
 
     def _optimize_STRLEN(self, op, mode):
-        #value = self.getvalue(op.getarg(0))
-        #lengthbox = value.getstrlen(self, mode, op)
-        #if op in self.optimizer.values:
-        #    assert self.getvalue(op) is self.getvalue(lengthbox)
-        #elif op is not lengthbox:
-        #    self.make_equal_to(op, self.getvalue(lengthbox))
+        opinfo = self.getptrinfo(op.getarg(0))
+        if opinfo:
+            lgtop = opinfo.getstrlen(op, self, mode, False)
+            if lgtop is not None:
+                self.make_equal_to(op, lgtop)
+                return
         self.emit_operation(op)
 
     def optimize_COPYSTRCONTENT(self, op):
diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -2887,8 +2887,7 @@
             assert i + 1 == len(self.virtualizable_boxes)
             # we're during tracing, so we should not execute it
             self.history.record(rop.SETFIELD_GC, [vbox, self.cpu.ts.CONST_NULL],
-                                self.cpu.ts.CONST_NULL.getref_base(),
-                                descr=vinfo.vable_token_descr)
+                                None, descr=vinfo.vable_token_descr)
 
     def replace_box(self, oldbox, newbox):
         for frame in self.framestack:


More information about the pypy-commit mailing list