def _do_optimize_loop(self, loop, call_pure_results): from pypy.jit.metainterp.optimizeopt import optimize_trace from pypy.jit.metainterp.optimizeopt.util import args_dict self.loop = loop loop.call_pure_results = args_dict() if call_pure_results is not None: for k, v in call_pure_results.items(): loop.call_pure_results[list(k)] = v metainterp_sd = FakeMetaInterpStaticData(self.cpu) if hasattr(self, 'vrefinfo'): metainterp_sd.virtualref_info = self.vrefinfo if hasattr(self, 'callinfocollection'): metainterp_sd.callinfocollection = self.callinfocollection # optimize_trace(metainterp_sd, loop, self.enable_opts)
def _do_optimize_bridge(self, bridge, call_pure_results): from pypy.jit.metainterp.optimizeopt import optimize_trace from pypy.jit.metainterp.optimizeopt.util import args_dict self.bridge = bridge bridge.call_pure_results = args_dict() if call_pure_results is not None: for k, v in call_pure_results.items(): bridge.call_pure_results[list(k)] = v metainterp_sd = FakeMetaInterpStaticData(self.cpu) if hasattr(self, 'vrefinfo'): metainterp_sd.virtualref_info = self.vrefinfo if hasattr(self, 'callinfocollection'): metainterp_sd.callinfocollection = self.callinfocollection # bridge.resume_at_jump_descr = FakeDescrWithSnapshot() optimize_trace(metainterp_sd, bridge, self.enable_opts)
def compile_trace(metainterp, resumekey, resume_at_jump_descr=None): """Try to compile a new bridge leading from the beginning of the history to some existing place. """ from pypy.jit.metainterp.optimizeopt import optimize_trace # The history contains new operations to attach as the code for the # failure of 'resumekey.guard_op'. # # Attempt to use optimize_bridge(). This may return None in case # it does not work -- i.e. none of the existing old_loop_tokens match. new_trace = create_empty_loop(metainterp) new_trace.inputargs = inputargs = metainterp.history.inputargs[:] # clone ops, as optimize_bridge can mutate the ops new_trace.operations = [op.clone() for op in metainterp.history.operations] new_trace.resume_at_jump_descr = resume_at_jump_descr metainterp_sd = metainterp.staticdata state = metainterp.jitdriver_sd.warmstate if isinstance(resumekey, ResumeAtPositionDescr): inline_short_preamble = False else: inline_short_preamble = True try: optimize_trace(metainterp_sd, new_trace, state.enable_opts, inline_short_preamble) except InvalidLoop: debug_print("compile_new_bridge: got an InvalidLoop") # XXX I am fairly convinced that optimize_bridge cannot actually raise # InvalidLoop debug_print('InvalidLoop in compile_new_bridge') return None 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) 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: metainterp.retrace_needed(new_trace) return None
def compile_retrace(metainterp, greenkey, start, inputargs, jumpargs, resume_at_jump_descr, 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.resume_at_jump_descr = resume_at_jump_descr 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)] label = part.operations[0] orignial_label = label.clone() assert label.getopnum() == rop.LABEL try: optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts) except InvalidLoop: # Fall back on jumping to preamble target_token = label.getdescr() assert isinstance(target_token, TargetToken) assert target_token.exported_state part.operations = [orignial_label] + \ [ResOperation(rop.JUMP, inputargs[:], None, descr=loop_jitcell_token)] try: optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts, inline_short_preamble=False) except InvalidLoop: 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) loop = partial_trace loop.operations = loop.operations[:-1] + part.operations 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
def compile_loop(metainterp, greenkey, start, inputargs, jumpargs, resume_at_jump_descr, full_preamble_needed=True): """Try to compile a new procedure by closing the current history back to the first operation. """ from pypy.jit.metainterp.optimizeopt import optimize_trace metainterp_sd = metainterp.staticdata jitdriver_sd = metainterp.jitdriver_sd history = metainterp.history jitcell_token = make_jitcell_token(jitdriver_sd) part = create_empty_loop(metainterp) part.inputargs = inputargs[:] h_ops = history.operations part.resume_at_jump_descr = resume_at_jump_descr part.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(jitcell_token))] + \ [h_ops[i].clone() for i in range(start, len(h_ops))] + \ [ResOperation(rop.LABEL, jumpargs, None, descr=jitcell_token)] try: optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts) except InvalidLoop: return None target_token = part.operations[0].getdescr() assert isinstance(target_token, TargetToken) all_target_tokens = [target_token] 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) while part.operations[-1].getopnum() == rop.LABEL: inliner = Inliner(inputargs, jumpargs) 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, part, jitdriver_sd.warmstate.enable_opts) 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) if not loop.quasi_immutable_deps: loop.quasi_immutable_deps = None for box in loop.inputargs: assert isinstance(box, Box) 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]