Author: Hakan Ardo <ha...@debian.org> 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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit