[llvm][NFC] Cache FAM in InlineAdvisor

Summary:
This simplifies the interface by storing the function analysis manager
with the InlineAdvisor, and, thus, not requiring it be passed each time
we inquire for an advice.

Reviewers: davidxl, asbirlea

Subscribers: eraman, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D80405
This commit is contained in:
Mircea Trofin 2020-05-21 08:40:49 -07:00
parent a05f1e5ae4
commit 999ea25a9e
4 changed files with 27 additions and 19 deletions

View File

@ -116,8 +116,7 @@ public:
/// inline or not. \p CB is assumed to be a direct call. \p FAM is assumed to /// 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. /// be up-to-date wrt previous inlining decisions.
/// Returns an InlineAdvice with the inlining recommendation. /// Returns an InlineAdvice with the inlining recommendation.
virtual std::unique_ptr<InlineAdvice> virtual std::unique_ptr<InlineAdvice> getAdvice(CallBase &CB) = 0;
getAdvice(CallBase &CB, FunctionAnalysisManager &FAM) = 0;
/// This must be called when the Inliner pass is entered, to allow the /// This must be called when the Inliner pass is entered, to allow the
/// InlineAdvisor update internal state, as result of function passes run /// InlineAdvisor update internal state, as result of function passes run
@ -130,7 +129,9 @@ public:
virtual void onPassExit() {} virtual void onPassExit() {}
protected: protected:
InlineAdvisor() = default; InlineAdvisor(FunctionAnalysisManager &FAM) : FAM(FAM) {}
FunctionAnalysisManager &FAM;
/// We may want to defer deleting functions to after the inlining for a whole /// 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 /// module has finished. This allows us to reliably use function pointers as
@ -156,13 +157,14 @@ private:
/// reusable as-is for inliner pass test scenarios, as well as for regular use. /// reusable as-is for inliner pass test scenarios, as well as for regular use.
class DefaultInlineAdvisor : public InlineAdvisor { class DefaultInlineAdvisor : public InlineAdvisor {
public: public:
DefaultInlineAdvisor(InlineParams Params) : Params(Params) {} DefaultInlineAdvisor(FunctionAnalysisManager &FAM, InlineParams Params)
: InlineAdvisor(FAM), Params(Params) {}
private: private:
std::unique_ptr<InlineAdvice> std::unique_ptr<InlineAdvice> getAdvice(CallBase &CB) override;
getAdvice(CallBase &CB, FunctionAnalysisManager &FAM) override;
void onPassExit() override { freeDeletedFunctions(); } void onPassExit() override { freeDeletedFunctions(); }
InlineParams Params; InlineParams Params;
}; };
@ -173,7 +175,7 @@ public:
static AnalysisKey Key; static AnalysisKey Key;
InlineAdvisorAnalysis() = default; InlineAdvisorAnalysis() = default;
struct Result { struct Result {
Result(Module &M, ModuleAnalysisManager &MAM) {} Result(Module &M, ModuleAnalysisManager &MAM) : M(M), MAM(MAM) {}
bool invalidate(Module &, const PreservedAnalyses &, bool invalidate(Module &, const PreservedAnalyses &,
ModuleAnalysisManager::Invalidator &) { ModuleAnalysisManager::Invalidator &) {
// InlineAdvisor must be preserved across analysis invalidations. // InlineAdvisor must be preserved across analysis invalidations.
@ -184,6 +186,8 @@ public:
void clear() { Advisor.reset(); } void clear() { Advisor.reset(); }
private: private:
Module &M;
ModuleAnalysisManager &MAM;
std::unique_ptr<InlineAdvisor> Advisor; std::unique_ptr<InlineAdvisor> Advisor;
}; };

View File

@ -106,7 +106,7 @@ public:
private: private:
InlineAdvisor &getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM, InlineAdvisor &getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM,
Module &M); FunctionAnalysisManager &FAM, Module &M);
std::unique_ptr<ImportedFunctionsInliningStatistics> ImportedFunctionsStats; std::unique_ptr<ImportedFunctionsInliningStatistics> ImportedFunctionsStats;
Optional<DefaultInlineAdvisor> OwnedDefaultAdvisor; Optional<DefaultInlineAdvisor> OwnedDefaultAdvisor;
}; };

View File

