Author: Maciej Fijalkowski <[email protected]>
Branch: optresult-unroll
Changeset: r79098:49ba7cf0f814
Date: 2015-08-21 11:52 +0200
http://bitbucket.org/pypy/pypy/changeset/49ba7cf0f814/
Log: pass the first test about mul_bridge_ovf1
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
@@ -225,27 +225,14 @@
call_pure_results=call_pure_results,
enable_opts=enable_opts)
try:
- try:
- start_state, preamble_ops = optimize_trace(metainterp_sd,
- jitdriver_sd,
- preamble_data)
- except InvalidLoop:
- return None
- finally:
- forget_optimization_info(ops)
- forget_optimization_info(inputargs)
+ start_state, preamble_ops = optimize_trace(metainterp_sd, jitdriver_sd,
+ preamble_data)
+ except InvalidLoop:
+ return None
- #loop = create_empty_loop(metainterp)
- #loop.inputargs = part.inputargs
- #loop.operations = part.operations
- #loop.quasi_immutable_deps = {}
- #if part.quasi_immutable_deps:
- # loop.quasi_immutable_deps.update(part.quasi_immutable_deps)
- #lastopnum = preamble_ops[-1].getopnum()
- #if lastopnum != rop.FINISH:
- #if start_state is not None:
- assert start_state is not None
- end_label = ResOperation(rop.LABEL, start_state.end_args,
+ metainterp_sd = metainterp.staticdata
+ jitdriver_sd = metainterp.jitdriver_sd
+ end_label = ResOperation(rop.LABEL, inputargs,
descr=jitcell_token)
jump_op = ResOperation(rop.JUMP, jumpargs, descr=jitcell_token)
loop_data = UnrolledLoopData(end_label, jump_op, ops, start_state,
@@ -279,44 +266,6 @@
send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, "loop")
record_loop_or_bridge(metainterp_sd, loop)
return start_descr
-
- #part.quasi_immutable_deps = None
- # part.operations = [part.operations[-1]] + \
- # [inliner.inline_op(h_ops[i]) for i in
range(start, len(h_ops))] + \
- # [ResOperation(rop.JUMP, [inliner.inline_arg(a)
for a in jumpargs],
- # None, descr=jitcell_token)]
- # target_token = part.operations[0].getdescr()
- # assert isinstance(target_token, TargetToken)
- # all_target_tokens.append(target_token)
- # inputargs = jumpargs
- # jumpargs = part.operations[-1].getarglist()
-
- # try:
- # optimize_trace(metainterp_sd, jitdriver_sd, part,
enable_opts,
- # start_state=start_state, export_state=False)
- # except InvalidLoop:
- # return None
-
- # loop.operations = loop.operations[:-1] + part.operations
- # if part.quasi_immutable_deps:
- # loop.quasi_immutable_deps.update(part.quasi_immutable_deps)
- # assert part.operations[-1].getopnum() != rop.LABEL
-
- # if not loop.quasi_immutable_deps:
- # loop.quasi_immutable_deps = None
- # for box in loop.inputargs:
- # assert not isinstance(box, Const)
-
- # loop.original_jitcell_token = jitcell_token
- # for label in all_target_tokens:
- # assert isinstance(label, TargetToken)
- # if label.virtual_state and label.short_preamble:
- # metainterp_sd.logger_ops.log_short_preamble([],
label.short_preamble)
- # jitcell_token.target_tokens = all_target_tokens
- # propagate_original_jitcell_token(loop)
- # send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, "loop")
- # record_loop_or_bridge(metainterp_sd, loop)
- # return all_target_tokens[0]
def compile_retrace(metainterp, greenkey, start,
inputargs, jumpargs,
@@ -324,7 +273,6 @@
"""Try to compile a new procedure by closing the current history back
to the first operation.
"""
- xxx
from rpython.jit.metainterp.optimizeopt import optimize_trace
history = metainterp.history
@@ -333,24 +281,21 @@
loop_jitcell_token = metainterp.get_procedure_token(greenkey)
assert loop_jitcell_token
- assert partial_trace.operations[-1].getopnum() == rop.LABEL
- part = create_empty_loop(metainterp)
- part.inputargs = inputargs[:]
- h_ops = history.operations
-
- part.operations = [partial_trace.operations[-1]] + \
- h_ops[start:] + \
- [ResOperation(rop.JUMP, jumpargs,
descr=loop_jitcell_token)]
- label = part.operations[0]
- orignial_label = label.clone()
- assert label.getopnum() == rop.LABEL
+ end_label = ResOperation(rop.LABEL, inputargs,
+ descr=loop_jitcell_token)
+ jump_op = ResOperation(rop.JUMP, jumpargs, descr=loop_jitcell_token)
+ enable_opts = jitdriver_sd.warmstate.enable_opts
+ ops = history.operations[start:]
+ call_pure_results = metainterp.call_pure_results
+ loop_data = UnrolledLoopData(end_label, jump_op, ops, start_state,
+ call_pure_results=call_pure_results,
+ enable_opts=enable_opts)
try:
- optimize_trace(metainterp_sd, jitdriver_sd, part,
- jitdriver_sd.warmstate.enable_opts,
- start_state=start_state, export_state=False)
+ loop_info, loop_ops = optimize_trace(metainterp_sd, jitdriver_sd,
+ loop_data)
except InvalidLoop:
- xxx # XXX forget optimizations
+ xxx
# Fall back on jumping to preamble
target_token = label.getdescr()
assert isinstance(target_token, TargetToken)
@@ -365,33 +310,29 @@
except InvalidLoop:
xxx # XXX forget optimizations
return None
- assert part.operations[-1].getopnum() != rop.LABEL
- target_token = label.getdescr()
- assert isinstance(target_token, TargetToken)
- assert loop_jitcell_token.target_tokens
- loop_jitcell_token.target_tokens.append(target_token)
- if target_token.short_preamble:
- metainterp_sd.logger_ops.log_short_preamble([],
target_token.short_preamble)
loop = partial_trace
- loop.operations = loop.operations[:-1] + part.operations
+ target_token = TargetToken(loop_jitcell_token)
+ target_token.original_jitcell_token = loop_jitcell_token
+ target_token.short_preamble = loop_info.short_preamble
+ target_token.virtual_state = start_state.virtual_state
+ loop_ops[-1].setdescr(target_token)
+ mid_label = ResOperation(rop.LABEL, loop_info.label_args,
+ descr=target_token)
+ loop.operations = (loop.operations + loop_info.extra_same_as + [mid_label]
+ + loop_ops)
+ loop_jitcell_token.target_tokens.append(target_token)
- quasi_immutable_deps = {}
- if loop.quasi_immutable_deps:
- quasi_immutable_deps.update(loop.quasi_immutable_deps)
- if part.quasi_immutable_deps:
- quasi_immutable_deps.update(part.quasi_immutable_deps)
- if quasi_immutable_deps:
- loop.quasi_immutable_deps = quasi_immutable_deps
+ #quasi_immutable_deps = {}
+ #if loop.quasi_immutable_deps:
+ # quasi_immutable_deps.update(loop.quasi_immutable_deps)
+ #if part.quasi_immutable_deps:
+ # quasi_immutable_deps.update(part.quasi_immutable_deps)
+ #if quasi_immutable_deps:
+ # loop.quasi_immutable_deps = quasi_immutable_deps
- for box in loop.inputargs:
- assert isinstance(box, Box)
-
- target_token = loop.operations[-1].getdescr()
resumekey.compile_and_attach(metainterp, loop)
- target_token = label.getdescr()
- assert isinstance(target_token, TargetToken)
record_loop_or_bridge(metainterp_sd, loop)
return target_token
@@ -1036,20 +977,18 @@
call_pure_results = metainterp.call_pure_results
if operations[-1].getopnum() == rop.JUMP:
+ jump_op = operations[-1]
data = BridgeCompileData(label, operations[:],
call_pure_results=call_pure_results,
enable_opts=enable_opts,
inline_short_preamble=inline_short_preamble)
else:
+ jump_op = None
data = SimpleCompileData(label, operations[:],
call_pure_results=call_pure_results,
enable_opts=enable_opts)
try:
- try:
- info, newops = optimize_trace(metainterp_sd, jitdriver_sd, data)
- finally:
- forget_optimization_info(inputargs)
- forget_optimization_info(operations)
+ info, newops = optimize_trace(metainterp_sd, jitdriver_sd, data)
except InvalidLoop:
debug_print("compile_new_bridge: got an InvalidLoop")
# XXX I am fairly convinced that optimize_bridge cannot actually raise
@@ -1058,24 +997,16 @@
return None
new_trace = create_empty_loop(metainterp)
- new_trace.inputargs = info.inputargs
new_trace.operations = newops
- target_token = new_trace.operations[-1].getdescr()
- resumekey.compile_and_attach(metainterp, new_trace)
- record_loop_or_bridge(metainterp_sd, new_trace)
- return target_token
- xxxx
- if new_trace.operations[-1].getopnum() != rop.LABEL:
- # We managed to create a bridge. Dispatch to resumekey to
- # know exactly what we must do (ResumeGuardDescr/ResumeFromInterpDescr)
+ if info.final():
+ new_trace.inputargs = info.inputargs
target_token = new_trace.operations[-1].getdescr()
resumekey.compile_and_attach(metainterp, new_trace)
record_loop_or_bridge(metainterp_sd, new_trace)
return target_token
- else:
- raise Exception("should not occur with tracing disabled")
- metainterp.retrace_needed(new_trace, state)
- return None
+ new_trace.inputargs = info.renamed_inputargs
+ metainterp.retrace_needed(new_trace, info)
+ return None
# ____________________________________________________________
diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py
b/rpython/jit/metainterp/optimizeopt/__init__.py
--- a/rpython/jit/metainterp/optimizeopt/__init__.py
+++ b/rpython/jit/metainterp/optimizeopt/__init__.py
@@ -58,6 +58,7 @@
return compile_data.optimize(metainterp_sd, jitdriver_sd,
optimizations, unroll)
finally:
+ compile_data.forget_optimization_info()
debug_stop("jit-optimize")
if __name__ == '__main__':
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,6 +27,9 @@
def __init__(self, inputargs):
self.inputargs = inputargs
+ def final(self):
+ return True
+
class Optimization(object):
next_optimization = None
@@ -337,7 +340,7 @@
return op
def is_inputarg(self, op):
- #return True
+ return True
return op in self.inparg_dict
def get_constant_box(self, box):
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py
b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -6,7 +6,7 @@
from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer,\
Optimization, LoopInfo, MININT, MAXINT
from rpython.jit.metainterp.optimizeopt.virtualstate import (
- VirtualStateConstructor)
+ VirtualStateConstructor, VirtualStatesCantMatch)
from rpython.jit.metainterp.resoperation import rop, ResOperation
class UnrollableOptimizer(Optimizer):
@@ -90,7 +90,7 @@
self._check_no_forwarding([[start_label, end_label], ops])
info, newops = self.optimizer.propagate_all_forward(
start_label.getarglist()[:], ops, call_pure_results)
- exported_state = self.export_state(start_label, end_label,
+ exported_state = self.export_state(start_label, end_label.getarglist(),
info.inputargs)
# we need to absolutely make sure that we've cleaned up all
# the optimization info
@@ -137,25 +137,43 @@
start_label.getarglist()[:], operations[:-1],
call_pure_results, True)
jump_op = operations[-1]
- self.jump_to_existing_trace(jump_op, inline_short_preamble)
- return info, self.optimizer._newoperations[:]
+ vs = self.jump_to_existing_trace(jump_op, inline_short_preamble)
+ if vs is None:
+ return info, self.optimizer._newoperations[:]
+ exported_state = self.export_state(start_label,
+ operations[-1].getarglist(),
+ info.inputargs)
+ self.optimizer._clean_optimization_info(self.optimizer._newoperations)
+ return exported_state, self.optimizer._newoperations
def jump_to_existing_trace(self, jump_op, inline_short_preamble):
jitcelltoken = jump_op.getdescr()
args = [self.get_box_replacement(op) for op in jump_op.getarglist()]
- target_token = jitcelltoken.target_tokens[0]
virtual_state = self.get_virtual_state(args)
- target_virtual_state = target_token.virtual_state
-
- short_preamble = target_token.short_preamble
- extra = self.inline_short_preamble(args,
- short_preamble[0].getarglist(), short_preamble[1:-1],
- short_preamble[-1].getarglist(), self.optimizer.patchguardop)
- self.send_extra_operation(jump_op.copy_and_change(rop.JUMP,
- args=args + extra,
- descr=jitcelltoken.target_tokens[0]))
+ infos = [self.optimizer.getinfo(arg) for arg in args]
+ for target_token in jitcelltoken.target_tokens:
+ target_virtual_state = target_token.virtual_state
+ if target_virtual_state is None:
+ continue
+ try:
+ extra_guards = target_virtual_state.generate_guards(
+ virtual_state, args, infos, self.optimizer.cpu)
+ assert not extra_guards.extra_guards
+ except VirtualStatesCantMatch:
+ continue
+ short_preamble = target_token.short_preamble
+ extra = self.inline_short_preamble(args,
+ short_preamble[0].getarglist(), short_preamble[1:-1],
+ short_preamble[-1].getarglist(), self.optimizer.patchguardop)
+ self.send_extra_operation(jump_op.copy_and_change(rop.JUMP,
+ args=args + extra,
+ descr=target_token))
+ return None # explicit because the return can be non-None
+ return virtual_state
def filter_extra_jump_args(self, label_args, jump_args):
+ label_args = [self.get_box_replacement(x) for x in label_args]
+ jump_args = [self.get_box_replacement(x) for x in jump_args]
new_label_args = []
new_jump_args = []
assert len(label_args) == len(jump_args)
@@ -190,8 +208,7 @@
op.set_forwarded(None)
return res
- def export_state(self, start_label, end_label, renamed_inputargs):
- original_label_args = end_label.getarglist()
+ def export_state(self, start_label, original_label_args,
renamed_inputargs):
end_args = [self.get_box_replacement(a) for a in original_label_args]
virtual_state = self.get_virtual_state(end_args)
inparg_mapping = [(start_label.getarg(i), end_args[i])
@@ -222,13 +239,15 @@
def import_state(self, targetop, exported_state):
# the mapping between input args (from old label) and what we need
# to actually emit. Update the info
- for source, target in exported_state.inputarg_mapping:
- if source is not target:
- source.set_forwarded(target)
- info = exported_state.exported_infos.get(target, None)
+ assert len(exported_state.inputarg_mapping) ==
len(targetop.getarglist())
+ for i, (s, target) in enumerate(exported_state.inputarg_mapping):
+ source = targetop.getarg(i)
+ assert source is not target
+ source.set_forwarded(target)
+ info = exported_state.exported_infos.get(source, None)
if info is not None:
self.optimizer.setinfo_from_preamble(source, info,
- exported_state.exported_infos)
+ exported_state.exported_infos)
# import the optimizer state, starting from boxes that can be produced
# by short preamble
self.short_preamble_producer = ShortPreambleBuilder(
@@ -262,6 +281,9 @@
self.short_preamble = short_preamble
self.label_args = label_args
self.extra_same_as = extra_same_as
+
+ def final(self):
+ return True
class ExportedState(LoopInfo):
""" Exported state consists of a few pieces of information:
@@ -289,3 +311,6 @@
self.short_boxes = short_boxes
self.renamed_inputargs = renamed_inputargs
self.short_inputargs = short_inputargs
+
+ def final(self):
+ return False
diff --git a/rpython/jit/metainterp/optimizeopt/virtualstate.py
b/rpython/jit/metainterp/optimizeopt/virtualstate.py
--- a/rpython/jit/metainterp/optimizeopt/virtualstate.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualstate.py
@@ -127,6 +127,7 @@
if box is not None:
fieldbox = opinfo._fields[self.fielddescrs[i].get_index()]
# must be there
+ xxx
fieldinfo = fieldbox.get_forwarded()
else:
fieldbox = None
@@ -205,6 +206,7 @@
if box is not None:
assert isinstance(opinfo, info.ArrayPtrInfo)
fieldbox = opinfo._items[i]
+ xxx
fieldinfo = fieldbox.get_forwarded()
self.fieldstate[i].generate_guards(other.fieldstate[i],
fieldbox, fieldinfo, state)
@@ -344,7 +346,8 @@
if self.level == LEVEL_UNKNOWN:
# confusingly enough, this is done also for pointers
# which have the full range as the "bound", so it always works
- return self._generate_guards_intbounds(other, box, extra_guards)
+ return self._generate_guards_intbounds(other, box, opinfo,
+ extra_guards)
# the following conditions often peek into the runtime value that the
# box had when tracing. This value is only used as an educated guess.
@@ -412,13 +415,13 @@
raise VirtualStatesCantMatch("other not constant")
assert 0, "unreachable"
- def _generate_guards_intbounds(self, other, boxinfo, extra_guards):
+ def _generate_guards_intbounds(self, other, box, opinfo, extra_guards):
if self.intbound is None:
return
if self.intbound.contains_bound(other.intbound):
return
- if (boxinfo is not None and isinstance(box, BoxInt) and
- self.intbound.contains(box.getint())):
+ if (opinfo is not None and opinfo.is_constant() and
+ self.intbound.contains(opinfo.getint())):
# this may generate a few more guards than needed, but they are
# optimized away when emitting them
self.intbound.make_guards(box, extra_guards)
@@ -502,11 +505,11 @@
return False
return True
- def generate_guards(self, other, values, cpu):
- assert len(self.state) == len(other.state) == len(values)
+ def generate_guards(self, other, boxes, infos, cpu):
+ assert len(self.state) == len(other.state) == len(boxes) == len(infos)
state = GenerateGuardState(cpu)
for i in range(len(self.state)):
- self.state[i].generate_guards(other.state[i], values[i],
+ self.state[i].generate_guards(other.state[i], boxes[i], infos[i],
state)
return state
diff --git a/rpython/jit/metainterp/test/test_ajit.py
b/rpython/jit/metainterp/test/test_ajit.py
--- a/rpython/jit/metainterp/test/test_ajit.py
+++ b/rpython/jit/metainterp/test/test_ajit.py
@@ -270,6 +270,7 @@
y -= 1
return res
res = self.meta_interp(f, [6, sys.maxint, 48])
+ self.check_trace_count(6)
assert res == f(6, sys.maxint, 48)
def test_loop_invariant_mul_bridge_ovf2(self):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit