aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorDehao Chen <dehao@google.com>2017-10-10 21:13:50 +0000
committerDehao Chen <dehao@google.com>2017-10-10 21:13:50 +0000
commitded3597f2c1234ea8df401b5d1fd5cf096e64108 (patch)
tree083549059d1b8f419c482c091a97b1148a2cee2c /lib/Transforms
parentc6f64890a266c4512dc975b8585ab71534c59847 (diff)
downloadllvm-ded3597f2c1234ea8df401b5d1fd5cf096e64108.tar.gz
Use the first instruction's count to estimate the funciton's entry frequency.
Summary: In the current implementation, we only have accurate profile count for standalone symbols. For inlined functions, we do not have entry count data because it's not available in LBR. In this patch, we use the first instruction's frequency to estimiate the function's entry count, especially for inlined functions. This may be inaccurate due to debug info in optimized code. However, this is a better estimate than the static 80/20 estimation we have in the current implementation. Reviewers: tejohnson, davidxl Reviewed By: tejohnson Subscribers: sanjoy, llvm-commits, aprantl Differential Revision: https://reviews.llvm.org/D38478 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315369 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/IPO/SampleProfile.cpp29
1 files changed, 19 insertions, 10 deletions
diff --git a/lib/Transforms/IPO/SampleProfile.cpp b/lib/Transforms/IPO/SampleProfile.cpp
index 6df17ec400c..46b9914347b 100644
--- a/lib/Transforms/IPO/SampleProfile.cpp
+++ b/lib/Transforms/IPO/SampleProfile.cpp
@@ -171,7 +171,7 @@ protected:
ErrorOr<uint64_t> getBlockWeight(const BasicBlock *BB);
const FunctionSamples *findCalleeFunctionSamples(const Instruction &I) const;
std::vector<const FunctionSamples *>
- findIndirectCallFunctionSamples(const Instruction &I) const;
+ findIndirectCallFunctionSamples(const Instruction &I, uint64_t &Sum) const;
const FunctionSamples *findFunctionSamples(const Instruction &I) const;
bool inlineCallInstruction(Instruction *I);
bool inlineHotFunctions(Function &F,
@@ -625,10 +625,11 @@ SampleProfileLoader::findCalleeFunctionSamples(const Instruction &Inst) const {
}
/// Returns a vector of FunctionSamples that are the indirect call targets
-/// of \p Inst. The vector is sorted by the total number of samples.
+/// of \p Inst. The vector is sorted by the total number of samples. Stores
+/// the total call count of the indirect call in \p Sum.
std::vector<const FunctionSamples *>
SampleProfileLoader::findIndirectCallFunctionSamples(
- const Instruction &Inst) const {
+ const Instruction &Inst, uint64_t &Sum) const {
const DILocation *DIL = Inst.getDebugLoc();
std::vector<const FunctionSamples *> R;
@@ -640,16 +641,25 @@ SampleProfileLoader::findIndirectCallFunctionSamples(
if (FS == nullptr)
return R;
+ uint32_t LineOffset = getOffset(DIL);
+ uint32_t Discriminator = DIL->getBaseDiscriminator();
+
+ auto T = FS->findCallTargetMapAt(LineOffset, Discriminator);
+ Sum = 0;
+ if (T)
+ for (const auto &T_C : T.get())
+ Sum += T_C.second;
if (const FunctionSamplesMap *M = FS->findFunctionSamplesMapAt(
LineLocation(getOffset(DIL), DIL->getBaseDiscriminator()))) {
if (M->size() == 0)
return R;
for (const auto &NameFS : *M) {
+ Sum += NameFS.second.getEntrySamples();
R.push_back(&NameFS.second);
}
std::sort(R.begin(), R.end(),
[](const FunctionSamples *L, const FunctionSamples *R) {
- return L->getTotalSamples() > R->getTotalSamples();
+ return L->getEntrySamples() > R->getEntrySamples();
});
}
return R;
@@ -764,7 +774,8 @@ bool SampleProfileLoader::inlineHotFunctions(
if (CallSite(I).isIndirectCall()) {
if (PromotedInsns.count(I))
continue;
- for (const auto *FS : findIndirectCallFunctionSamples(*I)) {
+ uint64_t Sum;
+ for (const auto *FS : findIndirectCallFunctionSamples(*I, Sum)) {
if (IsThinLTOPreLink) {
FS->findImportedFunctions(ImportGUIDs, F.getParent(),
Samples->getTotalSamples() *
@@ -786,12 +797,10 @@ bool SampleProfileLoader::inlineHotFunctions(
!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.
+ uint64_t C = FS->getEntrySamples();
Instruction *DI = promoteIndirectCall(
- I, R->getValue(), 80, 100, false, ORE);
+ I, R->getValue(), C, Sum, false, ORE);
+ Sum -= C;
PromotedInsns.insert(I);
// If profile mismatches, we should not attempt to inline DI.
if ((isa<CallInst>(DI) || isa<InvokeInst>(DI)) &&