Skip to content

Commit fa6ea7a

Browse files
committed
[AlwaysInliner] Make legacy pass like the new pass
The legacy pass is only used in AMDGPU codegen, which doesn't care about running it in call graph order (it actually has to work around that fact). Make the legacy pass a module pass and share code with the new pass. This allows us to remove the legacy inliner infrastructure. Reviewed By: mtrofin Differential Revision: https://reviews.llvm.org/D146446
1 parent 2356bf2 commit fa6ea7a

File tree

12 files changed

+88
-677
lines changed

12 files changed

+88
-677
lines changed

llvm/include/llvm/Analysis/AliasAnalysis.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -985,10 +985,6 @@ ImmutablePass *createExternalAAWrapperPass(
985985
/// getAnalysisUsage.
986986
AAResults createLegacyPMAAResults(Pass &P, Function &F, BasicAAResult &BAR);
987987

988-
/// A helper for the legacy pass manager to populate \p AU to add uses to make
989-
/// sure the analyses required by \p createLegacyPMAAResults are available.
990-
void getAAResultsAnalysisUsage(AnalysisUsage &AU);
991-
992988
} // end namespace llvm
993989

994990
#endif // LLVM_ANALYSIS_ALIASANALYSIS_H

llvm/include/llvm/Transforms/IPO/Inliner.h

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -23,62 +23,6 @@ class AssumptionCacheTracker;
2323
class CallGraph;
2424
class ProfileSummaryInfo;
2525

26-
/// This class contains all of the helper code which is used to perform the
27-
/// inlining operations that do not depend on the policy. It contains the core
28-
/// bottom-up inlining infrastructure that specific inliner passes use.
29-
struct LegacyInlinerBase : public CallGraphSCCPass {
30-
explicit LegacyInlinerBase(char &ID);
31-
explicit LegacyInlinerBase(char &ID, bool InsertLifetime);
32-
33-
/// For this class, we declare that we require and preserve the call graph.
34-
/// If the derived class implements this method, it should always explicitly
35-
/// call the implementation here.
36-
void getAnalysisUsage(AnalysisUsage &Info) const override;
37-
38-
using llvm::Pass::doInitialization;
39-
40-
bool doInitialization(CallGraph &CG) override;
41-
42-
/// Main run interface method, this implements the interface required by the
43-
/// Pass class.
44-
bool runOnSCC(CallGraphSCC &SCC) override;
45-
46-
using llvm::Pass::doFinalization;
47-
48-
/// Remove now-dead linkonce functions at the end of processing to avoid
49-
/// breaking the SCC traversal.
50-
bool doFinalization(CallGraph &CG) override;
51-
52-
/// This method must be implemented by the subclass to determine the cost of
53-
/// inlining the specified call site. If the cost returned is greater than
54-
/// the current inline threshold, the call site is not inlined.
55-
virtual InlineCost getInlineCost(CallBase &CB) = 0;
56-
57-
/// Remove dead functions.
58-
///
59-
/// This also includes a hack in the form of the 'AlwaysInlineOnly' flag
60-
/// which restricts it to deleting functions with an 'AlwaysInline'
61-
/// attribute. This is useful for the InlineAlways pass that only wants to
62-
/// deal with that subset of the functions.
63-
bool removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly = false);
64-
65-
/// This function performs the main work of the pass. The default of
66-
/// Inlinter::runOnSCC() calls skipSCC() before calling this method, but
67-
/// derived classes which cannot be skipped can override that method and call
68-
/// this function unconditionally.
69-
bool inlineCalls(CallGraphSCC &SCC);
70-
71-
private:
72-
// Insert @llvm.lifetime intrinsics.
73-
bool InsertLifetime = true;
74-
75-
protected:
76-
AssumptionCacheTracker *ACT;
77-
ProfileSummaryInfo *PSI;
78-
std::function<const TargetLibraryInfo &(Function &)> GetTLI;
79-
ImportedFunctionsInliningStatistics ImportedFunctionsStats;
80-
};
81-
8226
/// The inliner pass for the new pass manager.
8327
///
8428
/// This pass wires together the inlining utilities and the inline cost

llvm/include/llvm/Transforms/Utils/Cloning.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,18 +203,15 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
203203
class InlineFunctionInfo {
204204
public:
205205
explicit InlineFunctionInfo(
206-
CallGraph *cg = nullptr,
207206
function_ref<AssumptionCache &(Function &)> GetAssumptionCache = nullptr,
208207
ProfileSummaryInfo *PSI = nullptr,
209208
BlockFrequencyInfo *CallerBFI = nullptr,
210209
BlockFrequencyInfo *CalleeBFI = nullptr, bool UpdateProfile = true)
211-
: CG(cg), GetAssumptionCache(GetAssumptionCache), PSI(PSI),
212-
CallerBFI(CallerBFI), CalleeBFI(CalleeBFI),
213-
UpdateProfile(UpdateProfile) {}
210+
: GetAssumptionCache(GetAssumptionCache), PSI(PSI), CallerBFI(CallerBFI),
211+
CalleeBFI(CalleeBFI), UpdateProfile(UpdateProfile) {}
214212

215213
/// If non-null, InlineFunction will update the callgraph to reflect the
216214
/// changes it makes.
217-
CallGraph *CG;
218215
function_ref<AssumptionCache &(Function &)> GetAssumptionCache;
219216
ProfileSummaryInfo *PSI;
220217
BlockFrequencyInfo *CallerBFI, *CalleeBFI;

llvm/lib/Analysis/AliasAnalysis.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -935,14 +935,3 @@ bool llvm::isNotVisibleOnUnwind(const Value *Object,
935935

936936
return false;
937937
}
938-
939-
void llvm::getAAResultsAnalysisUsage(AnalysisUsage &AU) {
940-
// This function needs to be in sync with llvm::createLegacyPMAAResults -- if
941-
// more alias analyses are added to llvm::createLegacyPMAAResults, they need
942-
// to be added here also.
943-
AU.addRequired<TargetLibraryInfoWrapperPass>();
944-
AU.addUsedIfAvailable<ScopedNoAliasAAWrapperPass>();
945-
AU.addUsedIfAvailable<TypeBasedAAWrapperPass>();
946-
AU.addUsedIfAvailable<GlobalsAAWrapperPass>();
947-
AU.addUsedIfAvailable<ExternalAAWrapperPass>();
948-
}

llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -974,12 +974,6 @@ void AMDGPUPassConfig::addIRPasses() {
974974
// Function calls are not supported, so make sure we inline everything.
975975
addPass(createAMDGPUAlwaysInlinePass());
976976
addPass(createAlwaysInlinerLegacyPass());
977-
// We need to add the barrier noop pass, otherwise adding the function
978-
// inlining pass will cause all of the PassConfigs passes to be run
979-
// one function at a time, which means if we have a module with two
980-
// functions, then we will generate code for the first function
981-
// without ever running any passes on the second.
982-
addPass(createBarrierNoopPass());
983977

984978
// Handle uses of OpenCL image2d_t, image3d_t and sampler_t arguments.
985979
if (TM.getTargetTriple().getArch() == Triple::r600)

llvm/lib/Transforms/IPO/AlwaysInliner.cpp

Lines changed: 56 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,13 @@ using namespace llvm;
2828

2929
#define DEBUG_TYPE "inline"
3030

31-
PreservedAnalyses AlwaysInlinerPass::run(Module &M,
32-
ModuleAnalysisManager &MAM) {
33-
// Add inline assumptions during code generation.
34-
FunctionAnalysisManager &FAM =
35-
MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
36-
auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
37-
return FAM.getResult<AssumptionAnalysis>(F);
38-
};
39-
auto &PSI = MAM.getResult<ProfileSummaryAnalysis>(M);
31+
namespace {
4032

33+
bool AlwaysInlineImpl(
34+
Module &M, bool InsertLifetime, ProfileSummaryInfo &PSI,
35+
function_ref<AssumptionCache &(Function &)> GetAssumptionCache,
36+
function_ref<AAResults &(Function &)> GetAAR,
37+
function_ref<BlockFrequencyInfo &(Function &)> GetBFI) {
4138
SmallSetVector<CallBase *, 16> Calls;
4239
bool Changed = false;
4340
SmallVector<Function *, 16> InlinedFunctions;
@@ -65,14 +62,12 @@ PreservedAnalyses AlwaysInlinerPass::run(Module &M,
6562
DebugLoc DLoc = CB->getDebugLoc();
6663
BasicBlock *Block = CB->getParent();
6764

68-
InlineFunctionInfo IFI(
69-
/*cg=*/nullptr, GetAssumptionCache, &PSI,
70-
&FAM.getResult<BlockFrequencyAnalysis>(*Caller),
71-
&FAM.getResult<BlockFrequencyAnalysis>(F));
65+
InlineFunctionInfo IFI(GetAssumptionCache, &PSI,
66+
GetBFI ? &GetBFI(*Caller) : nullptr,
67+
GetBFI ? &GetBFI(F) : nullptr);
7268

73-
InlineResult Res =
74-
InlineFunction(*CB, IFI, /*MergeAttributes=*/true,
75-
&FAM.getResult<AAManager>(F), InsertLifetime);
69+
InlineResult Res = InlineFunction(*CB, IFI, /*MergeAttributes=*/true,
70+
&GetAAR(F), InsertLifetime);
7671
if (!Res.isSuccess()) {
7772
ORE.emit([&]() {
7873
return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc,
@@ -127,95 +122,76 @@ PreservedAnalyses AlwaysInlinerPass::run(Module &M,
127122
}
128123
}
129124

130-
return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
125+
return Changed;
131126
}
132127

133-
namespace {
134-
135-
/// Inliner pass which only handles "always inline" functions.
136-
///
137-
/// Unlike the \c AlwaysInlinerPass, this uses the more heavyweight \c Inliner
138-
/// base class to provide several facilities such as array alloca merging.
139-
class AlwaysInlinerLegacyPass : public LegacyInlinerBase {
128+
struct AlwaysInlinerLegacyPass : public ModulePass {
129+
bool InsertLifetime;
140130

141-
public:
142-
AlwaysInlinerLegacyPass() : LegacyInlinerBase(ID, /*InsertLifetime*/ true) {
143-
initializeAlwaysInlinerLegacyPassPass(*PassRegistry::getPassRegistry());
144-
}
131+
AlwaysInlinerLegacyPass()
132+
: AlwaysInlinerLegacyPass(/*InsertLifetime*/ true) {}
145133

146134
AlwaysInlinerLegacyPass(bool InsertLifetime)
147-
: LegacyInlinerBase(ID, InsertLifetime) {
135+
: ModulePass(ID), InsertLifetime(InsertLifetime) {
148136
initializeAlwaysInlinerLegacyPassPass(*PassRegistry::getPassRegistry());
149137
}
150138

151139
/// Main run interface method. We override here to avoid calling skipSCC().
152-
bool runOnSCC(CallGraphSCC &SCC) override { return inlineCalls(SCC); }
140+
bool runOnModule(Module &M) override {
141+
142+
auto &PSI = getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
143+
auto GetAAR = [&](Function &F) -> AAResults & {
144+
return getAnalysis<AAResultsWrapperPass>(F).getAAResults();
145+
};
146+
auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
147+
return getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
148+
};
149+
150+
return AlwaysInlineImpl(M, InsertLifetime, PSI, GetAssumptionCache, GetAAR,
151+
/*GetBFI*/ nullptr);
152+
}
153153

154154
static char ID; // Pass identification, replacement for typeid
155155

156-
InlineCost getInlineCost(CallBase &CB) override;
157-
158-
using llvm::Pass::doFinalization;
159-
bool doFinalization(CallGraph &CG) override {
160-
return removeDeadFunctions(CG, /*AlwaysInlineOnly=*/true);
156+
void getAnalysisUsage(AnalysisUsage &AU) const override {
157+
AU.addRequired<AssumptionCacheTracker>();
158+
AU.addRequired<AAResultsWrapperPass>();
159+
AU.addRequired<ProfileSummaryInfoWrapperPass>();
161160
}
162161
};
163-
}
162+
163+
} // namespace
164164

165165
char AlwaysInlinerLegacyPass::ID = 0;
166166
INITIALIZE_PASS_BEGIN(AlwaysInlinerLegacyPass, "always-inline",
167167
"Inliner for always_inline functions", false, false)
168+
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
168169
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
169-
INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
170170
INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
171-
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
172171
INITIALIZE_PASS_END(AlwaysInlinerLegacyPass, "always-inline",
173172
"Inliner for always_inline functions", false, false)
174173

175174
Pass *llvm::createAlwaysInlinerLegacyPass(bool InsertLifetime) {
176175
return new AlwaysInlinerLegacyPass(InsertLifetime);
177176
}
178177

179-
/// Get the inline cost for the always-inliner.
180-
///
181-
/// The always inliner *only* handles functions which are marked with the
182-
/// attribute to force inlining. As such, it is dramatically simpler and avoids
183-
/// using the powerful (but expensive) inline cost analysis. Instead it uses
184-
/// a very simple and boring direct walk of the instructions looking for
185-
/// impossible-to-inline constructs.
186-
///
187-
/// Note, it would be possible to go to some lengths to cache the information
188-
/// computed here, but as we only expect to do this for relatively few and
189-
/// small functions which have the explicit attribute to force inlining, it is
190-
/// likely not worth it in practice.
191-
InlineCost AlwaysInlinerLegacyPass::getInlineCost(CallBase &CB) {
192-
Function *Callee = CB.getCalledFunction();
193-
194-
// Only inline direct calls to functions with always-inline attributes
195-
// that are viable for inlining.
196-
if (!Callee)
197-
return InlineCost::getNever("indirect call");
198-
199-
// When callee coroutine function is inlined into caller coroutine function
200-
// before coro-split pass,
201-
// coro-early pass can not handle this quiet well.
202-
// So we won't inline the coroutine function if it have not been unsplited
203-
if (Callee->isPresplitCoroutine())
204-
return InlineCost::getNever("unsplited coroutine call");
205-
206-
// FIXME: We shouldn't even get here for declarations.
207-
if (Callee->isDeclaration())
208-
return InlineCost::getNever("no definition");
209-
210-
if (!CB.hasFnAttr(Attribute::AlwaysInline))
211-
return InlineCost::getNever("no alwaysinline attribute");
212-
213-
if (Callee->hasFnAttribute(Attribute::AlwaysInline) && CB.isNoInline())
214-
return InlineCost::getNever("noinline call site attribute");
215-
216-
auto IsViable = isInlineViable(*Callee);
217-
if (!IsViable.isSuccess())
218-
return InlineCost::getNever(IsViable.getFailureReason());
219-
220-
return InlineCost::getAlways("always inliner");
178+
PreservedAnalyses AlwaysInlinerPass::run(Module &M,
179+
ModuleAnalysisManager &MAM) {
180+
FunctionAnalysisManager &FAM =
181+
MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
182+
auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
183+
return FAM.getResult<AssumptionAnalysis>(F);
184+
};
185+
auto GetBFI = [&](Function &F) -> BlockFrequencyInfo & {
186+
return FAM.getResult<BlockFrequencyAnalysis>(F);
187+
};
188+
auto GetAAR = [&](Function &F) -> AAResults & {
189+
return FAM.getResult<AAManager>(F);
190+
};
191+
auto &PSI = MAM.getResult<ProfileSummaryAnalysis>(M);
192+
193+
bool Changed = AlwaysInlineImpl(M, InsertLifetime, PSI, GetAssumptionCache,
194+
GetAAR, GetBFI);
195+
196+
return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
221197
}

0 commit comments

Comments
 (0)