Author: Hakan Ardo <[email protected]>
Branch: jit-targets
Changeset: r48833:d04c6e6f5e44
Date: 2011-11-06 18:25 +0100
http://bitbucket.org/pypy/pypy/changeset/d04c6e6f5e44/
Log: retrace support
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
@@ -93,9 +93,9 @@
# ____________________________________________________________
-def compile_procedure(metainterp, greenkey, start,
+def compile_loop(metainterp, greenkey, start,
inputargs, jumpargs,
- start_resumedescr, full_preamble_needed=True,
partial_trace=None):
+ start_resumedescr, full_preamble_needed=True):
"""Try to compile a new procedure by closing the current history back
to the first operation.
"""
@@ -105,7 +105,7 @@
metainterp_sd = metainterp.staticdata
jitdriver_sd = metainterp.jitdriver_sd
- if partial_trace:
+ if False:
part = partial_trace
assert False
procedur_token = metainterp.get_procedure_token(greenkey)
@@ -155,7 +155,7 @@
jitcell_token.target_tokens = all_target_tokens
send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, "loop")
record_loop_or_bridge(metainterp_sd, loop)
- return jitcell_token
+ return all_target_tokens[0]
if False: # FIXME: full_preamble_needed??
@@ -180,6 +180,53 @@
record_loop_or_bridge(metainterp_sd, loop)
return loop_token
+def compile_retrace(metainterp, greenkey, start,
+ inputargs, jumpargs,
+ start_resumedescr, partial_trace, resumekey):
+ """Try to compile a new procedure by closing the current history back
+ to the first operation.
+ """
+ from pypy.jit.metainterp.optimizeopt import optimize_trace
+
+ history = metainterp.history
+ metainterp_sd = metainterp.staticdata
+ jitdriver_sd = metainterp.jitdriver_sd
+
+ 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[:]
+ part.start_resumedescr = start_resumedescr
+ h_ops = history.operations
+ part.operations = [partial_trace.operations[-1]] + \
+ [h_ops[i].clone() for i in range(start, len(h_ops))] + \
+ [ResOperation(rop.JUMP, jumpargs, None,
descr=loop_jitcell_token)]
+ try:
+ optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts)
+ except InvalidLoop:
+ return None
+ assert part.operations[-1].getopnum() != rop.LABEL
+ label = part.operations[0]
+ assert label.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)
+
+ loop = partial_trace
+ loop.operations = loop.operations[:-1] + part.operations
+
+ for box in loop.inputargs:
+ assert isinstance(box, Box)
+
+ target_token = loop.operations[-1].getdescr()
+ resumekey.compile_and_attach(metainterp, loop)
+ label.getdescr().original_jitcell_token = loop.original_jitcell_token
+ record_loop_or_bridge(metainterp_sd, loop)
+ return target_token
+
def insert_loop_token(old_loop_tokens, loop_token):
# Find where in old_loop_tokens we should insert this new loop_token.
# The following algo means "as late as possible, but before another
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
@@ -778,6 +778,7 @@
call_pure_results = None
logops = None
quasi_immutable_deps = None
+ start_resumedescr = None
def _token(*args):
raise Exception("TreeLoop.token is killed")
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
@@ -116,9 +116,12 @@
jump_args = [self.getvalue(a).get_key_box() for a in
original_jump_args]
# FIXME: I dont thnik we need this anymore
- start_resumedescr =
self.optimizer.loop.start_resumedescr.clone_if_mutable()
- assert isinstance(start_resumedescr, ResumeGuardDescr)
- start_resumedescr.rd_snapshot = self.fix_snapshot(jump_args,
start_resumedescr.rd_snapshot)
+ if self.optimizer.loop.start_resumedescr:
+ start_resumedescr =
self.optimizer.loop.start_resumedescr.clone_if_mutable()
+ assert isinstance(start_resumedescr, ResumeGuardDescr)
+ start_resumedescr.rd_snapshot = self.fix_snapshot(jump_args,
start_resumedescr.rd_snapshot)
+ else:
+ start_resumedescr = None
modifier = VirtualStateAdder(self.optimizer)
virtual_state = modifier.get_virtual_state(jump_args)
@@ -177,7 +180,8 @@
self.imported_state = exported_state
self.inputargs = targetop.getarglist()
self.initial_virtual_state = target_token.virtual_state
- self.start_resumedescr = target_token.start_resumedescr
+ #self.start_resumedescr = target_token.start_resumedescr
+ self.start_resumedescr = self.optimizer.loop.start_resumedescr
seen = {}
for box in self.inputargs:
@@ -324,7 +328,14 @@
for i in range(len(short)):
short[i] = inliner.inline_op(short[i])
- target_token.start_resumedescr =
target_token.start_resumedescr.clone_if_mutable()
+ if target_token.start_resumedescr is None: # FIXME: Hack!
+ target_token.start_resumedescr =
self.start_resumedescr.clone_if_mutable()
+ fix = Inliner(self.optimizer.loop.operations[-1].getarglist(),
+ self.optimizer.loop.inputargs)
+
+ fix.inline_descr_inplace(target_token.start_resumedescr)
+ else:
+ target_token.start_resumedescr =
self.start_resumedescr.clone_if_mutable()
inliner.inline_descr_inplace(target_token.start_resumedescr)
# Forget the values to allow them to be freed
@@ -497,7 +508,7 @@
retraced_count = cell_token.retraced_count
limit =
self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.retrace_limit
- if not self.retraced and retraced_count<limit:
+ if retraced_count<limit:
cell_token.retraced_count += 1
return False
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -1563,7 +1563,7 @@
def retrace_needed(self, trace):
self.partial_trace = trace
- self.retracing_from = len(self.history)
+ self.retracing_from = len(self.history.operations) - 1
self.heapcache.reset()
@@ -1935,6 +1935,7 @@
# - if self.resumekey is a ResumeFromInterpDescr, it starts directly
# from the interpreter.
if not self.partial_trace:
+ # FIXME: Support a retrace to be a bridge as well as a loop
self.compile_trace(live_arg_boxes)
# raises in case it works -- which is the common case, hopefully,
@@ -1959,7 +1960,7 @@
# raises in case it works -- which is the common case
if self.partial_trace:
assert start == self.retracing_from # FIXME: Giveup
- self.compile_procedure(original_boxes, live_arg_boxes, start,
resumedescr)
+ self.compile_loop(original_boxes, live_arg_boxes, start,
resumedescr)
# creation of the loop was cancelled!
self.staticdata.log('cancelled, tracing more...')
#self.staticdata.log('cancelled, stopping tracing')
@@ -2019,20 +2020,27 @@
cell = self.jitdriver_sd.warmstate.jit_cell_at_key(greenkey)
return cell.get_procedure_token()
- def compile_procedure(self, original_boxes, live_arg_boxes, start,
start_resumedescr):
+ def compile_loop(self, original_boxes, live_arg_boxes, start,
start_resumedescr):
num_green_args = self.jitdriver_sd.num_green_args
greenkey = original_boxes[:num_green_args]
if not self.partial_trace:
assert self.get_procedure_token(greenkey) == None # FIXME:
recursion?
- procedure_token = compile.compile_procedure(self, greenkey, start,
-
original_boxes[num_green_args:],
-
live_arg_boxes[num_green_args:],
- start_resumedescr,
partial_trace=self.partial_trace)
- if procedure_token is not None: # raise if it *worked* correctly
- self.jitdriver_sd.warmstate.attach_procedure_to_interp(greenkey,
procedure_token)
+ if self.partial_trace:
+ target_token = compile.compile_retrace(self, greenkey, start,
+
original_boxes[num_green_args:],
+
live_arg_boxes[num_green_args:],
+ start_resumedescr,
self.partial_trace,
+ self.resumekey)
+ else:
+ target_token = compile.compile_loop(self, greenkey, start,
+
original_boxes[num_green_args:],
+
live_arg_boxes[num_green_args:],
+ start_resumedescr)
+ if target_token is not None: # raise if it *worked* correctly
+ self.jitdriver_sd.warmstate.attach_procedure_to_interp(greenkey,
target_token.cell_token)
self.history.inputargs = None
self.history.operations = None
- raise GenerateMergePoint(live_arg_boxes, procedure_token)
+ raise GenerateMergePoint(live_arg_boxes, target_token.cell_token)
def compile_trace(self, live_arg_boxes):
num_green_args = self.jitdriver_sd.num_green_args
@@ -2114,8 +2122,8 @@
# FIXME: kill TerminatingLoopToken?
# FIXME: can we call compile_trace?
self.history.record(rop.FINISH, exits, None,
descr=loop_tokens[0].finishdescr)
- target_loop_token = compile.compile_trace(self, self.resumekey)
- if not target_loop_token:
+ target_token = compile.compile_trace(self, self.resumekey)
+ if not target_token:
compile.giveup()
def compile_exit_frame_with_exception(self, valuebox):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit