Author: Hakan Ardo <ha...@debian.org> Branch: jit-targets Changeset: r48821:cb3302d943c7 Date: 2011-11-06 14:09 +0100 http://bitbucket.org/pypy/pypy/changeset/cb3302d943c7/
Log: Rename ProcedureToken to JitCellToken. It now refers to all compiled traces starting from a specific JitCell and it is used as a decsr of jumps produced by the frontend to indicate the target of the jump. The optimizer will the convert this to a jump to a TargetToken (which refers to a specific label in an already compiled trace). If that is not yet possible it will be converted into a label resop with a new TargetTocken diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py --- a/pypy/jit/metainterp/compile.py +++ b/pypy/jit/metainterp/compile.py @@ -9,7 +9,7 @@ from pypy.tool.sourcetools import func_with_new_name from pypy.jit.metainterp.resoperation import ResOperation, rop, get_deep_immutable_oplist -from pypy.jit.metainterp.history import TreeLoop, Box, History, ProcedureToken, TargetToken +from pypy.jit.metainterp.history import TreeLoop, Box, History, JitCellToken, TargetToken from pypy.jit.metainterp.history import AbstractFailDescr, BoxInt from pypy.jit.metainterp.history import BoxPtr, BoxObj, BoxFloat, Const from pypy.jit.metainterp import history @@ -47,7 +47,7 @@ def make_procedure_token(jitdriver_sd): - procedure_token = ProcedureToken() + procedure_token = JitCellToken() procedure_token.outermost_jitdriver_sd = jitdriver_sd return procedure_token @@ -68,7 +68,7 @@ n = descr.index if n >= 0: # we also record the resumedescr number looptoken.compiled_loop_token.record_faildescr_index(n) - elif isinstance(descr, ProcedureToken): + elif isinstance(descr, JitCellToken): assert False, "FIXME" elif isinstance(descr, TargetToken): # for a JUMP or a CALL_ASSEMBLER: record it as a potential jump. @@ -285,7 +285,7 @@ raise metainterp_sd.ExitFrameWithExceptionRef(cpu, value) -class TerminatingLoopToken(ProcedureToken): # FIXME:!! +class TerminatingLoopToken(JitCellToken): # FIXME: kill? terminating = True def __init__(self, nargs, finishdescr): diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py --- a/pypy/jit/metainterp/history.py +++ b/pypy/jit/metainterp/history.py @@ -727,7 +727,7 @@ # of operations. Each branch ends in a jump which can go either to # the top of the same loop, or to another TreeLoop; or it ends in a FINISH. -class ProcedureToken(AbstractDescr): +class JitCellToken(AbstractDescr): """Used for rop.JUMP, giving the target of the jump. This is different from TreeLoop: the TreeLoop class contains the whole loop, including 'operations', and goes away after the loop @@ -766,19 +766,22 @@ self.compiled_loop_token.cpu.dump_loop_token(self) class TargetToken(AbstractDescr): - def __init__(self, procedure_token): - self.procedure_token = procedure_token + def __init__(self, cell_token): + self.cell_token = cell_token self.virtual_state = None self.exported_state = None class TreeLoop(object): inputargs = None operations = None - token = None call_pure_results = None logops = None quasi_immutable_deps = None + def _token(*args): + raise Exception("TreeLoop.token is killed") + token = property(_token, _token) + def __init__(self, name): self.name = name # self.operations = list of ResOperations 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 @@ -7,7 +7,7 @@ from pypy.jit.metainterp.optimizeopt import optimize_loop_1, ALL_OPTS_DICT, build_opt_chain from pypy.jit.metainterp.optimize import InvalidLoop from pypy.jit.metainterp.history import AbstractDescr, ConstInt, BoxInt -from pypy.jit.metainterp.history import TreeLoop, ProcedureToken, TargetToken +from pypy.jit.metainterp.history import TreeLoop, JitCellToken, TargetToken from pypy.jit.metainterp.jitprof import EmptyProfiler from pypy.jit.metainterp import executor, compile, resume, history from pypy.jit.metainterp.resoperation import rop, opname, ResOperation @@ -92,19 +92,22 @@ preamble.inputargs = inputargs preamble.start_resumedescr = FakeDescr() - token = ProcedureToken() + token = JitCellToken() preamble.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(token))] + \ operations + \ - [ResOperation(rop.LABEL, jump_args, None, descr=TargetToken(token))] + [ResOperation(rop.JUMP, jump_args, None, descr=token)] self._do_optimize_loop(preamble, call_pure_results) + assert preamble.operations[-1].getopnum() == rop.LABEL + inliner = Inliner(inputargs, jump_args) loop.start_resumedescr = preamble.start_resumedescr loop.operations = [preamble.operations[-1]] + \ [inliner.inline_op(op, clone=False) for op in cloned_operations] + \ - [ResOperation(rop.LABEL, [inliner.inline_arg(a) for a in jump_args], - None, descr=TargetToken(token))] + [ResOperation(rop.JUMP, [inliner.inline_arg(a) for a in jump_args], + None, descr=token)] #[inliner.inline_op(jumpop)] + assert loop.operations[-1].getopnum() == rop.JUMP assert loop.operations[0].getopnum() == rop.LABEL loop.inputargs = loop.operations[0].getarglist() 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 @@ -1,7 +1,7 @@ from pypy.jit.codewriter.effectinfo import EffectInfo from pypy.jit.metainterp.optimizeopt.virtualstate import VirtualStateAdder, ShortBoxes from pypy.jit.metainterp.compile import ResumeGuardDescr -from pypy.jit.metainterp.history import TreeLoop, TargetToken +from pypy.jit.metainterp.history import TreeLoop, TargetToken, JitCellToken from pypy.jit.metainterp.jitexc import JitException from pypy.jit.metainterp.optimize import InvalidLoop, RetraceLoop from pypy.jit.metainterp.optimizeopt.optimizer import * @@ -67,6 +67,7 @@ loop = self.optimizer.loop self.optimizer.clear_newoperations() + start_label = loop.operations[0] if start_label.getopnum() == rop.LABEL: loop.operations = loop.operations[1:] @@ -75,39 +76,31 @@ self.optimizer.send_extra_operation(start_label) else: start_label = None - - stop_label = loop.operations[-1] - if stop_label.getopnum() == rop.LABEL: - loop.operations = loop.operations[:-1] - else: - stop_label = None + + jumpop = loop.operations[-1] + assert jumpop.getopnum() == rop.JUMP + loop.operations = loop.operations[:-1] self.import_state(start_label) self.optimizer.propagate_all_forward(clear=False) - if not stop_label: - self.optimizer.flush() - loop.operations = self.optimizer.get_newoperations() + if self.jump_to_already_compiled_trace(jumpop): return - elif not start_label: - try: - self.optimizer.send_extra_operation(stop_label) - except RetraceLoop: - pass - else: - self.optimizer.flush() - loop.operations = self.optimizer.get_newoperations() - return + # Failed to find a compiled trace to jump to, produce a label instead + cell_token = jumpop.getdescr() + assert isinstance(cell_token, JitCellToken) + stop_label = ResOperation(rop.LABEL, jumpop.getarglist(), None, TargetToken(cell_token)) + if not self.did_peel_one: # Enforce the previous behaviour of always peeling exactly one iteration (for now) self.optimizer.flush() KillHugeIntBounds(self.optimizer).apply() loop.operations = self.optimizer.get_newoperations() self.export_state(stop_label) - loop.operations.append(stop_label) + loop.operations.append(stop_label) else: - assert stop_label.getdescr().procedure_token is start_label.getdescr().procedure_token + assert stop_label.getdescr().cell_token is start_label.getdescr().cell_token jumpop = ResOperation(rop.JUMP, stop_label.getarglist(), None, descr=start_label.getdescr()) self.close_loop(jumpop) @@ -430,8 +423,82 @@ if box in self.optimizer.values: box = self.optimizer.values[box].force_box(self.optimizer) jumpargs.append(box) + + def jump_to_already_compiled_trace(self, jumpop): + assert jumpop.getopnum() == rop.JUMP + cell_token = jumpop.getdescr() + + assert isinstance(cell_token, JitCellToken) + if not cell_token.target_tokens: + return False + + args = jumpop.getarglist() + modifier = VirtualStateAdder(self.optimizer) + virtual_state = modifier.get_virtual_state(args) + debug_start('jit-log-virtualstate') + virtual_state.debug_print("Looking for ") + + for target in procedure_token.target_tokens: + if not target.virtual_state: + continue + ok = False + extra_guards = [] + + bad = {} + debugmsg = 'Did not match ' + if target.virtual_state.generalization_of(virtual_state, bad): + ok = True + debugmsg = 'Matched ' + else: + try: + cpu = self.optimizer.cpu + target.virtual_state.generate_guards(virtual_state, + args, cpu, + extra_guards) + + ok = True + debugmsg = 'Guarded to match ' + except InvalidLoop: + pass + target.virtual_state.debug_print(debugmsg, bad) + + if ok: + debug_stop('jit-log-virtualstate') + + values = [self.getvalue(arg) + for arg in jumpop.getarglist()] + args = target.virtual_state.make_inputargs(values, self.optimizer, + keyboxes=True) + short_inputargs = target.short_preamble[0].getarglist() + inliner = Inliner(short_inputargs, args) + + for guard in extra_guards: + if guard.is_guard(): + descr = target.start_resumedescr.clone_if_mutable() + inliner.inline_descr_inplace(descr) + guard.setdescr(descr) + self.emit_operation(guard) + + try: + for shop in target.short_preamble[1:]: + newop = inliner.inline_op(shop) + self.emit_operation(newop) + except InvalidLoop: + debug_print("Inlining failed unexpectedly", + "jumping to preamble instead") + assert False, "FIXME: Construct jump op" + self.emit_operation(op) + return True + debug_stop('jit-log-virtualstate') + + retraced_count = procedure_token.retraced_count + limit = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.retrace_limit + if not self.retraced and retraced_count<limit: + procedure_token.retraced_count += 1 + return False + - +# FIXME: kill class OptInlineShortPreamble(Optimization): def __init__(self, retraced): self.retraced = retraced @@ -440,82 +507,6 @@ return OptInlineShortPreamble(self.retraced) def propagate_forward(self, op): - if op.getopnum() == rop.JUMP: - self.emit_operation(op) - return - elif op.getopnum() == rop.LABEL: - target_token = op.getdescr() - assert isinstance(target_token, TargetToken) - procedure_token = target_token.procedure_token - if not procedure_token.target_tokens: - self.emit_operation(op) - return - - args = op.getarglist() - modifier = VirtualStateAdder(self.optimizer) - virtual_state = modifier.get_virtual_state(args) - debug_start('jit-log-virtualstate') - virtual_state.debug_print("Looking for ") - - for target in procedure_token.target_tokens: - if not target.virtual_state: - continue - ok = False - extra_guards = [] - - bad = {} - debugmsg = 'Did not match ' - if target.virtual_state.generalization_of(virtual_state, bad): - ok = True - debugmsg = 'Matched ' - else: - try: - cpu = self.optimizer.cpu - target.virtual_state.generate_guards(virtual_state, - args, cpu, - extra_guards) - - ok = True - debugmsg = 'Guarded to match ' - except InvalidLoop: - pass - target.virtual_state.debug_print(debugmsg, bad) - - if ok: - debug_stop('jit-log-virtualstate') - - values = [self.getvalue(arg) - for arg in op.getarglist()] - args = target.virtual_state.make_inputargs(values, self.optimizer, - keyboxes=True) - short_inputargs = target.short_preamble[0].getarglist() - inliner = Inliner(short_inputargs, args) - - for guard in extra_guards: - if guard.is_guard(): - descr = target.start_resumedescr.clone_if_mutable() - inliner.inline_descr_inplace(descr) - guard.setdescr(descr) - self.emit_operation(guard) - - try: - for shop in target.short_preamble[1:]: - newop = inliner.inline_op(shop) - self.emit_operation(newop) - except InvalidLoop: - debug_print("Inlining failed unexpectedly", - "jumping to preamble instead") - assert False, "FIXME: Construct jump op" - self.emit_operation(op) - return - debug_stop('jit-log-virtualstate') - - retraced_count = procedure_token.retraced_count - limit = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.retrace_limit - if not self.retraced and retraced_count<limit: - procedure_token.retraced_count += 1 - raise RetraceLoop - ## # We should not be failing much anymore... ## if not procedure_token.failed_states: ## debug_print("Retracing (%d of %d)" % (retraced_count, @@ -535,7 +526,8 @@ ## loop_token.failed_states=[virtual_state] ## else: ## loop_token.failed_states.append(virtual_state) - self.emit_operation(op) + self.emit_operation(op) + class ValueImporter(object): def __init__(self, unroll, value, op): diff --git a/pypy/jit/metainterp/test/test_compile.py b/pypy/jit/metainterp/test/test_compile.py --- a/pypy/jit/metainterp/test/test_compile.py +++ b/pypy/jit/metainterp/test/test_compile.py @@ -1,5 +1,5 @@ from pypy.config.pypyoption import get_pypy_config -from pypy.jit.metainterp.history import ProcedureToken, TargetToken, ConstInt, History, Stats +from pypy.jit.metainterp.history import TargetToken, ConstInt, History, Stats from pypy.jit.metainterp.history import BoxInt, INT from pypy.jit.metainterp.compile import insert_loop_token, compile_procedure from pypy.jit.metainterp.compile import ResumeGuardDescr diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py --- a/pypy/jit/tool/oparser.py +++ b/pypy/jit/tool/oparser.py @@ -70,7 +70,7 @@ self.invent_fail_descr = invent_fail_descr self.nonstrict = nonstrict self.model = get_model(self.use_mock_model) - self.looptoken = self.model.ProcedureToken() + self.celltoken = self.model.JitCellToken() def get_const(self, name, typ): if self._consts is None: @@ -243,7 +243,7 @@ descr = self.invent_fail_descr(self.model, fail_args) elif opnum == rop.JUMP: if descr is None and self.invent_fail_descr: - descr = self.looptoken + descr = self.celltoken return opnum, args, descr, fail_args def create_op(self, opnum, args, result, descr): @@ -307,7 +307,6 @@ raise ParseError("unexpected dedent at line: %s" % newlines[num]) loop = self.model.ExtendedTreeLoop("loop") loop.comment = first_comment - loop.token = self.looptoken loop.operations = ops loop.inputargs = inpargs loop.last_offset = last_offset diff --git a/pypy/jit/tool/oparser_model.py b/pypy/jit/tool/oparser_model.py --- a/pypy/jit/tool/oparser_model.py +++ b/pypy/jit/tool/oparser_model.py @@ -3,7 +3,7 @@ def get_real_model(): class LoopModel(object): - from pypy.jit.metainterp.history import TreeLoop, ProcedureToken + from pypy.jit.metainterp.history import TreeLoop, JitCellToken from pypy.jit.metainterp.history import Box, BoxInt, BoxFloat from pypy.jit.metainterp.history import ConstInt, ConstObj, ConstPtr, ConstFloat from pypy.jit.metainterp.history import BasicFailDescr _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit