[llvm] r314601 - Refactor the SamplePGO profile annotation logic to extract inlineCallInstruction. (NFC)
Dehao Chen via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 30 13:46:15 PDT 2017
Author: dehao
Date: Sat Sep 30 13:46:15 2017
New Revision: 314601
URL: http://llvm.org/viewvc/llvm-project?rev=314601&view=rev
Log:
Refactor the SamplePGO profile annotation logic to extract inlineCallInstruction. (NFC)
Modified:
llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp
Modified: llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp?rev=314601&r1=314600&r2=314601&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp Sat Sep 30 13:46:15 2017
@@ -172,6 +172,7 @@ protected:
std::vector<const FunctionSamples *>
findIndirectCallFunctionSamples(const Instruction &I) const;
const FunctionSamples *findFunctionSamples(const Instruction &I) const;
+ bool inlineCallInstruction(Instruction *I);
bool inlineHotFunctions(Function &F,
DenseSet<GlobalValue::GUID> &ImportGUIDs);
void printEdgeWeight(raw_ostream &OS, Edge E);
@@ -676,6 +677,39 @@ SampleProfileLoader::findFunctionSamples
return FS;
}
+bool SampleProfileLoader::inlineCallInstruction(Instruction *I) {
+ assert(isa<CallInst>(I) || isa<InvokeInst>(I));
+ CallSite CS(I);
+ Function *CalledFunction = CS.getCalledFunction();
+ assert(CalledFunction);
+ DebugLoc DLoc = I->getDebugLoc();
+ BasicBlock *BB = I->getParent();
+ InlineParams Params = getInlineParams();
+ Params.ComputeFullInlineCost = true;
+ // Checks if there is anything in the reachable portion of the callee at
+ // this callsite that makes this inlining potentially illegal. Need to
+ // set ComputeFullInlineCost, otherwise getInlineCost may return early
+ // when cost exceeds threshold without checking all IRs in the callee.
+ // The acutal cost does not matter because we only checks isNever() to
+ // see if it is legal to inline the callsite.
+ InlineCost Cost = getInlineCost(CS, Params, GetTTI(*CalledFunction), GetAC,
+ None, nullptr, nullptr);
+ if (Cost.isNever()) {
+ ORE->emit(OptimizationRemark(DEBUG_TYPE, "Not inline", DLoc, BB)
+ << "incompatible inlining");
+ return false;
+ }
+ InlineFunctionInfo IFI(nullptr, &GetAC);
+ if (InlineFunction(CS, IFI)) {
+ // The call to InlineFunction erases I, so we can't pass it here.
+ ORE->emit(OptimizationRemark(DEBUG_TYPE, "HotInline", DLoc, BB)
+ << "inlined hot callee '" << ore::NV("Callee", CalledFunction)
+ << "' into '" << ore::NV("Caller", BB->getParent()) << "'");
+ return true;
+ }
+ return false;
+}
+
/// \brief Iteratively inline hot callsites of a function.
///
/// Iteratively traverse all callsites of the function \p F, and find if
@@ -713,82 +747,55 @@ bool SampleProfileLoader::inlineHotFunct
}
}
for (auto I : CIS) {
- InlineFunctionInfo IFI(nullptr, &GetAC);
Function *CalledFunction = CallSite(I).getCalledFunction();
// Do not inline recursive calls.
if (CalledFunction == &F)
continue;
- Instruction *DI = I;
- if (!CalledFunction && !PromotedInsns.count(I) &&
- CallSite(I).isIndirectCall()) {
+ if (CallSite(I).isIndirectCall()) {
+ if (PromotedInsns.count(I))
+ continue;
for (const auto *FS : findIndirectCallFunctionSamples(*I)) {
auto CalleeFunctionName = FS->getName();
// If it is a recursive call, we do not inline it as it could bloat
// the code exponentially. There is way to better handle this, e.g.
// clone the caller first, and inline the cloned caller if it is
- // recursive. As llvm does not inline recursive calls, we will simply
- // ignore it instead of handling it explicitly.
+ // recursive. As llvm does not inline recursive calls, we will
+ // simply ignore it instead of handling it explicitly.
if (CalleeFunctionName == F.getName())
continue;
+
const char *Reason = "Callee function not available";
auto R = SymbolMap.find(CalleeFunctionName);
- if (R == SymbolMap.end())
- continue;
- CalledFunction = R->getValue();
- if (CalledFunction && isLegalToPromote(I, CalledFunction, &Reason)) {
- // The indirect target was promoted and inlined in the profile, as a
- // result, we do not have profile info for the branch probability.
- // We set the probability to 80% taken to indicate that the static
- // call is likely taken.
- DI = dyn_cast<Instruction>(
- promoteIndirectCall(I, CalledFunction, 80, 100, false, ORE)
+ if (R != SymbolMap.end() && R->getValue() &&
+ !R->getValue()->isDeclaration() &&
+ R->getValue()->getSubprogram() &&
+ isLegalToPromote(I, R->getValue(), &Reason)) {
+ // The indirect target was promoted and inlined in the profile,
+ // as a result, we do not have profile info for the branch
+ // probability. We set the probability to 80% taken to indicate
+ // that the static call is likely taken.
+ Instruction *DI = dyn_cast<Instruction>(
+ promoteIndirectCall(I, R->getValue(), 80, 100, false, ORE)
->stripPointerCasts());
PromotedInsns.insert(I);
+ // If profile mismatches, we should not attempt to inline DI.
+ if ((isa<CallInst>(DI) || isa<InvokeInst>(DI)) &&
+ inlineCallInstruction(DI))
+ LocalChanged = true;
} else {
- DEBUG(dbgs() << "\nFailed to promote indirect call to "
- << CalleeFunctionName << " because " << Reason
- << "\n");
- continue;
+ FS->findImportedFunctions(ImportGUIDs, F.getParent(),
+ Samples->getTotalSamples() *
+ SampleProfileHotThreshold / 100);
}
}
- // If there is profile mismatch, we should not attempt to inline DI.
- if (!isa<CallInst>(DI) && !isa<InvokeInst>(DI))
- continue;
- }
- if (!CalledFunction || !CalledFunction->getSubprogram()) {
- // Handles functions that are imported from other modules.
- for (const FunctionSamples *FS : findIndirectCallFunctionSamples(*I))
- FS->findImportedFunctions(
- ImportGUIDs, F.getParent(),
- Samples->getTotalSamples() * SampleProfileHotThreshold / 100);
- continue;
- }
- assert(isa<CallInst>(DI) || isa<InvokeInst>(DI));
- CallSite CS(DI);
- DebugLoc DLoc = I->getDebugLoc();
- BasicBlock *BB = I->getParent();
- InlineParams Params = getInlineParams();
- Params.ComputeFullInlineCost = true;
- // Checks if there is anything in the reachable portion of the callee at
- // this callsite that makes this inlining potentially illegal. Need to
- // set ComputeFullInlineCost, otherwise getInlineCost may return early
- // when cost exceeds threshold without checking all IRs in the callee.
- // The acutal cost does not matter because we only checks isNever() to
- // see if it is legal to inline the callsite.
- InlineCost Cost = getInlineCost(CS, Params, GetTTI(*CalledFunction), GetAC,
- None, nullptr, nullptr);
- if (Cost.isNever()) {
- ORE->emit(OptimizationRemark(DEBUG_TYPE, "Not inline", DLoc, BB)
- << "incompatible inlining");
- continue;
- }
- if (InlineFunction(CS, IFI)) {
- LocalChanged = true;
- // The call to InlineFunction erases DI, so we can't pass it here.
- ORE->emit(OptimizationRemark(DEBUG_TYPE, "HotInline", DLoc, BB)
- << "inlined hot callee '"
- << ore::NV("Callee", CalledFunction) << "' into '"
- << ore::NV("Caller", &F) << "'");
+ } else if (CalledFunction && CalledFunction->getSubprogram() &&
+ !CalledFunction->isDeclaration()) {
+ if (inlineCallInstruction(I))
+ LocalChanged = true;
+ } else {
+ findCalleeFunctionSamples(*I)->findImportedFunctions(
+ ImportGUIDs, F.getParent(),
+ Samples->getTotalSamples() * SampleProfileHotThreshold / 100);
}
}
if (LocalChanged) {
More information about the llvm-commits
mailing list