Skip to content

Commit ab6a683

Browse files
committed
Avoid using a raw AssumptionCacheTracker in various inliner functions.
This unblocks the new PM part of River's patch in https://reviews.llvm.org/D22706 Conveniently, this same change was needed for D21921 and so these changes are just spun out from there. llvm-svn: 276515
1 parent c6b9be2 commit ab6a683

File tree

8 files changed

+115
-82
lines changed

8 files changed

+115
-82
lines changed

llvm/include/llvm/Analysis/InlineCost.h

+10-6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define LLVM_ANALYSIS_INLINECOST_H
1616

1717
#include "llvm/Analysis/CallGraphSCCPass.h"
18+
#include "llvm/Analysis/AssumptionCache.h"
1819
#include <cassert>
1920
#include <climits>
2021

@@ -110,18 +111,21 @@ class InlineCost {
110111
///
111112
/// Also note that calling this function *dynamically* computes the cost of
112113
/// inlining the callsite. It is an expensive, heavyweight call.
113-
InlineCost getInlineCost(CallSite CS, int DefaultThreshold,
114-
TargetTransformInfo &CalleeTTI,
115-
AssumptionCacheTracker *ACT, ProfileSummaryInfo *PSI);
114+
InlineCost
115+
getInlineCost(CallSite CS, int DefaultThreshold, TargetTransformInfo &CalleeTTI,
116+
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
117+
ProfileSummaryInfo *PSI);
116118

117119
/// \brief Get an InlineCost with the callee explicitly specified.
118120
/// This allows you to calculate the cost of inlining a function via a
119121
/// pointer. This behaves exactly as the version with no explicit callee
120122
/// parameter in all other respects.
121123
//
122-
InlineCost getInlineCost(CallSite CS, Function *Callee, int DefaultThreshold,
123-
TargetTransformInfo &CalleeTTI,
124-
AssumptionCacheTracker *ACT, ProfileSummaryInfo *PSI);
124+
InlineCost
125+
getInlineCost(CallSite CS, Function *Callee, int DefaultThreshold,
126+
TargetTransformInfo &CalleeTTI,
127+
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
128+
ProfileSummaryInfo *PSI);
125129

126130
int computeThresholdFromOptLevels(unsigned OptLevel, unsigned SizeOptLevel);
127131

llvm/include/llvm/Transforms/IPO/InlinerPass.h

+2-11
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#define LLVM_TRANSFORMS_IPO_INLINERPASS_H
1919

2020
#include "llvm/Analysis/CallGraphSCCPass.h"
21+
#include "llvm/Analysis/InlineCost.h"
22+
#include "llvm/Analysis/TargetTransformInfo.h"
2123

2224
namespace llvm {
2325
class AssumptionCacheTracker;
@@ -73,17 +75,6 @@ struct Inliner : public CallGraphSCCPass {
7375
// InsertLifetime - Insert @llvm.lifetime intrinsics.
7476
bool InsertLifetime;
7577

76-
/// shouldInline - Return true if the inliner should attempt to
77-
/// inline at the given CallSite.
78-
bool shouldInline(CallSite CS);
79-
/// Return true if inlining of CS can block the caller from being
80-
/// inlined which is proved to be more beneficial. \p IC is the
81-
/// estimated inline cost associated with callsite \p CS.
82-
/// \p TotalAltCost will be set to the estimated cost of inlining the caller
83-
/// if \p CS is suppressed for inlining.
84-
bool shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
85-
int &TotalAltCost);
86-
8778
protected:
8879
AssumptionCacheTracker *ACT;
8980
ProfileSummaryInfo *PSI;

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

+5-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/ADT/SmallVector.h"
2222
#include "llvm/ADT/Twine.h"
2323
#include "llvm/Analysis/AliasAnalysis.h"
24+
#include "llvm/Analysis/AssumptionCache.h"
2425
#include "llvm/IR/ValueHandle.h"
2526
#include "llvm/IR/ValueMap.h"
2627
#include "llvm/Transforms/Utils/ValueMapper.h"
@@ -176,13 +177,14 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
176177
class InlineFunctionInfo {
177178
public:
178179
explicit InlineFunctionInfo(CallGraph *cg = nullptr,
179-
AssumptionCacheTracker *ACT = nullptr)
180-
: CG(cg), ACT(ACT) {}
180+
std::function<AssumptionCache &(Function &)>
181+
*GetAssumptionCache = nullptr)
182+
: CG(cg), GetAssumptionCache(GetAssumptionCache) {}
181183

182184
/// CG - If non-null, InlineFunction will update the callgraph to reflect the
183185
/// changes it makes.
184186
CallGraph *CG;
185-
AssumptionCacheTracker *ACT;
187+
std::function<AssumptionCache &(Function &)> *GetAssumptionCache;
186188

187189
/// StaticAllocas - InlineFunction fills this in with all static allocas that
188190
/// get copied into the caller.

llvm/lib/Analysis/InlineCost.cpp

+29-29
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
7575
/// The TargetTransformInfo available for this compilation.
7676
const TargetTransformInfo &TTI;
7777

78-
/// The cache of @llvm.assume intrinsics.
79-
AssumptionCacheTracker *ACT;
78+
/// Getter for the cache of @llvm.assume intrinsics.
79+
std::function<AssumptionCache &(Function &)> &GetAssumptionCache;
8080

8181
/// Profile summary information.
8282
ProfileSummaryInfo *PSI;
@@ -203,20 +203,21 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
203203
bool visitUnreachableInst(UnreachableInst &I);
204204

205205
public:
206-
CallAnalyzer(const TargetTransformInfo &TTI, AssumptionCacheTracker *ACT,
206+
CallAnalyzer(const TargetTransformInfo &TTI,
207+
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
207208
ProfileSummaryInfo *PSI, Function &Callee, int Threshold,
208209
CallSite CSArg)
209-
: TTI(TTI), ACT(ACT), PSI(PSI), F(Callee), CandidateCS(CSArg),
210-
Threshold(Threshold), Cost(0), IsCallerRecursive(false),
211-
IsRecursiveCall(false), ExposesReturnsTwice(false),
212-
HasDynamicAlloca(false), ContainsNoDuplicateCall(false),
213-
HasReturn(false), HasIndirectBr(false), HasFrameEscape(false),
214-
AllocatedSize(0), NumInstructions(0), NumVectorInstructions(0),
215-
FiftyPercentVectorBonus(0), TenPercentVectorBonus(0), VectorBonus(0),
216-
NumConstantArgs(0), NumConstantOffsetPtrArgs(0), NumAllocaArgs(0),
217-
NumConstantPtrCmps(0), NumConstantPtrDiffs(0),
218-
NumInstructionsSimplified(0), SROACostSavings(0),
219-
SROACostSavingsLost(0) {}
210+
: TTI(TTI), GetAssumptionCache(GetAssumptionCache), PSI(PSI), F(Callee),
211+
CandidateCS(CSArg), Threshold(Threshold), Cost(0),
212+
IsCallerRecursive(false), IsRecursiveCall(false),
213+
ExposesReturnsTwice(false), HasDynamicAlloca(false),
214+
ContainsNoDuplicateCall(false), HasReturn(false), HasIndirectBr(false),
215+
HasFrameEscape(false), AllocatedSize(0), NumInstructions(0),
216+
NumVectorInstructions(0), FiftyPercentVectorBonus(0),
217+
TenPercentVectorBonus(0), VectorBonus(0), NumConstantArgs(0),
218+
NumConstantOffsetPtrArgs(0), NumAllocaArgs(0), NumConstantPtrCmps(0),
219+
NumConstantPtrDiffs(0), NumInstructionsSimplified(0),
220+
SROACostSavings(0), SROACostSavingsLost(0) {}
220221

221222
bool analyzeCall(CallSite CS);
222223

@@ -957,8 +958,8 @@ bool CallAnalyzer::visitCallSite(CallSite CS) {
957958
// during devirtualization and so we want to give it a hefty bonus for
958959
// inlining, but cap that bonus in the event that inlining wouldn't pan
959960
// out. Pretend to inline the function, with a custom threshold.
960-
CallAnalyzer CA(TTI, ACT, PSI, *F, InlineConstants::IndirectCallThreshold,
961-
CS);
961+
CallAnalyzer CA(TTI, GetAssumptionCache, PSI, *F,
962+
InlineConstants::IndirectCallThreshold, CS);
962963
if (CA.analyzeCall(CS)) {
963964
// We were able to inline the indirect call! Subtract the cost from the
964965
// threshold to get the bonus we want to apply, but don't go below zero.
@@ -1312,8 +1313,7 @@ bool CallAnalyzer::analyzeCall(CallSite CS) {
13121313
// the ephemeral values multiple times (and they're completely determined by
13131314
// the callee, so this is purely duplicate work).
13141315
SmallPtrSet<const Value *, 32> EphValues;
1315-
CodeMetrics::collectEphemeralValues(&F, &ACT->getAssumptionCache(F),
1316-
EphValues);
1316+
CodeMetrics::collectEphemeralValues(&F, &GetAssumptionCache(F), EphValues);
13171317

13181318
// The worklist of live basic blocks in the callee *after* inlining. We avoid
13191319
// adding basic blocks of the callee which can be proven to be dead for this
@@ -1444,12 +1444,12 @@ static bool functionsHaveCompatibleAttributes(Function *Caller,
14441444
AttributeFuncs::areInlineCompatible(*Caller, *Callee);
14451445
}
14461446

1447-
InlineCost llvm::getInlineCost(CallSite CS, int DefaultThreshold,
1448-
TargetTransformInfo &CalleeTTI,
1449-
AssumptionCacheTracker *ACT,
1450-
ProfileSummaryInfo *PSI) {
1447+
InlineCost llvm::getInlineCost(
1448+
CallSite CS, int DefaultThreshold, TargetTransformInfo &CalleeTTI,
1449+
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
1450+
ProfileSummaryInfo *PSI) {
14511451
return getInlineCost(CS, CS.getCalledFunction(), DefaultThreshold, CalleeTTI,
1452-
ACT, PSI);
1452+
GetAssumptionCache, PSI);
14531453
}
14541454

14551455
int llvm::computeThresholdFromOptLevels(unsigned OptLevel,
@@ -1465,11 +1465,11 @@ int llvm::computeThresholdFromOptLevels(unsigned OptLevel,
14651465

14661466
int llvm::getDefaultInlineThreshold() { return DefaultInlineThreshold; }
14671467

1468-
InlineCost llvm::getInlineCost(CallSite CS, Function *Callee,
1469-
int DefaultThreshold,
1470-
TargetTransformInfo &CalleeTTI,
1471-
AssumptionCacheTracker *ACT,
1472-
ProfileSummaryInfo *PSI) {
1468+
InlineCost llvm::getInlineCost(
1469+
CallSite CS, Function *Callee, int DefaultThreshold,
1470+
TargetTransformInfo &CalleeTTI,
1471+
std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
1472+
ProfileSummaryInfo *PSI) {
14731473

14741474
// Cannot inline indirect calls.
14751475
if (!Callee)
@@ -1503,7 +1503,7 @@ InlineCost llvm::getInlineCost(CallSite CS, Function *Callee,
15031503
DEBUG(llvm::dbgs() << " Analyzing call of " << Callee->getName()
15041504
<< "...\n");
15051505

1506-
CallAnalyzer CA(CalleeTTI, ACT, PSI, *Callee, DefaultThreshold, CS);
1506+
CallAnalyzer CA(CalleeTTI, GetAssumptionCache, PSI, *Callee, DefaultThreshold, CS);
15071507
bool ShouldInline = CA.analyzeCall(CS);
15081508

15091509
DEBUG(CA.dump());

llvm/lib/Transforms/IPO/InlineSimple.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,12 @@ class SimpleInliner : public Inliner {
6161
InlineCost getInlineCost(CallSite CS) override {
6262
Function *Callee = CS.getCalledFunction();
6363
TargetTransformInfo &TTI = TTIWP->getTTI(*Callee);
64-
return llvm::getInlineCost(CS, DefaultThreshold, TTI, ACT, PSI);
64+
std::function<AssumptionCache &(Function &)> GetAssumptionCache = [&](
65+
Function &F) -> AssumptionCache & {
66+
return ACT->getAssumptionCache(F);
67+
};
68+
return llvm::getInlineCost(CS, DefaultThreshold, TTI, GetAssumptionCache,
69+
PSI);
6570
}
6671

6772
bool runOnSCC(CallGraphSCC &SCC) override;

llvm/lib/Transforms/IPO/Inliner.cpp

+55-26
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,15 @@ InlinedArrayAllocasTy;
7575
/// available from other functions inlined into the caller. If we are able to
7676
/// inline this call site we attempt to reuse already available allocas or add
7777
/// any new allocas to the set if not possible.
78-
static bool InlineCallIfPossible(Pass &P, CallSite CS, InlineFunctionInfo &IFI,
79-
InlinedArrayAllocasTy &InlinedArrayAllocas,
80-
int InlineHistory, bool InsertLifetime) {
78+
static bool
79+
InlineCallIfPossible(CallSite CS, InlineFunctionInfo &IFI,
80+
InlinedArrayAllocasTy &InlinedArrayAllocas,
81+
int InlineHistory, bool InsertLifetime,
82+
std::function<AAResults &(Function &)> &AARGetter) {
8183
Function *Callee = CS.getCalledFunction();
8284
Function *Caller = CS.getCaller();
8385

84-
// We need to manually construct BasicAA directly in order to disable
85-
// its use of other function analyses.
86-
BasicAAResult BAR(createLegacyPMBasicAAResult(P, *Callee));
87-
88-
// Construct our own AA results for this function. We do this manually to
89-
// work around the limitations of the legacy pass manager.
90-
AAResults AAR(createLegacyPMAAResults(P, *Callee, BAR));
86+
AAResults &AAR = AARGetter(*Callee);
9187

9288
// Try to inline the function. Get the list of static allocas that were
9389
// inlined.
@@ -229,8 +225,15 @@ static void emitAnalysis(CallSite CS, const Twine &Msg) {
229225
emitOptimizationRemarkAnalysis(Ctx, DEBUG_TYPE, *Caller, DLoc, Msg);
230226
}
231227

232-
bool Inliner::shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
233-
int &TotalSecondaryCost) {
228+
/// Return true if inlining of CS can block the caller from being
229+
/// inlined which is proved to be more beneficial. \p IC is the
230+
/// estimated inline cost associated with callsite \p CS.
231+
/// \p TotalAltCost will be set to the estimated cost of inlining the caller
232+
/// if \p CS is suppressed for inlining.
233+
static bool
234+
shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
235+
int &TotalSecondaryCost,
236+
std::function<InlineCost(CallSite CS)> &GetInlineCost) {
234237

235238
// For now we only handle local or inline functions.
236239
if (!Caller->hasLocalLinkage() && !Caller->hasLinkOnceODRLinkage())
@@ -269,7 +272,7 @@ bool Inliner::shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
269272
continue;
270273
}
271274

272-
InlineCost IC2 = getInlineCost(CS2);
275+
InlineCost IC2 = GetInlineCost(CS2);
273276
++NumCallerCallersAnalyzed;
274277
if (!IC2) {
275278
callerWillBeRemoved = false;
@@ -300,8 +303,9 @@ bool Inliner::shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
300303
}
301304

302305
/// Return true if the inliner should attempt to inline at the given CallSite.
303-
bool Inliner::shouldInline(CallSite CS) {
304-
InlineCost IC = getInlineCost(CS);
306+
static bool shouldInline(CallSite CS,
307+
std::function<InlineCost(CallSite CS)> GetInlineCost) {
308+
InlineCost IC = GetInlineCost(CS);
305309

306310
if (IC.isAlways()) {
307311
DEBUG(dbgs() << " Inlining: cost=always"
@@ -332,7 +336,7 @@ bool Inliner::shouldInline(CallSite CS) {
332336
}
333337

334338
int TotalSecondaryCost = 0;
335-
if (shouldBeDeferred(Caller, CS, IC, TotalSecondaryCost)) {
339+
if (shouldBeDeferred(Caller, CS, IC, TotalSecondaryCost, GetInlineCost)) {
336340
DEBUG(dbgs() << " NOT Inlining: " << *CS.getInstruction()
337341
<< " Cost = " << IC.getCost()
338342
<< ", outer Cost = " << TotalSecondaryCost << '\n');
@@ -370,15 +374,17 @@ static bool InlineHistoryIncludes(Function *F, int InlineHistoryID,
370374
bool Inliner::runOnSCC(CallGraphSCC &SCC) {
371375
if (skipSCC(SCC))
372376
return false;
377+
373378
return inlineCalls(SCC);
374379
}
375380

376-
bool Inliner::inlineCalls(CallGraphSCC &SCC) {
377-
CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
378-
ACT = &getAnalysis<AssumptionCacheTracker>();
379-
PSI = getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI(CG.getModule());
380-
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
381-
381+
static bool
382+
inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
383+
std::function<AssumptionCache &(Function &)> GetAssumptionCache,
384+
ProfileSummaryInfo *PSI, TargetLibraryInfo &TLI,
385+
bool InsertLifetime,
386+
std::function<InlineCost(CallSite CS)> GetInlineCost,
387+
std::function<AAResults &(Function &)> AARGetter) {
382388
SmallPtrSet<Function*, 8> SCCFunctions;
383389
DEBUG(dbgs() << "Inliner visiting SCC:");
384390
for (CallGraphNode *Node : SCC) {
@@ -437,7 +443,7 @@ bool Inliner::inlineCalls(CallGraphSCC &SCC) {
437443

438444

439445
InlinedArrayAllocasTy InlinedArrayAllocas;
440-
InlineFunctionInfo InlineInfo(&CG, ACT);
446+
InlineFunctionInfo InlineInfo(&CG, &GetAssumptionCache);
441447

442448
// Now that we have all of the call sites, loop over them and inline them if
443449
// it looks profitable to do so.
@@ -486,7 +492,7 @@ bool Inliner::inlineCalls(CallGraphSCC &SCC) {
486492

487493
// If the policy determines that we should inline this function,
488494
// try to do so.
489-
if (!shouldInline(CS)) {
495+
if (!shouldInline(CS, GetInlineCost)) {
490496
emitOptimizationRemarkMissed(CallerCtx, DEBUG_TYPE, *Caller, DLoc,
491497
Twine(Callee->getName() +
492498
" will not be inlined into " +
@@ -495,8 +501,8 @@ bool Inliner::inlineCalls(CallGraphSCC &SCC) {
495501
}
496502

497503
// Attempt to inline the function.
498-
if (!InlineCallIfPossible(*this, CS, InlineInfo, InlinedArrayAllocas,
499-
InlineHistoryID, InsertLifetime)) {
504+
if (!InlineCallIfPossible(CS, InlineInfo, InlinedArrayAllocas,
505+
InlineHistoryID, InsertLifetime, AARGetter)) {
500506
emitOptimizationRemarkMissed(CallerCtx, DEBUG_TYPE, *Caller, DLoc,
501507
Twine(Callee->getName() +
502508
" will not be inlined into " +
@@ -565,6 +571,29 @@ bool Inliner::inlineCalls(CallGraphSCC &SCC) {
565571
return Changed;
566572
}
567573

574+
bool Inliner::inlineCalls(CallGraphSCC &SCC) {
575+
CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
576+
ACT = &getAnalysis<AssumptionCacheTracker>();
577+
PSI = getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI(CG.getModule());
578+
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
579+
// We compute dedicated AA results for each function in the SCC as needed. We
580+
// use a lambda referencing external objects so that they live long enough to
581+
// be queried, but we re-use them each time.
582+
Optional<BasicAAResult> BAR;
583+
Optional<AAResults> AAR;
584+
auto AARGetter = [&](Function &F) -> AAResults & {
585+
BAR.emplace(createLegacyPMBasicAAResult(*this, F));
586+
AAR.emplace(createLegacyPMAAResults(*this, F, *BAR));
587+
return *AAR;
588+
};
589+
auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
590+
return ACT->getAssumptionCache(F);
591+
};
592+
return inlineCallsImpl(SCC, CG, GetAssumptionCache, PSI, TLI, InsertLifetime,
593+
[this](CallSite CS) { return getInlineCost(CS); },
594+
AARGetter);
595+
}
596+
568597
/// Remove now-dead linkonce functions at the end of
569598
/// processing to avoid breaking the SCC traversal.
570599
bool Inliner::doFinalization(CallGraph &CG) {

llvm/lib/Transforms/IPO/SampleProfile.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,8 @@ SampleProfileLoader::findFunctionSamples(const Instruction &Inst) const {
627627
bool SampleProfileLoader::inlineHotFunctions(Function &F) {
628628
bool Changed = false;
629629
LLVMContext &Ctx = F.getContext();
630+
std::function<AssumptionCache &(Function &)> GetAssumptionCache = [&](
631+
Function &F) -> AssumptionCache & { return ACT->getAssumptionCache(F); };
630632
while (true) {
631633
bool LocalChanged = false;
632634
SmallVector<CallInst *, 10> CIS;
@@ -638,7 +640,7 @@ bool SampleProfileLoader::inlineHotFunctions(Function &F) {
638640
}
639641
}
640642
for (auto CI : CIS) {
641-
InlineFunctionInfo IFI(nullptr, ACT);
643+
InlineFunctionInfo IFI(nullptr, ACT ? &GetAssumptionCache : nullptr);
642644
Function *CalledFunction = CI->getCalledFunction();
643645
DebugLoc DLoc = CI->getDebugLoc();
644646
uint64_t NumSamples = findCalleeFunctionSamples(*CI)->getTotalSamples();

0 commit comments

Comments
 (0)