@ -90,8 +90,7 @@ private:
} // namespace } // namespace
std::unique_ptr<InlineAdvice> std::unique_ptr<InlineAdvice> DefaultInlineAdvisor::getAdvice(CallBase &CB) {
DefaultInlineAdvisor::getAdvice(CallBase &CB, FunctionAnalysisManager &FAM) {
Function &Caller = *CB.getCaller(); Function &Caller = *CB.getCaller();
ProfileSummaryInfo *PSI = ProfileSummaryInfo *PSI =
FAM.getResult<ModuleAnalysisManagerFunctionProxy>(Caller) FAM.getResult<ModuleAnalysisManagerFunctionProxy>(Caller)
@ -149,9 +148,10 @@ AnalysisKey InlineAdvisorAnalysis::Key;
bool InlineAdvisorAnalysis::Result::tryCreate(InlineParams Params, bool InlineAdvisorAnalysis::Result::tryCreate(InlineParams Params,
InliningAdvisorMode Mode) { InliningAdvisorMode Mode) {
auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
switch (Mode) { switch (Mode) {
case InliningAdvisorMode::Default: case InliningAdvisorMode::Default:
Advisor.reset(new DefaultInlineAdvisor(Params)); Advisor.reset(new DefaultInlineAdvisor(FAM, Params));
break; break;
case InliningAdvisorMode::Development: case InliningAdvisorMode::Development:
// To be added subsequently under conditional compilation. // To be added subsequently under conditional compilation.

View File

@ -668,14 +668,18 @@ InlinerPass::~InlinerPass() {
InlineAdvisor & InlineAdvisor &
InlinerPass::getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM, InlinerPass::getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM,
Module &M) { FunctionAnalysisManager &FAM, Module &M) {
auto *IAA = MAM.getCachedResult<InlineAdvisorAnalysis>(M); auto *IAA = MAM.getCachedResult<InlineAdvisorAnalysis>(M);
if (!IAA) { if (!IAA) {
// It should still be possible to run the inliner as a stand-alone SCC pass, // 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 // for test scenarios. In that case, we default to the
// DefaultInlineAdvisor, which doesn't need to keep state between SCC pass // DefaultInlineAdvisor, which doesn't need to keep state between SCC pass
// runs. It also uses just the default InlineParams. // 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; return *OwnedDefaultAdvisor;
} }
assert(IAA->getAdvisor() && assert(IAA->getAdvisor() &&
@ -695,7 +699,11 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
Module &M = *InitialC.begin()->getFunction().getParent(); Module &M = *InitialC.begin()->getFunction().getParent();
ProfileSummaryInfo *PSI = MAMProxy.getCachedResult<ProfileSummaryAnalysis>(M); ProfileSummaryInfo *PSI = MAMProxy.getCachedResult<ProfileSummaryAnalysis>(M);
InlineAdvisor &Advisor = getAdvisor(MAMProxy, M); FunctionAnalysisManager &FAM =
AM.getResult<FunctionAnalysisManagerCGSCCProxy>(InitialC, CG)
.getManager();
InlineAdvisor &Advisor = getAdvisor(MAMProxy, FAM, M);
Advisor.onPassEntry(); Advisor.onPassEntry();
auto AdvisorOnExit = make_scope_exit([&] { Advisor.onPassExit(); }); auto AdvisorOnExit = make_scope_exit([&] { Advisor.onPassExit(); });
@ -733,10 +741,6 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
// incrementally maknig a single function grow in a super linear fashion. // incrementally maknig a single function grow in a super linear fashion.
SmallVector<std::pair<CallBase *, int>, 16> Calls; SmallVector<std::pair<CallBase *, int>, 16> Calls;
FunctionAnalysisManager &FAM =
AM.getResult<FunctionAnalysisManagerCGSCCProxy>(InitialC, CG)
.getManager();
// Populate the initial list of calls in this SCC. // Populate the initial list of calls in this SCC.
for (auto &N : InitialC) { for (auto &N : InitialC) {
auto &ORE = auto &ORE =
@ -838,7 +842,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
continue; continue;
} }
auto Advice = Advisor.getAdvice(*CB, FAM); auto Advice = Advisor.getAdvice(*CB);
// Check whether we want to inline this callsite. // Check whether we want to inline this callsite.
if (!Advice->isInliningRecommended()) { if (!Advice->isInliningRecommended()) {
Advice->recordUnattemptedInlining(); Advice->recordUnattemptedInlining();