Beispiel #1
0
    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
Beispiel #2
0
    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")