def _run_inliner( self, state, inline_type, sig, template, arg_typs, expr, i, impl, block, work_list, is_method, ): from numba.inline_closurecall import (inline_closure_call, callee_ir_validator) do_inline = True if not inline_type.is_always_inline: from numba.typing.templates import _inline_info caller_inline_info = _inline_info(state.func_ir, state.type_annotation.typemap, state.type_annotation.calltypes, sig) # must be a cost-model function, run the function iinfo = template._inline_overloads[arg_typs]['iinfo'] if inline_type.has_cost_model: do_inline = inline_type.value(expr, caller_inline_info, iinfo) else: assert 'unreachable' if do_inline: if is_method: if not self._add_method_self_arg(state, expr): return False arg_typs = template._inline_overloads[arg_typs]['folded_args'] # pass is typed so use the callee globals inline_closure_call(state.func_ir, impl.__globals__, block, i, impl, typingctx=state.typingctx, arg_typs=arg_typs, typemap=state.type_annotation.typemap, calltypes=state.type_annotation.calltypes, work_list=work_list, replace_freevars=False, callee_validator=callee_ir_validator) return True else: return False
def _do_work(self, state, work_list, block, i, expr): from numba.inline_closurecall import (inline_closure_call, callee_ir_validator) # try and get a definition for the call, this isn't always possible as # it might be a eval(str)/part generated awaiting update etc. (parfors) to_inline = None try: to_inline = state.func_ir.get_definition(expr.func) except Exception: return False # do not handle closure inlining here, another pass deals with that. if getattr(to_inline, 'op', False) == 'make_function': return False # check this is a known and typed function try: func_ty = state.type_annotation.typemap[expr.func.name] except KeyError: # e.g. Calls to CUDA Intrinsic have no mapped type so KeyError return False if not hasattr(func_ty, 'get_call_type'): return False # search the templates for this overload looking for "inline" templates = getattr(func_ty, 'templates', None) if templates is None: return False sig = state.type_annotation.calltypes[expr] impl = None for template in templates: inline_type = getattr(template, '_inline', None) if inline_type is None: # inline not defined continue if not inline_type.is_never_inline: try: impl = template._overload_func(*sig.args) if impl is None: raise Exception # abort for this template break except Exception: continue else: return False # at this point we know we maybe want to inline something and there's # definitely something that could be inlined. do_inline = True if not inline_type.is_always_inline: from numba.typing.templates import _inline_info caller_inline_info = _inline_info(state.func_ir, state.type_annotation.typemap, state.type_annotation.calltypes, sig) # must be a cost-model function, run the function iinfo = template._inline_overloads[sig.args]['iinfo'] if inline_type.has_cost_model: do_inline = inline_type.value(expr, caller_inline_info, iinfo) else: assert 'unreachable' if do_inline: arg_typs = template._inline_overloads[sig.args]['folded_args'] # pass is typed so use the callee globals inline_closure_call(state.func_ir, impl.__globals__, block, i, impl, typingctx=state.typingctx, arg_typs=arg_typs, typemap=state.type_annotation.typemap, calltypes=state.type_annotation.calltypes, work_list=work_list, replace_freevars=False, callee_validator=callee_ir_validator) return True else: return False