def compile(self, sig): disp = self._get_dispatcher_for_current_target() if disp is not self: return disp.compile(sig) with ExitStack() as scope: cres = None def cb_compiler(dur): if cres is not None: self._callback_add_compiler_timer(dur, cres) def cb_llvm(dur): if cres is not None: self._callback_add_llvm_timer(dur, cres) scope.enter_context( ev.install_timer("numba:compiler_lock", cb_compiler)) scope.enter_context(ev.install_timer("numba:llvm_lock", cb_llvm)) scope.enter_context(global_compiler_lock) if not self._can_compile: raise RuntimeError("compilation disabled") # Use counter to track recursion compilation depth with self._compiling_counter: args, return_type = sigutils.normalize_signature(sig) # Don't recompile if signature already exists existing = self.overloads.get(tuple(args)) if existing is not None: return existing.entry_point # Try to load from disk cache cres = self._cache.load_overload(sig, self.targetctx) if cres is not None: self._cache_hits[sig] += 1 # XXX fold this in add_overload()? (also see compiler.py) if not cres.objectmode: self.targetctx.insert_user_function( cres.entry_point, cres.fndesc, [cres.library]) self.add_overload(cres) return cres.entry_point self._cache_misses[sig] += 1 ev_details = dict( dispatcher=self, args=args, return_type=return_type, ) with ev.trigger_event("numba:compile", data=ev_details): try: cres = self._compiler.compile(args, return_type) except errors.ForceLiteralArg as e: def folded(args, kws): return self._compiler.fold_argument_types( args, kws)[1] raise e.bind_fold_arguments(folded) self.add_overload(cres) self._cache.save_overload(sig, cres) return cres.entry_point
def compile(self, sig): with ExitStack() as scope: cres = None def cb_compiler(dur): if cres is not None: self._callback_add_compiler_timer(dur, cres) def cb_llvm(dur): if cres is not None: self._callback_add_llvm_timer(dur, cres) scope.enter_context( ev.install_timer("numba:compiler_lock", cb_compiler)) scope.enter_context(ev.install_timer("numba:llvm_lock", cb_llvm)) scope.enter_context(global_compiler_lock) # Use counter to track recursion compilation depth with self._compiling_counter: # XXX this is mostly duplicated from Dispatcher. flags = self.flags args, return_type = sigutils.normalize_signature(sig) # Don't recompile if signature already exists # (e.g. if another thread compiled it before we got the lock) existing = self.overloads.get(tuple(args)) if existing is not None: return existing.entry_point self._pre_compile(args, return_type, flags) # Clone IR to avoid (some of the) mutation in the rewrite pass cloned_func_ir = self.func_ir.copy() ev_details = dict( dispatcher=self, args=args, return_type=return_type, ) with ev.trigger_event("numba:compile", data=ev_details): cres = compiler.compile_ir( typingctx=self.typingctx, targetctx=self.targetctx, func_ir=cloned_func_ir, args=args, return_type=return_type, flags=flags, locals=self.locals, lifted=(), lifted_from=self.lifted_from, is_lifted_loop=True, ) # Check typing error if object mode is used if (cres.typing_error is not None and not flags.enable_pyobject): raise cres.typing_error self.add_overload(cres) return cres.entry_point
def _runPass(self, index, pss, internal_state): mutated = False def check(func, compiler_state): mangled = func(compiler_state) if mangled not in (True, False): msg = ( "CompilerPass implementations should return True/False. " "CompilerPass with name '%s' did not.") raise ValueError(msg % pss.name()) return mangled def debug_print(pass_name, print_condition, printable_condition): if pass_name in print_condition: fid = internal_state.func_id args = (fid.modname, fid.func_qualname, self.pipeline_name, printable_condition, pass_name) print(("%s.%s: %s: %s %s" % args).center(120, '-')) if internal_state.func_ir is not None: internal_state.func_ir.dump() else: print("func_ir is None") # debug print before this pass? debug_print(pss.name(), self._print_before + self._print_wrap, "BEFORE") # wire in the analysis info so it's accessible pss.analysis = self._analysis qualname = internal_state.func_id.func_qualname ev_details = dict( name=f"{pss.name()} [{qualname}]", qualname=qualname, module=internal_state.func_id.modname, flags=pformat(internal_state.flags.values()), args=str(internal_state.args), return_type=str(internal_state.return_type), ) with ev.trigger_event("numba:run_pass", data=ev_details): with SimpleTimer() as init_time: mutated |= check(pss.run_initialization, internal_state) with SimpleTimer() as pass_time: mutated |= check(pss.run_pass, internal_state) with SimpleTimer() as finalize_time: mutated |= check(pss.run_finalizer, internal_state) # Check that if the pass is an instance of a FunctionPass that it hasn't # emitted ir.Dels. if isinstance(pss, FunctionPass): enforce_no_dels(internal_state.func_ir) if self._ENFORCING: # TODO: Add in self consistency enforcement for # `func_ir._definitions` etc if _pass_registry.get(pss.__class__).mutates_CFG: if mutated: # block level changes, rebuild all PostProcessor(internal_state.func_ir).run() else: # CFG level changes rebuild CFG internal_state.func_ir.blocks = transforms.canonicalize_cfg( internal_state.func_ir.blocks) # Check the func_ir has exactly one Scope instance if not legalize_single_scope(internal_state.func_ir.blocks): raise errors.CompilerError( f"multiple scope in func_ir detected in {pss}", ) # inject runtimes pt = pass_timings(init_time.elapsed, pass_time.elapsed, finalize_time.elapsed) self.exec_times["%s_%s" % (index, pss.name())] = pt # debug print after this pass? debug_print(pss.name(), self._print_after + self._print_wrap, "AFTER")