diff --git a/llvm/include/llvm/Analysis/InlineAdvisor.h b/llvm/include/llvm/Analysis/InlineAdvisor.h --- a/llvm/include/llvm/Analysis/InlineAdvisor.h +++ b/llvm/include/llvm/Analysis/InlineAdvisor.h @@ -117,8 +117,7 @@ /// inline or not. \p CB is assumed to be a direct call. \p FAM is assumed to /// be up-to-date wrt previous inlining decisions. /// Returns an InlineAdvice with the inlining recommendation. - virtual std::unique_ptr - getAdvice(CallBase &CB, FunctionAnalysisManager &FAM) = 0; + virtual std::unique_ptr getAdvice(CallBase &CB) = 0; /// This must be called when the Inliner pass is entered, to allow the /// InlineAdvisor update internal state, as result of function passes run @@ -131,7 +130,9 @@ virtual void onPassExit() {} protected: - InlineAdvisor() = default; + InlineAdvisor(FunctionAnalysisManager &FAM) : FAM(FAM) {} + + FunctionAnalysisManager &FAM; /// We may want to defer deleting functions to after the inlining for a whole /// module has finished. This allows us to reliably use function pointers as @@ -157,13 +158,14 @@ /// reusable as-is for inliner pass test scenarios, as well as for regular use. class DefaultInlineAdvisor : public InlineAdvisor { public: - DefaultInlineAdvisor(InlineParams Params) : Params(Params) {} + DefaultInlineAdvisor(FunctionAnalysisManager &FAM, InlineParams Params) + : InlineAdvisor(FAM), Params(Params) {} private: - std::unique_ptr - getAdvice(CallBase &CB, FunctionAnalysisManager &FAM) override; + std::unique_ptr getAdvice(CallBase &CB) override; void onPassExit() override { freeDeletedFunctions(); } + InlineParams Params; }; @@ -174,7 +176,7 @@ static AnalysisKey Key; InlineAdvisorAnalysis() = default; struct Result { - Result(Module &M, ModuleAnalysisManager &MAM) {} + Result(Module &M, ModuleAnalysisManager &MAM) : M(M), MAM(MAM) {} bool invalidate(Module &, const PreservedAnalyses &, ModuleAnalysisManager::Invalidator &) { // InlineAdvisor must be preserved across analysis invalidations. @@ -185,6 +187,8 @@ void clear() { Advisor.reset(); } private: + Module &M; + ModuleAnalysisManager &MAM; std::unique_ptr Advisor; }; diff --git a/llvm/include/llvm/Transforms/IPO/Inliner.h b/llvm/include/llvm/Transforms/IPO/Inliner.h --- a/llvm/include/llvm/Transforms/IPO/Inliner.h +++ b/llvm/include/llvm/Transforms/IPO/Inliner.h @@ -106,7 +106,7 @@ private: InlineAdvisor &getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM, - Module &M); + FunctionAnalysisManager &FAM, Module &M); std::unique_ptr ImportedFunctionsStats; Optional OwnedDefaultAdvisor; }; diff --git a/llvm/lib/Analysis/InlineAdvisor.cpp b/llvm/lib/Analysis/InlineAdvisor.cpp --- a/llvm/lib/Analysis/InlineAdvisor.cpp +++ b/llvm/lib/Analysis/InlineAdvisor.cpp @@ -90,8 +90,7 @@ } // namespace -std::unique_ptr -DefaultInlineAdvisor::getAdvice(CallBase &CB, FunctionAnalysisManager &FAM) { +std::unique_ptr DefaultInlineAdvisor::getAdvice(CallBase &CB) { Function &Caller = *CB.getCaller(); ProfileSummaryInfo *PSI = FAM.getResult(Caller) @@ -149,9 +148,10 @@ bool InlineAdvisorAnalysis::Result::tryCreate(InlineParams Params, InliningAdvisorMode Mode) { + auto &FAM = MAM.getResult(M).getManager(); switch (Mode) { case InliningAdvisorMode::Default: - Advisor.reset(new DefaultInlineAdvisor(Params)); + Advisor.reset(new DefaultInlineAdvisor(FAM, Params)); break; case InliningAdvisorMode::Development: // To be added subsequently under conditional compilation. diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -668,14 +668,18 @@ InlineAdvisor & InlinerPass::getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM, - Module &M) { + FunctionAnalysisManager &FAM, Module &M) { auto *IAA = MAM.getCachedResult(M); if (!IAA) { // It should still be possible to run the inliner as a stand-alone SCC pass, // for test scenarios. In that case, we default to the // DefaultInlineAdvisor, which doesn't need to keep state between SCC pass // runs. It also uses just the default InlineParams. - OwnedDefaultAdvisor.emplace(getInlineParams()); + // In this case, we need to use the provided FAM, which is valid for the + // duration of the inliner pass, and thus the lifetime of the owned advisor. + // The one we would get from the MAM can be invalidated as a result of the + // inliner's activity. + OwnedDefaultAdvisor.emplace(FAM, getInlineParams()); return *OwnedDefaultAdvisor; } assert(IAA->getAdvisor() && @@ -695,7 +699,11 @@ Module &M = *InitialC.begin()->getFunction().getParent(); ProfileSummaryInfo *PSI = MAMProxy.getCachedResult(M); - InlineAdvisor &Advisor = getAdvisor(MAMProxy, M); + FunctionAnalysisManager &FAM = + AM.getResult(InitialC, CG) + .getManager(); + + InlineAdvisor &Advisor = getAdvisor(MAMProxy, FAM, M); Advisor.onPassEntry(); auto AdvisorOnExit = make_scope_exit([&] { Advisor.onPassExit(); }); @@ -733,10 +741,6 @@ // incrementally maknig a single function grow in a super linear fashion. SmallVector, 16> Calls; - FunctionAnalysisManager &FAM = - AM.getResult(InitialC, CG) - .getManager(); - // Populate the initial list of calls in this SCC. for (auto &N : InitialC) { auto &ORE = @@ -838,7 +842,7 @@ continue; } - auto Advice = Advisor.getAdvice(*CB, FAM); + auto Advice = Advisor.getAdvice(*CB); // Check whether we want to inline this callsite. if (!Advice->isInliningRecommended()) { Advice->recordUnattemptedInlining();