Repository: JuliaLang/julia
File: Compiler/src/ssair/inlining.jl (Julia)

Code before:

        simpleres = process_simple!(todo, ir, idx, flag, state)
        simpleres === nothing && continue
        stmt, sig = simpleres
        info = inst[:info]

        # `NativeInterpreter` won't need this, but provide a support for `:invoke` exprs here
        # for external `AbstractInterpreter`s that may run the inlining pass multiple times
        if isexpr(stmt, :invoke)
            handle_invoke_expr!(todo, ir, idx, stmt, info, flag, sig, state)
            continue
        end

        # Check for invoke with CodeInstance pattern and transform it
        # This allows invoke calls with CodeInstance to be resolved at compile time
        # Pattern: Expr(:call, invoke, f, ::CodeInstance, args...)
        # Transformed into: Expr(:invoke, ::CodeInstance, f, args...)
        if sig.f === Core.invoke && is_invoke_with_codeinstance(stmt, ir)
            if transform_invoke_codeinstance!(ir, idx, stmt)
                # Successfully transformed to :invoke, now handle it as such
                handle_invoke_expr!(todo, ir, idx, stmt, info, flag, sig, state)
                continue
            end
           # If transformation failed, fall through to normal invoke handling
        end

        # Check whether this call was @pure and evaluates to a constant
        if info isa MethodResultPure
            inline_const_if_inlineable!(ir[SSAValue(idx)]) && continue
            info = info.info
        end
        if info === NoCallInfo()
            # Inference determined this couldn't be analyzed. Don't question it.
            continue
        end

        # handle special cased builtins
        if isa(info, OpaqueClosureCallInfo)
            handle_opaque_closure_call!(todo, ir, idx, stmt, info, flag, sig, state)
        elseif isa(info, ModifyOpInfo)
            handle_modifyop!_call!(ir, idx, stmt, info, state)
        elseif sig.f === Core.invoke
            handle_invoke_call!(todo, ir, idx, stmt, info, flag, sig, state)
        elseif isa(info, FinalizerInfo)
            handle_finalizer_call!(ir, idx, stmt, info, state)
        else
            # cascade to the generic (and extendable) handler
            handle_call!(todo, ir, idx, stmt, info, flag, sig, state)
        end
    end


Review comment (refactor):
I think normally we add a `abstract_call_X` handler in abstractinterpretation.jl which returns a `return CallMeta(call.rt, call.exct, call.effects, XCallInfo(..., call.info))`

So for you the function to look at ought to be `abstract_invoke`




Code after:
            end
        elseif contains_is(_PURE_BUILTINS, f)
            return SomeCase(quoted(val))
        elseif contains_is(_EFFECT_FREE_BUILTINS, f)
            if has_flag(flag, IR_FLAG_NOTHROW)
                return SomeCase(quoted(val))
            end
        end
    end
    if f === compilerbarrier
        # check if this `compilerbarrier` has already imposed a barrier on abstract interpretation
        # so that it can be eliminated here
        length(argtypes) == 3 || return nothing
        setting = argtypes[2]
        isa(setting, Const) || return nothing
        setting = setting.val
        isa(setting, Symbol) || return nothing
        # setting === :const || setting === :type barrier const evaluation,
        # so they can't be eliminated at IPO time
        setting === :conditional || return nothing
        # barriered successfully already, eliminate it
        return SomeCase(stmt.args[3])
    elseif f === Core.ifelse && length(argtypes) == 4
        cond = argtypes[2]
        if isa(cond, Const)
            if cond.val === true
                return SomeCase(stmt.args[3])
            elseif cond.val === false
                return SomeCase(stmt.args[4])
            end
        elseif ⊑(optimizer_lattice(state.interp), cond, Bool) && stmt.args[3] === stmt.args[4]
            return SomeCase(stmt.args[3])
        end
    end
    return nothing
end

# special-case some regular method calls whose results are not folded within `abstract_call_known`
# (and thus `early_inline_special_case` doesn't handle them yet)
# NOTE we manually inline the method bodies, and so the logic here needs to precisely sync with their definitions
function late_inline_special_case!(ir::IRCode, idx::Int, stmt::Expr, flag::UInt32,
                                   @nospecialize(type), sig::Signature, state::InliningState)
    OptimizationParams(state.interp).inlining || return nothing
    (; f, ft, argtypes) = sig
    if length(argtypes) == 3 && f === Core.:(!==)
        # special-case inliner for !== that precedes _methods_by_ftype union splitting
        # and that works, even though inference generally avoids inferring the `!==` Method
        if isa(type, Const)
            return SomeCase(quoted(type.val))
        end
        cmp_call = Expr(:call, GlobalRef(Core, :(===)), stmt.args[2], stmt.args[3])