Author: Hakan Ardo <ha...@debian.org> Branch: jit-optimizeopt-cleanups Changeset: r47402:0fbcbb4e7bc7 Date: 2011-09-22 20:32 +0200 http://bitbucket.org/pypy/pypy/changeset/0fbcbb4e7bc7/
Log: pass strengthen guards down the optimization chain instead of modifying optimizer.newoperations directly 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 @@ -31,8 +31,8 @@ class OptValue(object): __metaclass__ = extendabletype - _attrs_ = ('box', 'known_class', 'last_guard_index', 'level', 'intbound', 'lenbound') - last_guard_index = -1 + _attrs_ = ('box', 'known_class', 'last_guard', 'level', 'intbound', 'lenbound') + last_guard = None level = LEVEL_UNKNOWN known_class = None @@ -100,7 +100,7 @@ self.make_constant(other.get_key_box()) optimizer.turned_constant(self) elif other.level == LEVEL_KNOWNCLASS: - self.make_constant_class(other.known_class, -1) + self.make_constant_class(other.known_class, None) else: if other.level == LEVEL_NONNULL: self.ensure_nonnull() @@ -162,16 +162,16 @@ else: return None - def make_constant_class(self, classbox, opindex): + def make_constant_class(self, classbox, guardop): assert self.level < LEVEL_KNOWNCLASS self.known_class = classbox self.level = LEVEL_KNOWNCLASS - self.last_guard_index = opindex + self.last_guard = guardop - def make_nonnull(self, opindex): + def make_nonnull(self, guardop): assert self.level < LEVEL_NONNULL self.level = LEVEL_NONNULL - self.last_guard_index = opindex + self.last_guard = guardop def is_nonnull(self): level = self.level @@ -331,6 +331,7 @@ self.exception_might_have_happened = False self.quasi_immutable_deps = None self.opaque_pointers = {} + self.replaces_guard = {} self.newoperations = [] if loop is not None: self.call_pure_results = loop.call_pure_results @@ -511,11 +512,27 @@ self.metainterp_sd.profiler.count(jitprof.OPT_OPS) if op.is_guard(): self.metainterp_sd.profiler.count(jitprof.OPT_GUARDS) - op = self.store_final_boxes_in_guard(op) + if self.replaces_guard and op in self.replaces_guard: + self.replace_op(self.replaces_guard[op], op) + del self.replaces_guard[op] + return + else: + op = self.store_final_boxes_in_guard(op) elif op.can_raise(): self.exception_might_have_happened = True self.newoperations.append(op) + def replace_op(self, old_op, new_op): + # XXX: Do we want to cache indexes to prevent search? + i = len(self.newoperations) + while i > 0: + i -= 1 + if self.newoperations[i] is old_op: + self.newoperations[i] = new_op + break + else: + assert False + def store_final_boxes_in_guard(self, op): descr = op.getdescr() assert isinstance(descr, compile.ResumeGuardDescr) diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py --- a/pypy/jit/metainterp/optimizeopt/rewrite.py +++ b/pypy/jit/metainterp/optimizeopt/rewrite.py @@ -263,30 +263,28 @@ elif value.is_null(): raise InvalidLoop self.emit_operation(op) - value.make_nonnull(len(self.optimizer.newoperations) - 1) + value.make_nonnull(op) def optimize_GUARD_VALUE(self, op): value = self.getvalue(op.getarg(0)) - emit_operation = True - if value.last_guard_index != -1: + if value.last_guard: # there already has been a guard_nonnull or guard_class or # guard_nonnull_class on this value, which is rather silly. # replace the original guard with a guard_value - old_guard_op = self.optimizer.newoperations[value.last_guard_index] - new_guard_op = old_guard_op.copy_and_change(rop.GUARD_VALUE, - args = [old_guard_op.getarg(0), op.getarg(1)]) - self.optimizer.newoperations[value.last_guard_index] = new_guard_op + old_guard_op = value.last_guard + op = old_guard_op.copy_and_change(rop.GUARD_VALUE, + args = [old_guard_op.getarg(0), op.getarg(1)]) + self.optimizer.replaces_guard[op] = old_guard_op # hack hack hack. Change the guard_opnum on # new_guard_op.getdescr() so that when resuming, # the operation is not skipped by pyjitpl.py. - descr = new_guard_op.getdescr() + descr = op.getdescr() assert isinstance(descr, compile.ResumeGuardDescr) descr.guard_opnum = rop.GUARD_VALUE - descr.make_a_counter_per_value(new_guard_op) - emit_operation = False + descr.make_a_counter_per_value(op) constbox = op.getarg(1) assert isinstance(constbox, Const) - self.optimize_guard(op, constbox, emit_operation) + self.optimize_guard(op, constbox) def optimize_GUARD_TRUE(self, op): self.optimize_guard(op, CONST_1) @@ -303,30 +301,24 @@ if realclassbox.same_constant(expectedclassbox): return raise InvalidLoop - emit_operation = True - if value.last_guard_index != -1: + if value.last_guard: # there already has been a guard_nonnull or guard_class or # guard_nonnull_class on this value. - old_guard_op = self.optimizer.newoperations[value.last_guard_index] + old_guard_op = value.last_guard if old_guard_op.getopnum() == rop.GUARD_NONNULL: # it was a guard_nonnull, which we replace with a # guard_nonnull_class. - new_guard_op = old_guard_op.copy_and_change (rop.GUARD_NONNULL_CLASS, + op = old_guard_op.copy_and_change (rop.GUARD_NONNULL_CLASS, args = [old_guard_op.getarg(0), op.getarg(1)]) - self.optimizer.newoperations[value.last_guard_index] = new_guard_op + self.optimizer.replaces_guard[op] = old_guard_op # hack hack hack. Change the guard_opnum on # new_guard_op.getdescr() so that when resuming, # the operation is not skipped by pyjitpl.py. - descr = new_guard_op.getdescr() + descr = op.getdescr() assert isinstance(descr, compile.ResumeGuardDescr) descr.guard_opnum = rop.GUARD_NONNULL_CLASS - emit_operation = False - if emit_operation: - self.emit_operation(op) - last_guard_index = len(self.optimizer.newoperations) - 1 - else: - last_guard_index = value.last_guard_index - value.make_constant_class(expectedclassbox, last_guard_index) + self.emit_operation(op) + value.make_constant_class(expectedclassbox, op) def optimize_GUARD_NONNULL_CLASS(self, op): value = self.getvalue(op.getarg(0)) diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -221,7 +221,6 @@ newop.setfailargs(self.getfailargs()) return newop - # ============ # arity mixins # ============ _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit