diff --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp index 921fe8c18aa72..cf85c799fb29b 100644 --- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp +++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp @@ -30,6 +30,47 @@ using namespace llvm; namespace { +/// Sanity check for a call site's inlinability based on inline attributes. +static bool canInlineCallBase(CallBase *CB) { + return CB->hasFnAttr(Attribute::AlwaysInline) && + !CB->getAttributes().hasFnAttr(Attribute::NoInline); +} + +/// Attempt to inline a call site \p CB into its caller. +/// Returns true if the inlining was successful, false otherwise. +static bool attemptInlineFunction( + Function &F, CallBase *CB, bool InsertLifetime, + function_ref &GetAAR, + function_ref &GetAssumptionCache, + ProfileSummaryInfo &PSI) { + Function *Caller = CB->getCaller(); + OptimizationRemarkEmitter ORE(Caller); + DebugLoc DLoc = CB->getDebugLoc(); + BasicBlock *Block = CB->getParent(); + + InlineFunctionInfo IFI(GetAssumptionCache, &PSI, nullptr, nullptr); + InlineResult Res = InlineFunction(*CB, IFI, /*MergeAttributes=*/true, + &GetAAR(F), InsertLifetime); + if (!Res.isSuccess()) { + ORE.emit([&]() { + return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block) + << "'" << ore::NV("Callee", &F) << "' is not inlined into '" + << ore::NV("Caller", Caller) + << "': " << ore::NV("Reason", Res.getFailureReason()); + }); + return false; + } + + emitInlinedIntoBasedOnCost(ORE, DLoc, Block, F, *Caller, + InlineCost::getAlways("always inline attribute"), + /*ForProfileContext=*/false, DEBUG_TYPE); + + return true; +} + +/// This function inlines all functions that are marked with the always_inline +/// attribute. It also removes the inlined functions if they are dead after the +/// inlining process. bool AlwaysInlineImpl( Module &M, bool InsertLifetime, ProfileSummaryInfo &PSI, FunctionAnalysisManager *FAM, @@ -50,36 +91,13 @@ bool AlwaysInlineImpl( for (User *U : F.users()) if (auto *CB = dyn_cast(U)) - if (CB->getCalledFunction() == &F && - CB->hasFnAttr(Attribute::AlwaysInline) && - !CB->getAttributes().hasFnAttr(Attribute::NoInline)) + if (CB->getCalledFunction() == &F && canInlineCallBase(CB)) Calls.insert(CB); for (CallBase *CB : Calls) { Function *Caller = CB->getCaller(); - OptimizationRemarkEmitter ORE(Caller); - DebugLoc DLoc = CB->getDebugLoc(); - BasicBlock *Block = CB->getParent(); - - InlineFunctionInfo IFI(GetAssumptionCache, &PSI, nullptr, nullptr); - InlineResult Res = InlineFunction(*CB, IFI, /*MergeAttributes=*/true, - &GetAAR(F), InsertLifetime); - if (!Res.isSuccess()) { - ORE.emit([&]() { - return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block) - << "'" << ore::NV("Callee", &F) << "' is not inlined into '" - << ore::NV("Caller", Caller) - << "': " << ore::NV("Reason", Res.getFailureReason()); - }); - continue; - } - - emitInlinedIntoBasedOnCost( - ORE, DLoc, Block, F, *Caller, - InlineCost::getAlways("always inline attribute"), - /*ForProfileContext=*/false, DEBUG_TYPE); - - Changed = true; + Changed |= attemptInlineFunction(F, CB, InsertLifetime, GetAAR, + GetAssumptionCache, PSI); if (FAM) FAM->invalidate(*Caller, PreservedAnalyses::none()); }