Author: Hakan Ardo <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit