[llvm] 248d55a - [NFC][MLGO] Use LazyCallGraph::Node to track functions.
Mircea Trofin via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 11 19:39:21 PST 2022
Author: Mircea Trofin
Date: 2022-01-11T19:23:47-08:00
New Revision: 248d55af3e446ad69a64f08cfcc4879f9690e580
URL: https://github.com/llvm/llvm-project/commit/248d55af3e446ad69a64f08cfcc4879f9690e580
DIFF: https://github.com/llvm/llvm-project/commit/248d55af3e446ad69a64f08cfcc4879f9690e580.diff
LOG: [NFC][MLGO] Use LazyCallGraph::Node to track functions.
This avoids the InlineAdvisor carrying the responsibility of deleting
Function objects. We use LazyCallGraph::Node objects instead, which are
stable in memory for the duration of the Module-wide performance of CGSCC
passes started under the same ModuleToPostOrderCGSCCPassAdaptor (which
is the case here)
Differential Revision: https://reviews.llvm.org/D116964
Added:
Modified:
llvm/include/llvm/Analysis/InlineAdvisor.h
llvm/include/llvm/Analysis/MLInlineAdvisor.h
llvm/lib/Analysis/DevelopmentModeInlineAdvisor.cpp
llvm/lib/Analysis/InlineAdvisor.cpp
llvm/lib/Analysis/MLInlineAdvisor.cpp
llvm/lib/Transforms/IPO/Inliner.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/InlineAdvisor.h b/llvm/include/llvm/Analysis/InlineAdvisor.h
index 9f9bc3a5e71b4..0405ca51cf220 100644
--- a/llvm/include/llvm/Analysis/InlineAdvisor.h
+++ b/llvm/include/llvm/Analysis/InlineAdvisor.h
@@ -65,7 +65,9 @@ class InlineAdvice {
/// Call after inlining succeeded, and did not result in deleting the callee.
void recordInlining();
- /// Call after inlining succeeded, and resulted in deleting the callee.
+ /// Call after inlining succeeded, and results in the callee being
+ /// delete-able, meaning, it has no more users, and will be cleaned up
+ /// subsequently.
void recordInliningWithCalleeDeleted();
/// Call after the decision for a call site was to not inline.
@@ -178,19 +180,6 @@ class InlineAdvisor {
FunctionAnalysisManager &FAM;
std::unique_ptr<ImportedFunctionsInliningStatistics> ImportedFunctionsStats;
- /// 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
- /// unique identifiers, as an efficient implementation detail of the
- /// InlineAdvisor. Otherwise, it is possible the memory allocator
- /// re-allocate Function objects at the same address of a deleted Function;
- /// and Functions are potentially created during the function passes called
- /// after each SCC inlining (e.g. argument promotion does that).
- void freeDeletedFunctions();
-
- bool isFunctionDeleted(const Function *F) const {
- return DeletedFunctions.count(F);
- }
-
enum class MandatoryInliningKind { NotMandatory, Always, Never };
static MandatoryInliningKind getMandatoryKind(CallBase &CB,
@@ -201,8 +190,6 @@ class InlineAdvisor {
private:
friend class InlineAdvice;
- void markFunctionAsDeleted(Function *F);
- std::unordered_set<const Function *> DeletedFunctions;
};
/// The default (manual heuristics) implementation of the InlineAdvisor. This
@@ -217,8 +204,6 @@ class DefaultInlineAdvisor : public InlineAdvisor {
private:
std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) override;
- void onPassExit() override { freeDeletedFunctions(); }
-
InlineParams Params;
};
diff --git a/llvm/include/llvm/Analysis/MLInlineAdvisor.h b/llvm/include/llvm/Analysis/MLInlineAdvisor.h
index a218561e61c73..3d2d508fa6305 100644
--- a/llvm/include/llvm/Analysis/MLInlineAdvisor.h
+++ b/llvm/include/llvm/Analysis/MLInlineAdvisor.h
@@ -9,8 +9,8 @@
#ifndef LLVM_ANALYSIS_MLINLINEADVISOR_H
#define LLVM_ANALYSIS_MLINLINEADVISOR_H
-#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/InlineAdvisor.h"
+#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/Analysis/MLModelRunner.h"
#include "llvm/IR/PassManager.h"
@@ -26,7 +26,6 @@ class MLInlineAdvisor : public InlineAdvisor {
MLInlineAdvisor(Module &M, ModuleAnalysisManager &MAM,
std::unique_ptr<MLModelRunner> ModelRunner);
- CallGraph *callGraph() const { return CG.get(); }
virtual ~MLInlineAdvisor() = default;
void onPassEntry() override;
@@ -51,17 +50,22 @@ class MLInlineAdvisor : public InlineAdvisor {
virtual std::unique_ptr<MLInlineAdvice>
getAdviceFromModel(CallBase &CB, OptimizationRemarkEmitter &ORE);
+ // Get the initial 'level' of the function, or 0 if the function has been
+ // introduced afterwards.
+ // TODO: should we keep this updated?
+ unsigned getInitialFunctionLevel(const Function &F) const;
+
std::unique_ptr<MLModelRunner> ModelRunner;
private:
int64_t getModuleIRSize() const;
bool Invalid = true;
- std::unique_ptr<CallGraph> CG;
+ LazyCallGraph &CG;
int64_t NodeCount = 0;
int64_t EdgeCount = 0;
- std::map<const Function *, unsigned> FunctionLevels;
+ std::map<const LazyCallGraph::Node *, unsigned> FunctionLevels;
const int32_t InitialIRSize = 0;
int32_t CurrentIRSize = 0;
diff --git a/llvm/lib/Analysis/DevelopmentModeInlineAdvisor.cpp b/llvm/lib/Analysis/DevelopmentModeInlineAdvisor.cpp
index 26bdbda56ba66..94a60f6a75c19 100644
--- a/llvm/lib/Analysis/DevelopmentModeInlineAdvisor.cpp
+++ b/llvm/lib/Analysis/DevelopmentModeInlineAdvisor.cpp
@@ -412,8 +412,6 @@ size_t DevelopmentModeMLInlineAdvisor::getTotalSizeEstimate() {
for (auto &F : M) {
if (F.isDeclaration())
continue;
- if (isFunctionDeleted(&F))
- continue;
Ret += *getNativeSizeEstimate(F);
}
return Ret;
diff --git a/llvm/lib/Analysis/InlineAdvisor.cpp b/llvm/lib/Analysis/InlineAdvisor.cpp
index 140c88eb8b0d4..a0d8ce85f3233 100644
--- a/llvm/lib/Analysis/InlineAdvisor.cpp
+++ b/llvm/lib/Analysis/InlineAdvisor.cpp
@@ -160,18 +160,6 @@ InlineAdvice::InlineAdvice(InlineAdvisor *Advisor, CallBase &CB,
DLoc(CB.getDebugLoc()), Block(CB.getParent()), ORE(ORE),
IsInliningRecommended(IsInliningRecommended) {}
-void InlineAdvisor::markFunctionAsDeleted(Function *F) {
- assert((!DeletedFunctions.count(F)) &&
- "Cannot put cause a function to become dead twice!");
- DeletedFunctions.insert(F);
-}
-
-void InlineAdvisor::freeDeletedFunctions() {
- for (auto *F : DeletedFunctions)
- delete F;
- DeletedFunctions.clear();
-}
-
void InlineAdvice::recordInlineStatsIfNeeded() {
if (Advisor->ImportedFunctionsStats)
Advisor->ImportedFunctionsStats->recordInline(*Caller, *Callee);
@@ -186,7 +174,6 @@ void InlineAdvice::recordInlining() {
void InlineAdvice::recordInliningWithCalleeDeleted() {
markRecorded();
recordInlineStatsIfNeeded();
- Advisor->markFunctionAsDeleted(Callee);
recordInliningWithCalleeDeletedImpl();
}
@@ -523,8 +510,6 @@ InlineAdvisor::~InlineAdvisor() {
ImportedFunctionsStats->dump(InlinerFunctionImportStats ==
InlinerFunctionImportStatsOpts::Verbose);
}
-
- freeDeletedFunctions();
}
std::unique_ptr<InlineAdvice> InlineAdvisor::getMandatoryAdvice(CallBase &CB,
diff --git a/llvm/lib/Analysis/MLInlineAdvisor.cpp b/llvm/lib/Analysis/MLInlineAdvisor.cpp
index f5a65cd2b689d..83f118b24186c 100644
--- a/llvm/lib/Analysis/MLInlineAdvisor.cpp
+++ b/llvm/lib/Analysis/MLInlineAdvisor.cpp
@@ -22,6 +22,7 @@
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/FunctionPropertiesAnalysis.h"
#include "llvm/Analysis/InlineCost.h"
+#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/Analysis/MLInlineAdvisor.h"
#include "llvm/Analysis/MLModelRunner.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
@@ -90,7 +91,8 @@ MLInlineAdvisor::MLInlineAdvisor(Module &M, ModuleAnalysisManager &MAM,
std::unique_ptr<MLModelRunner> Runner)
: InlineAdvisor(
M, MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager()),
- ModelRunner(std::move(Runner)), CG(new CallGraph(M)),
+ ModelRunner(std::move(Runner)),
+ CG(MAM.getResult<LazyCallGraphAnalysis>(M)),
InitialIRSize(getModuleIRSize()), CurrentIRSize(InitialIRSize) {
assert(ModelRunner);
@@ -100,7 +102,8 @@ MLInlineAdvisor::MLInlineAdvisor(Module &M, ModuleAnalysisManager &MAM,
// critical in behavioral cloning - i.e. training a model to mimic the manual
// heuristic's decisions - and, thus, equally important for training for
// improvement.
- for (auto I = scc_begin(CG.get()); !I.isAtEnd(); ++I) {
+ CallGraph CGraph(M);
+ for (auto I = scc_begin(&CGraph); !I.isAtEnd(); ++I) {
const std::vector<CallGraphNode *> &CGNodes = *I;
unsigned Level = 0;
for (auto *CGNode : CGNodes) {
@@ -110,7 +113,7 @@ MLInlineAdvisor::MLInlineAdvisor(Module &M, ModuleAnalysisManager &MAM,
for (auto &I : instructions(F)) {
if (auto *CS = getInlinableCS(I)) {
auto *Called = CS->getCalledFunction();
- auto Pos = FunctionLevels.find(Called);
+ auto Pos = FunctionLevels.find(&CG.get(*Called));
// In bottom up traversal, an inlinable callee is either in the
// same SCC, or to a function in a visited SCC. So not finding its
// level means we haven't visited it yet, meaning it's in this SCC.
@@ -123,11 +126,15 @@ MLInlineAdvisor::MLInlineAdvisor(Module &M, ModuleAnalysisManager &MAM,
for (auto *CGNode : CGNodes) {
Function *F = CGNode->getFunction();
if (F && !F->isDeclaration())
- FunctionLevels[F] = Level;
+ FunctionLevels[&CG.get(*F)] = Level;
}
}
}
+unsigned MLInlineAdvisor::getInitialFunctionLevel(const Function &F) const {
+ return CG.lookup(F) ? FunctionLevels.at(CG.lookup(F)) : 0;
+}
+
void MLInlineAdvisor::onPassEntry() {
// Function passes executed between InlinerPass runs may have changed the
// module-wide features.
@@ -192,7 +199,7 @@ void MLInlineAdvisor::onSuccessfulInlining(const MLInlineAdvice &Advice,
int64_t MLInlineAdvisor::getModuleIRSize() const {
int64_t Ret = 0;
- for (auto &F : CG->getModule())
+ for (auto &F : M)
if (!F.isDeclaration())
Ret += getIRSize(F);
return Ret;
@@ -263,7 +270,7 @@ std::unique_ptr<InlineAdvice> MLInlineAdvisor::getAdviceImpl(CallBase &CB) {
*ModelRunner->getTensor<int64_t>(FeatureIndex::CalleeBasicBlockCount) =
CalleeBefore.BasicBlockCount;
*ModelRunner->getTensor<int64_t>(FeatureIndex::CallSiteHeight) =
- FunctionLevels[&Caller];
+ getInitialFunctionLevel(Caller);
*ModelRunner->getTensor<int64_t>(FeatureIndex::NodeCount) = NodeCount;
*ModelRunner->getTensor<int64_t>(FeatureIndex::NrCtantParams) = NrCtantParams;
*ModelRunner->getTensor<int64_t>(FeatureIndex::EdgeCount) = EdgeCount;
diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp
index be3455939ba56..c5527c76e8882 100644
--- a/llvm/lib/Transforms/IPO/Inliner.cpp
+++ b/llvm/lib/Transforms/IPO/Inliner.cpp
@@ -1045,14 +1045,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
UR.UpdatedC = nullptr;
// And delete the actual function from the module.
- // The Advisor may use Function pointers to efficiently index various
- // internal maps, e.g. for memoization. Function cleanup passes like
- // argument promotion create new functions. It is possible for a new
- // function to be allocated at the address of a deleted function. We could
- // index using names, but that's inefficient. Alternatively, we let the
- // Advisor free the functions when it sees fit.
- DeadF->getBasicBlockList().clear();
- M.getFunctionList().remove(DeadF);
+ M.getFunctionList().erase(DeadF);
++NumDeleted;
}
More information about the llvm-commits
mailing list