[llvm] 655aa1a - [llvm][NFC] Replace CallSite with CallBase in Inliner
Mircea Trofin via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 9 15:02:16 PDT 2020
Author: Mircea Trofin
Date: 2020-04-09T15:01:58-07:00
New Revision: 655aa1ae4af46a5c89e25e1b6c5958eb7395d028
URL: https://github.com/llvm/llvm-project/commit/655aa1ae4af46a5c89e25e1b6c5958eb7395d028
DIFF: https://github.com/llvm/llvm-project/commit/655aa1ae4af46a5c89e25e1b6c5958eb7395d028.diff
LOG: [llvm][NFC] Replace CallSite with CallBase in Inliner
Summary:
*Almost* all uses are replaced. Left FIXMEs for the two sites that
require refactoring outside of Inliner, to scope this patch.
Subscribers: eraman, hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D77817
Added:
Modified:
llvm/include/llvm/Transforms/IPO/Inliner.h
llvm/lib/Transforms/IPO/Inliner.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Transforms/IPO/Inliner.h b/llvm/include/llvm/Transforms/IPO/Inliner.h
index 38137e9d6cec..a211d1ad252f 100644
--- a/llvm/include/llvm/Transforms/IPO/Inliner.h
+++ b/llvm/include/llvm/Transforms/IPO/Inliner.h
@@ -51,8 +51,16 @@ struct LegacyInlinerBase : public CallGraphSCCPass {
/// This method must be implemented by the subclass to determine the cost of
/// inlining the specified call site. If the cost returned is greater than
/// the current inline threshold, the call site is not inlined.
+ // FIXME(mtrofin): remove this in favor of the CallBase-based one
virtual InlineCost getInlineCost(CallSite CS) = 0;
+ /// This method must be implemented by the subclass to determine the cost of
+ /// inlining the specified call site. If the cost returned is greater than
+ /// the current inline threshold, the call site is not inlined.
+ virtual InlineCost getInlineCost(CallBase &CB) {
+ return getInlineCost(CallSite(&CB));
+ }
+
/// Remove dead functions.
///
/// This also includes a hack in the form of the 'AlwaysInlineOnly' flag
diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp
index 1b10c5433b46..c9eac60cc574 100644
--- a/llvm/lib/Transforms/IPO/Inliner.cpp
+++ b/llvm/lib/Transforms/IPO/Inliner.cpp
@@ -273,7 +273,7 @@ static void mergeInlinedArrayAllocas(
/// inline this call site we attempt to reuse already available allocas or add
/// any new allocas to the set if not possible.
static InlineResult InlineCallIfPossible(
- CallSite CS, InlineFunctionInfo &IFI,
+ CallBase &CS, InlineFunctionInfo &IFI,
InlinedArrayAllocasTy &InlinedArrayAllocas, int InlineHistory,
bool InsertLifetime, function_ref<AAResults &(Function &)> &AARGetter,
ImportedFunctionsInliningStatistics &ImportedFunctionsStats) {
@@ -284,7 +284,7 @@ static InlineResult InlineCallIfPossible(
// Try to inline the function. Get the list of static allocas that were
// inlined.
- InlineResult IR = InlineFunction(CS, IFI, &AAR, InsertLifetime);
+ InlineResult IR = InlineFunction(&CS, IFI, &AAR, InsertLifetime);
if (!IR.isSuccess())
return IR;
@@ -305,9 +305,8 @@ static InlineResult InlineCallIfPossible(
/// \p TotalSecondaryCost will be set to the estimated cost of inlining the
/// caller if \p CS is suppressed for inlining.
static bool
-shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
- int &TotalSecondaryCost,
- function_ref<InlineCost(CallSite CS)> GetInlineCost) {
+shouldBeDeferred(Function *Caller, InlineCost IC, int &TotalSecondaryCost,
+ function_ref<InlineCost(CallBase &CS)> GetInlineCost) {
// For now we only handle local or inline functions.
if (!Caller->hasLocalLinkage() && !Caller->hasLinkOnceODRLinkage())
return false;
@@ -346,17 +345,17 @@ shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
// applied), then we can exit the loop early.
if (!ApplyLastCallBonus && TotalSecondaryCost >= IC.getCost())
return false;
- CallSite CS2(U);
+ CallBase *CS2 = dyn_cast<CallBase>(U);
// If this isn't a call to Caller (it could be some other sort
// of reference) skip it. Such references will prevent the caller
// from being removed.
- if (!CS2 || CS2.getCalledFunction() != Caller) {
+ if (!CS2 || CS2->getCalledFunction() != Caller) {
ApplyLastCallBonus = false;
continue;
}
- InlineCost IC2 = GetInlineCost(CS2);
+ InlineCost IC2 = GetInlineCost(*CS2);
++NumCallerCallersAnalyzed;
if (!IC2) {
ApplyLastCallBonus = false;
@@ -417,24 +416,24 @@ static std::string inlineCostStr(const InlineCost &IC) {
/// CallSite. If we return the cost, we will emit an optimisation remark later
/// using that cost, so we won't do so from this function.
static Optional<InlineCost>
-shouldInline(CallSite CS, function_ref<InlineCost(CallSite CS)> GetInlineCost,
+shouldInline(CallBase &CS, function_ref<InlineCost(CallBase &CS)> GetInlineCost,
OptimizationRemarkEmitter &ORE) {
using namespace ore;
InlineCost IC = GetInlineCost(CS);
- Instruction *Call = CS.getInstruction();
+ Instruction *Call = &CS;
Function *Callee = CS.getCalledFunction();
Function *Caller = CS.getCaller();
if (IC.isAlways()) {
LLVM_DEBUG(dbgs() << " Inlining " << inlineCostStr(IC)
- << ", Call: " << *CS.getInstruction() << "\n");
+ << ", Call: " << CS << "\n");
return IC;
}
if (IC.isNever()) {
LLVM_DEBUG(dbgs() << " NOT Inlining " << inlineCostStr(IC)
- << ", Call: " << *CS.getInstruction() << "\n");
+ << ", Call: " << CS << "\n");
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline", Call)
<< NV("Callee", Callee) << " not inlined into "
@@ -446,7 +445,7 @@ shouldInline(CallSite CS, function_ref<InlineCost(CallSite CS)> GetInlineCost,
if (!IC) {
LLVM_DEBUG(dbgs() << " NOT Inlining " << inlineCostStr(IC)
- << ", Call: " << *CS.getInstruction() << "\n");
+ << ", Call: " << CS << "\n");
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "TooCostly", Call)
<< NV("Callee", Callee) << " not inlined into "
@@ -456,8 +455,8 @@ shouldInline(CallSite CS, function_ref<InlineCost(CallSite CS)> GetInlineCost,
}
int TotalSecondaryCost = 0;
- if (shouldBeDeferred(Caller, CS, IC, TotalSecondaryCost, GetInlineCost)) {
- LLVM_DEBUG(dbgs() << " NOT Inlining: " << *CS.getInstruction()
+ if (shouldBeDeferred(Caller, IC, TotalSecondaryCost, GetInlineCost)) {
+ LLVM_DEBUG(dbgs() << " NOT Inlining: " << CS
<< " Cost = " << IC.getCost()
<< ", outer Cost = " << TotalSecondaryCost << '\n');
ORE.emit([&]() {
@@ -473,8 +472,8 @@ shouldInline(CallSite CS, function_ref<InlineCost(CallSite CS)> GetInlineCost,
return None;
}
- LLVM_DEBUG(dbgs() << " Inlining " << inlineCostStr(IC)
- << ", Call: " << *CS.getInstruction() << '\n');
+ LLVM_DEBUG(dbgs() << " Inlining " << inlineCostStr(IC) << ", Call: " << CS
+ << '\n');
return IC;
}
@@ -517,11 +516,11 @@ static void emit_inlined_into(OptimizationRemarkEmitter &ORE, DebugLoc &DLoc,
});
}
-static void setInlineRemark(CallSite &CS, StringRef message) {
+static void setInlineRemark(CallBase &CS, StringRef Message) {
if (!InlineRemarkAttribute)
return;
- Attribute attr = Attribute::get(CS->getContext(), "inline-remark", message);
+ Attribute attr = Attribute::get(CS.getContext(), "inline-remark", Message);
CS.addAttribute(AttributeList::FunctionIndex, attr);
}
@@ -531,7 +530,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
ProfileSummaryInfo *PSI,
std::function<const TargetLibraryInfo &(Function &)> GetTLI,
bool InsertLifetime,
- function_ref<InlineCost(CallSite CS)> GetInlineCost,
+ function_ref<InlineCost(CallBase &CS)> GetInlineCost,
function_ref<AAResults &(Function &)> AARGetter,
ImportedFunctionsInliningStatistics &ImportedFunctionsStats) {
SmallPtrSet<Function *, 8> SCCFunctions;
@@ -546,7 +545,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
// Scan through and identify all call sites ahead of time so that we only
// inline call sites in the original functions, not call sites that result
// from inlining other functions.
- SmallVector<std::pair<CallSite, int>, 16> CallSites;
+ SmallVector<std::pair<CallBase *, int>, 16> CallSites;
// When inlining a callee produces new call sites, we want to keep track of
// the fact that they were inlined from the callee. This allows us to avoid
@@ -562,7 +561,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
OptimizationRemarkEmitter ORE(F);
for (BasicBlock &BB : *F)
for (Instruction &I : BB) {
- CallSite CS(cast<Value>(&I));
+ auto *CS = dyn_cast<CallBase>(&I);
// If this isn't a call, or it is a call to an intrinsic, it can
// never be inlined.
if (!CS || isa<IntrinsicInst>(I))
@@ -571,15 +570,15 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
// If this is a direct call to an external function, we can never inline
// it. If it is an indirect call, inlining may resolve it to be a
// direct call, so we keep it.
- if (Function *Callee = CS.getCalledFunction())
+ if (Function *Callee = CS->getCalledFunction())
if (Callee->isDeclaration()) {
using namespace ore;
- setInlineRemark(CS, "unavailable definition");
+ setInlineRemark(*CS, "unavailable definition");
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NoDefinition", &I)
<< NV("Callee", Callee) << " will not be inlined into "
- << NV("Caller", CS.getCaller())
+ << NV("Caller", CS->getCaller())
<< " because its definition is unavailable"
<< setIsVerbose();
});
@@ -600,7 +599,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
// current SCC to the end of the list.
unsigned FirstCallInSCC = CallSites.size();
for (unsigned i = 0; i < FirstCallInSCC; ++i)
- if (Function *F = CallSites[i].first.getCalledFunction())
+ if (Function *F = CallSites[i].first->getCalledFunction())
if (SCCFunctions.count(F))
std::swap(CallSites[i--], CallSites[--FirstCallInSCC]);
@@ -617,7 +616,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
// calls to become direct calls.
// CallSites may be modified inside so ranged for loop can not be used.
for (unsigned CSi = 0; CSi != CallSites.size(); ++CSi) {
- CallSite CS = CallSites[CSi].first;
+ CallBase &CS = *CallSites[CSi].first;
Function *Caller = CS.getCaller();
Function *Callee = CS.getCalledFunction();
@@ -626,7 +625,7 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
if (!Callee || Callee->isDeclaration())
continue;
- Instruction *Instr = CS.getInstruction();
+ Instruction *Instr = &CS;
bool IsTriviallyDead =
isInstructionTriviallyDead(Instr, &GetTLI(*Caller));
@@ -674,12 +673,12 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
LLVM_DEBUG(dbgs() << " -> Deleting dead call: " << *Instr << "\n");
// Update the call graph by deleting the edge from Callee to Caller.
setInlineRemark(CS, "trivially dead");
- CG[Caller]->removeCallEdgeFor(*cast<CallBase>(CS.getInstruction()));
+ CG[Caller]->removeCallEdgeFor(CS);
Instr->eraseFromParent();
++NumCallsDeleted;
} else {
// Get DebugLoc to report. CS will be invalid after Inliner.
- DebugLoc DLoc = CS->getDebugLoc();
+ DebugLoc DLoc = CS.getDebugLoc();
BasicBlock *Block = CS.getParent();
// Attempt to inline the function.
@@ -717,16 +716,17 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG,
// happen when a callsite is simpilfied to reusing the return value
// of another callsite during function cloning, thus the other
// callsite will be reconsidered here.
- DenseSet<CallSite> DbgCallSites;
+ DenseSet<CallBase *> DbgCallSites;
for (auto &II : CallSites)
DbgCallSites.insert(II.first);
#endif
for (Value *Ptr : InlineInfo.InlinedCalls) {
#ifndef NDEBUG
- assert(DbgCallSites.count(CallSite(Ptr)) == 0);
+ assert(DbgCallSites.count(dyn_cast<CallBase>(Ptr)) == 0);
#endif
- CallSites.push_back(std::make_pair(CallSite(Ptr), NewHistoryID));
+ CallSites.push_back(
+ std::make_pair(dyn_cast<CallBase>(Ptr), NewHistoryID));
}
}
}
@@ -784,8 +784,8 @@ bool LegacyInlinerBase::inlineCalls(CallGraphSCC &SCC) {
};
return inlineCallsImpl(
SCC, CG, GetAssumptionCache, PSI, GetTLI, InsertLifetime,
- [this](CallSite CS) { return getInlineCost(CS); }, LegacyAARGetter(*this),
- ImportedFunctionsStats);
+ [this](CallBase &CS) { return getInlineCost(CS); },
+ LegacyAARGetter(*this), ImportedFunctionsStats);
}
/// Remove now-dead linkonce functions at the end of
@@ -929,7 +929,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
// this model, but it is uniformly spread across all the functions in the SCC
// and eventually they all become too large to inline, rather than
// incrementally maknig a single function grow in a super linear fashion.
- SmallVector<std::pair<CallSite, int>, 16> Calls;
+ SmallVector<std::pair<CallBase *, int>, 16> Calls;
FunctionAnalysisManager &FAM =
AM.getResult<FunctionAnalysisManagerCGSCCProxy>(InitialC, CG)
@@ -945,17 +945,17 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
// FIXME: Using instructions sequence is a really bad way to do this.
// Instead we should do an actual RPO walk of the function body.
for (Instruction &I : instructions(N.getFunction()))
- if (auto CS = CallSite(&I))
- if (Function *Callee = CS.getCalledFunction()) {
+ if (auto *CS = dyn_cast<CallBase>(&I))
+ if (Function *Callee = CS->getCalledFunction()) {
if (!Callee->isDeclaration())
Calls.push_back({CS, -1});
else if (!isa<IntrinsicInst>(I)) {
using namespace ore;
- setInlineRemark(CS, "unavailable definition");
+ setInlineRemark(*CS, "unavailable definition");
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NoDefinition", &I)
<< NV("Callee", Callee) << " will not be inlined into "
- << NV("Caller", CS.getCaller())
+ << NV("Caller", CS->getCaller())
<< " because its definition is unavailable"
<< setIsVerbose();
});
@@ -991,12 +991,12 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
// have the same caller, so we first set up some shared infrastructure for
// this caller. We also do any pruning we can at this layer on the caller
// alone.
- Function &F = *Calls[i].first.getCaller();
+ Function &F = *Calls[i].first->getCaller();
LazyCallGraph::Node &N = *CG.lookup(F);
if (CG.lookupSCC(N) != C)
continue;
if (F.hasOptNone()) {
- setInlineRemark(Calls[i].first, "optnone attribute");
+ setInlineRemark(*Calls[i].first, "optnone attribute");
continue;
}
@@ -1027,30 +1027,29 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
return FAM.getResult<TargetLibraryAnalysis>(F);
};
- auto GetInlineCost = [&](CallSite CS) {
+ auto GetInlineCost = [&](CallBase &CS) {
Function &Callee = *CS.getCalledFunction();
auto &CalleeTTI = FAM.getResult<TargetIRAnalysis>(Callee);
bool RemarksEnabled =
Callee.getContext().getDiagHandlerPtr()->isMissedOptRemarkEnabled(
DEBUG_TYPE);
- return getInlineCost(cast<CallBase>(*CS.getInstruction()), Params,
- CalleeTTI, GetAssumptionCache, {GetBFI}, GetTLI, PSI,
- RemarksEnabled ? &ORE : nullptr);
+ return getInlineCost(CS, Params, CalleeTTI, GetAssumptionCache, {GetBFI},
+ GetTLI, PSI, RemarksEnabled ? &ORE : nullptr);
};
// Now process as many calls as we have within this caller in the sequnece.
// We bail out as soon as the caller has to change so we can update the
// call graph and prepare the context of that new caller.
bool DidInline = false;
- for (; i < (int)Calls.size() && Calls[i].first.getCaller() == &F; ++i) {
+ for (; i < (int)Calls.size() && Calls[i].first->getCaller() == &F; ++i) {
int InlineHistoryID;
- CallSite CS;
+ CallBase *CS = nullptr;
std::tie(CS, InlineHistoryID) = Calls[i];
- Function &Callee = *CS.getCalledFunction();
+ Function &Callee = *CS->getCalledFunction();
if (InlineHistoryID != -1 &&
InlineHistoryIncludes(&Callee, InlineHistoryID, InlineHistory)) {
- setInlineRemark(CS, "recursive");
+ setInlineRemark(*CS, "recursive");
continue;
}
@@ -1064,21 +1063,21 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
LLVM_DEBUG(dbgs() << "Skipping inlining internal SCC edge from a node "
"previously split out of this SCC by inlining: "
<< F.getName() << " -> " << Callee.getName() << "\n");
- setInlineRemark(CS, "recursive SCC split");
+ setInlineRemark(*CS, "recursive SCC split");
continue;
}
- Optional<InlineCost> OIC = shouldInline(CS, GetInlineCost, ORE);
+ Optional<InlineCost> OIC = shouldInline(*CS, GetInlineCost, ORE);
// Check whether we want to inline this callsite.
if (!OIC.hasValue()) {
- setInlineRemark(CS, "deferred");
+ setInlineRemark(*CS, "deferred");
continue;
}
if (!OIC.getValue()) {
// shouldInline() call returned a negative inline cost that explains
// why this callsite should not be inlined.
- setInlineRemark(CS, inlineCostStr(*OIC));
+ setInlineRemark(*CS, inlineCostStr(*OIC));
continue;
}
@@ -1086,19 +1085,19 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
// `InlineFunction` routine.
InlineFunctionInfo IFI(
/*cg=*/nullptr, &GetAssumptionCache, PSI,
- &FAM.getResult<BlockFrequencyAnalysis>(*(CS.getCaller())),
+ &FAM.getResult<BlockFrequencyAnalysis>(*(CS->getCaller())),
&FAM.getResult<BlockFrequencyAnalysis>(Callee));
// Get DebugLoc to report. CS will be invalid after Inliner.
DebugLoc DLoc = CS->getDebugLoc();
- BasicBlock *Block = CS.getParent();
+ BasicBlock *Block = CS->getParent();
using namespace ore;
InlineResult IR = InlineFunction(CS, IFI);
if (!IR.isSuccess()) {
- setInlineRemark(CS, std::string(IR.getFailureReason()) + "; " +
- inlineCostStr(*OIC));
+ setInlineRemark(*CS, std::string(IR.getFailureReason()) + "; " +
+ inlineCostStr(*OIC));
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
<< NV("Callee", &Callee) << " will not be inlined into "
@@ -1118,6 +1117,8 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
if (!IFI.InlinedCallSites.empty()) {
int NewHistoryID = InlineHistory.size();
InlineHistory.push_back({&Callee, InlineHistoryID});
+
+ // FIXME(mtrofin): refactor IFI.InlinedCallSites to be CallBase-based
for (CallSite &CS : reverse(IFI.InlinedCallSites)) {
Function *NewCallee = CS.getCalledFunction();
if (!NewCallee) {
@@ -1130,7 +1131,8 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
}
if (NewCallee)
if (!NewCallee->isDeclaration())
- Calls.push_back({CS, NewHistoryID});
+ Calls.push_back(
+ {cast<CallBase>(CS.getInstruction()), NewHistoryID});
}
}
@@ -1151,8 +1153,8 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
if (Callee.use_empty() && !CG.isLibFunction(Callee)) {
Calls.erase(
std::remove_if(Calls.begin() + i + 1, Calls.end(),
- [&Callee](const std::pair<CallSite, int> &Call) {
- return Call.first.getCaller() == &Callee;
+ [&Callee](const std::pair<CallBase *, int> &Call) {
+ return Call.first->getCaller() == &Callee;
}),
Calls.end());
// Clear the body and queue the function itself for deletion when we
More information about the llvm-commits
mailing list