[pypy-commit] pypy jit-targets: 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
hakanardo
noreply at buildbot.pypy.org
Sun Nov 6 14:10:46 CET 2011
Author: Hakan Ardo <hakan at 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
More information about the pypy-commit
mailing list