Author: Hakan Ardo <ha...@debian.org> Branch: jit-short_from_state Changeset: r45642:f443c6b9ddb5 Date: 2011-07-15 19:38 +0200 http://bitbucket.org/pypy/pypy/changeset/f443c6b9ddb5/
Log: Setup the state of new optimizer chain for the peeled loop by emitting the short preamble operations. This becomes a lot simpler and less errorprone than trying to copy the exact subset of the preamble optimizer state that would corespond to having executed those ops in the (short) preamble. diff --git a/pypy/jit/metainterp/optimizeopt/fficall.py b/pypy/jit/metainterp/optimizeopt/fficall.py --- a/pypy/jit/metainterp/optimizeopt/fficall.py +++ b/pypy/jit/metainterp/optimizeopt/fficall.py @@ -86,6 +86,9 @@ debug_stop('jit-log-ffiopt') Optimization.propagate_end_forward(self) + def new(self): + return OptFfiCall() + def reconstruct_for_next_iteration(self, short_boxes, surviving_boxes, optimizer, valuemap): return OptFfiCall() 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 @@ -163,6 +163,9 @@ def flush(self): self.force_all_lazy_setfields_and_arrayitems() + + def new(self): + return OptHeap() def reconstruct_for_next_iteration(self, short_boxes, surviving_boxes, optimizer, valuemap): @@ -170,7 +173,7 @@ for descr, d in self.cached_fields.items(): new.cached_fields[descr] = d.get_cloned(optimizer, valuemap, short_boxes) - + for descr, submap in self.cached_arrayitems.items(): newdict = {} for index, d in submap.items(): diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py --- a/pypy/jit/metainterp/optimizeopt/intbounds.py +++ b/pypy/jit/metainterp/optimizeopt/intbounds.py @@ -13,6 +13,10 @@ self.posponedop = None self.nextop = None + def new(self): + assert self.posponedop is None + return OptIntBounds() + def reconstruct_for_next_iteration(self, short_boxes, surviving_boxes, optimizer, valuemap): assert self.posponedop is None 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 @@ -303,6 +303,9 @@ pass # It is too late to force stuff here, it must be done in force_at_end_of_preamble + def new(self): + raise NotImplementedError + def reconstruct_for_next_iteration(self, short_boxes, surviving_boxes=None, optimizer=None, valuemap=None): raise NotImplementedError @@ -335,6 +338,7 @@ self.exception_might_have_happened = False self.quasi_immutable_deps = None self.newoperations = [] + self.emitting_dissabled = False if loop is not None: self.call_pure_results = loop.call_pure_results @@ -363,7 +367,15 @@ for o in self.optimizations: o.flush() assert self.posponedop is None - + + def new(self): + assert self.posponedop is None + new = Optimizer(self.metainterp_sd, self.loop) + optimizations = [o.new() for o in self.optimizations] + new.set_optimizations(optimizations) + new.quasi_immutable_deps = self.quasi_immutable_deps + return new + def reconstruct_for_next_iteration(self, short_boxes, surviving_boxes=None, optimizer=None, valuemap=None): assert optimizer is None @@ -575,10 +587,11 @@ return True def emit_operation(self, op): - ###self.heap_op_optimizer.emitting_operation(op) - self._emit_operation(op) - - def _emit_operation(self, op): + if op.returns_bool_result(): + self.bool_boxes[self.getvalue(op.result)] = None + if self.emitting_dissabled: + return + for i in range(op.numargs()): arg = op.getarg(i) if arg in self.values: @@ -590,8 +603,6 @@ op = self.store_final_boxes_in_guard(op) elif op.can_raise(): self.exception_might_have_happened = True - elif op.returns_bool_result(): - self.bool_boxes[self.getvalue(op.result)] = None self.newoperations.append(op) def store_final_boxes_in_guard(self, op): 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 @@ -14,8 +14,11 @@ """ def __init__(self): self.loop_invariant_results = {} - self.loop_invariant_producer = {} + self.loop_invariant_producer = {} + def new(self): + return OptRewrite() + def reconstruct_for_next_iteration(self, short_boxes, surviving_boxes, optimizer, valuemap): new = OptRewrite() @@ -24,7 +27,7 @@ value.get_cloned(new, valuemap) return new - def produce_potential_short_preamble_ops(self, potential_ops): + def produce_potential_short_preamble_ops(self, potential_ops): for op in self.loop_invariant_producer.values(): potential_ops[op.result] = op diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py @@ -5092,32 +5092,38 @@ def test_invariant_ovf(self): ops = """ - [i0, i1, i10, i11, i12] + [i0, i1, i10, i11, i20, i21] i2 = int_add_ovf(i0, i1) guard_no_overflow() [] i3 = int_sub_ovf(i0, i1) guard_no_overflow() [] i4 = int_mul_ovf(i0, i1) guard_no_overflow() [] + escape(i2) + escape(i3) + escape(i4) i24 = int_mul_ovf(i10, i11) guard_no_overflow() [] i23 = int_sub_ovf(i10, i11) guard_no_overflow() [] i22 = int_add_ovf(i10, i11) guard_no_overflow() [] - jump(i0, i1, i2, i3, i4) - """ - expected = """ - [i0, i1, i10, i11, i12] + jump(i0, i1, i20, i21, i20, i21) + """ + expected = """ + [i0, i1, i10, i11, i2, i3, i4] + escape(i2) + escape(i3) + escape(i4) i24 = int_mul_ovf(i10, i11) guard_no_overflow() [] i23 = int_sub_ovf(i10, i11) guard_no_overflow() [] i22 = int_add_ovf(i10, i11) guard_no_overflow() [] - jump(i0, i1, i10, i11, i12) - """ - self.optimize_loop(ops, expected, ops) + jump(i0, i1, i10, i11, i2, i3, i4) + """ + self.optimize_loop(ops, expected) def test_value_proven_to_be_constant_after_two_iterations(self): class FakeDescr(AbstractDescr): @@ -6213,6 +6219,22 @@ self.optimize_loop(ops, expected, ops) # FIXME: check jumparg 0 == getfield_gc() + def test_constant_getfield1bis(self): + ops = """ + [p1, p187, i184] + p188 = getarrayitem_gc(p187, 42, descr=<GcPtrArrayDescr>) + guard_value(p188, ConstPtr(myptr)) [] + p25 = getfield_gc(ConstPtr(myptr), descr=otherdescr) + p26 = call(p25, descr=nonwritedescr) + jump(p26, p187, i184) + """ + expected = """ + [p24, p187, i184, p25] + p26 = call(p25, descr=nonwritedescr) + jump(p26, p187, i184, p25) + """ + self.optimize_loop(ops, expected) + def test_constant_getfield2(self): ops = """ [p19] diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py --- a/pypy/jit/metainterp/optimizeopt/unroll.py +++ b/pypy/jit/metainterp/optimizeopt/unroll.py @@ -147,9 +147,6 @@ snapshot_args = snapshot.boxes new_snapshot_args = [] for a in snapshot_args: - if not isinstance(a, Const): - a = loop.preamble.inputargs[jump_args.index(a)] - a = self.inliner.inline_arg(a) a = self.getvalue(a).get_key_box() new_snapshot_args.append(a) prev = self.fix_snapshot(loop, jump_args, snapshot.prev) @@ -173,13 +170,21 @@ self.optimizer.flush() KillHugeIntBounds(self.optimizer).apply() + + loop.preamble.operations = self.optimizer.newoperations + jump_args = [self.getvalue(a).get_key_box() for a in jump_args] - loop.preamble.operations = self.optimizer.newoperations + start_resumedescr = loop.preamble.start_resumedescr.clone_if_mutable() + self.start_resumedescr = start_resumedescr + assert isinstance(start_resumedescr, ResumeGuardDescr) + start_resumedescr.rd_snapshot = self.fix_snapshot(loop, jump_args, + start_resumedescr.rd_snapshot) modifier = VirtualStateAdder(self.optimizer) virtual_state = modifier.get_virtual_state(jump_args) values = [self.getvalue(arg) for arg in jump_args] inputargs = virtual_state.make_inputargs(values) + short_inputargs = virtual_state.make_inputargs(values, keyboxes=True) self.constant_inputargs = {} for box in jump_args: @@ -193,21 +198,44 @@ preamble_optimizer = self.optimizer loop.preamble.quasi_immutable_deps = ( self.optimizer.quasi_immutable_deps) - self.optimizer = self.optimizer.reconstruct_for_next_iteration(sb, jump_args) + self.optimizer = self.optimizer.new() loop.quasi_immutable_deps = self.optimizer.quasi_immutable_deps + # Force virtuals amoung the jump_args of the preamble to get the + # operations needed to setup the proper state of those virtuals + # in the peeled loop + inputarg_setup_ops = [] + preamble_optimizer.newoperations = [] + for box in short_inputargs: + value = preamble_optimizer.getvalue(box) + if value.is_virtual(): + value.force_box() + else: + inputarg_setup_ops.extend(value.make_guards(box)) + preamble_optimizer.flush() + inputarg_setup_ops += preamble_optimizer.newoperations + + # Setup the state of the new optimizer by emiting the + # short preamble operations and discarding the result + self.optimizer.emitting_dissabled = True + for op in inputarg_setup_ops: + self.optimizer.send_extra_operation(op) + seen = {} + for op in self.short_boxes.values(): + self.ensure_short_op_emitted(op, self.optimizer, seen) + if op and op.result: + value = preamble_optimizer.getvalue(op.result) + for guard in value.make_guards(op.result): + self.optimizer.send_extra_operation(guard) + self.optimizer.flush() + self.optimizer.emitting_dissabled = False + initial_inputargs_len = len(inputargs) self.inliner = Inliner(loop.inputargs, jump_args) - start_resumedescr = loop.preamble.start_resumedescr.clone_if_mutable() - self.start_resumedescr = start_resumedescr - assert isinstance(start_resumedescr, ResumeGuardDescr) - start_resumedescr.rd_snapshot = self.fix_snapshot(loop, jump_args, - start_resumedescr.rd_snapshot) - - inputargs, short_inputargs, short = self.inline(self.cloned_operations, - loop.inputargs, jump_args, - virtual_state) + short = self.inline(inputargs, self.cloned_operations, + loop.inputargs, short_inputargs, + virtual_state) #except KeyError: # debug_print("Unrolling failed.") @@ -267,13 +295,10 @@ if op.result: op.result.forget_value() - def inline(self, loop_operations, loop_args, jump_args, virtual_state): + def inline(self, inputargs, loop_operations, loop_args, short_inputargs, virtual_state): inliner = self.inliner - values = [self.getvalue(arg) for arg in jump_args] - inputargs = virtual_state.make_inputargs(values) short_jumpargs = inputargs[:] - short_inputargs = virtual_state.make_inputargs(values, keyboxes=True) short = [] short_seen = {} @@ -360,8 +385,22 @@ raise InvalidLoop debug_stop('jit-log-virtualstate') - return inputargs, short_inputargs, short + return short + def ensure_short_op_emitted(self, op, optimizer, seen): + if op is None: + return + if op.result is not None and op.result in seen: + return + for a in op.getarglist(): + if not isinstance(a, Const) and a not in seen: + self.ensure_short_op_emitted(self.short_boxes[a], optimizer, seen) + optimizer.send_extra_operation(op) + seen[op.result] = True + if op.is_ovf(): + guard = ResOperation(rop.GUARD_NO_OVERFLOW, [], None) + optimizer.send_extra_operation(guard) + def add_op_to_short(self, op, short, short_seen, emit=True, guards_needed=False): if op is None: return None @@ -656,7 +695,10 @@ class OptInlineShortPreamble(Optimization): def __init__(self, retraced): self.retraced = retraced - + + def new(self): + return OptInlineShortPreamble(self.retraced) + def reconstruct_for_next_iteration(self, short_boxes, surviving_boxes, optimizer, valuemap): return OptInlineShortPreamble(self.retraced) 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 @@ -311,6 +311,9 @@ class OptVirtualize(optimizer.Optimization): "Virtualize objects until they escape." + def new(self): + return OptVirtualize() + def reconstruct_for_next_iteration(self, short_boxes, surviving_boxes, optimizer, valuemap): return OptVirtualize() diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py b/pypy/jit/metainterp/optimizeopt/vstring.py --- a/pypy/jit/metainterp/optimizeopt/vstring.py +++ b/pypy/jit/metainterp/optimizeopt/vstring.py @@ -366,6 +366,9 @@ "Handling of strings and unicodes." enabled = True + def new(self): + return OptString() + def reconstruct_for_next_iteration(self, short_boxes, surviving_boxes, optimizer, valuemap): return OptString() _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit