summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorRong Xu <xur@google.com>2016-03-28 17:08:56 +0000
committerRong Xu <xur@google.com>2016-03-28 17:08:56 +0000
commit6090afd7447997bd6960c0ca60931671b02a6f44 (patch)
tree3c68049f29e8e57d45eaeb516a1e8993d09f15c1 /llvm/lib/Transforms
parentad154c837e4428842cfe5c0f9dbfcc42ba7a1454 (diff)
downloadbcm5719-llvm-6090afd7447997bd6960c0ca60931671b02a6f44.tar.gz
bcm5719-llvm-6090afd7447997bd6960c0ca60931671b02a6f44.zip
[PGO] Don't set the function hotness attribute when populating counters
Don't set the function hotness attribute on the fly. This changes the CFG branch probability of the caller function, which leads to inconsistent BB ordering. This patch moves the attribute setting to a separated loop after the counts in all functions are populated. Fixes PR27024 - PGO instrumentation profile data is not reflected in correct basic blocks. Differential Revision: http://reviews.llvm.org/D18491 llvm-svn: 264594
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp73
1 files changed, 52 insertions, 21 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
index 787f098869f..f32e94d19fe 100644
--- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
+++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
@@ -459,6 +459,32 @@ static uint64_t sumEdgeCount(const ArrayRef<PGOUseEdge *> Edges) {
}
class PGOUseFunc {
+public:
+ PGOUseFunc(Function &Func, Module *Modu, BranchProbabilityInfo *BPI = nullptr,
+ BlockFrequencyInfo *BFI = nullptr)
+ : F(Func), M(Modu), FuncInfo(Func, false, BPI, BFI),
+ FreqAttr(FFA_Normal) {}
+
+ // Read counts for the instrumented BB from profile.
+ bool readCounters(IndexedInstrProfReader *PGOReader);
+
+ // Populate the counts for all BBs.
+ void populateCounters();
+
+ // Set the branch weights based on the count values.
+ void setBranchWeights();
+
+ // Annotate the indirect call sites.
+ void annotateIndirectCallSites();
+
+ // The hotness of the function from the profile count.
+ enum FuncFreqAttr { FFA_Normal, FFA_Cold, FFA_Hot };
+
+ // Return the funtion hotness from the profile.
+ FuncFreqAttr getFuncFreqAttr() const {
+ return FreqAttr;
+ }
+
private:
Function &F;
Module *M;
@@ -477,6 +503,9 @@ private:
// ProfileRecord for this function.
InstrProfRecord ProfileRecord;
+ // Function hotness info derived from profile.
+ FuncFreqAttr FreqAttr;
+
// Find the Instrumented BB and set the value.
void setInstrumentedCounts(const std::vector<uint64_t> &CountFromProfile);
@@ -490,7 +519,7 @@ private:
// Set the hot/cold inline hints based on the count values.
// FIXME: This function should be removed once the functionality in
// the inliner is implemented.
- void applyFunctionAttributes(uint64_t EntryCount, uint64_t MaxCount) {
+ void markFunctionAttributes(uint64_t EntryCount, uint64_t MaxCount) {
if (ProgramMaxCount == 0)
return;
// Threshold of the hot functions.
@@ -498,27 +527,10 @@ private:
// Threshold of the cold functions.
const BranchProbability ColdFunctionThreshold(2, 10000);
if (EntryCount >= HotFunctionThreshold.scale(ProgramMaxCount))
- F.addFnAttr(llvm::Attribute::InlineHint);
+ FreqAttr = FFA_Hot;
else if (MaxCount <= ColdFunctionThreshold.scale(ProgramMaxCount))
- F.addFnAttr(llvm::Attribute::Cold);
+ FreqAttr = FFA_Cold;
}
-
-public:
- PGOUseFunc(Function &Func, Module *Modu, BranchProbabilityInfo *BPI = nullptr,
- BlockFrequencyInfo *BFI = nullptr)
- : F(Func), M(Modu), FuncInfo(Func, false, BPI, BFI) {}
-
- // Read counts for the instrumented BB from profile.
- bool readCounters(IndexedInstrProfReader *PGOReader);
-
- // Populate the counts for all BBs.
- void populateCounters();
-
- // Set the branch weights based on the count values.
- void setBranchWeights();
-
- // Annotate the indirect call sites.
- void annotateIndirectCallSites();
};
// Visit all the edges and assign the count value for the instrumented
@@ -681,7 +693,7 @@ void PGOUseFunc::populateCounters() {
if (Count > FuncMaxCount)
FuncMaxCount = Count;
}
- applyFunctionAttributes(FuncEntryCount, FuncMaxCount);
+ markFunctionAttributes(FuncEntryCount, FuncMaxCount);
DEBUG(FuncInfo.dumpInfo("after reading profile."));
}
@@ -827,6 +839,8 @@ bool PGOInstrumentationUse::runOnModule(Module &M) {
return false;
}
+ std::vector<Function *> HotFunctions;
+ std::vector<Function *> ColdFunctions;
for (auto &F : M) {
if (F.isDeclaration())
continue;
@@ -836,6 +850,23 @@ bool PGOInstrumentationUse::runOnModule(Module &M) {
&(getAnalysis<BlockFrequencyInfoWrapperPass>(F).getBFI());
PGOUseFunc Func(F, &M, BPI, BFI);
setPGOCountOnFunc(Func, PGOReader.get());
+ PGOUseFunc::FuncFreqAttr FreqAttr = Func.getFuncFreqAttr();
+ if (FreqAttr == PGOUseFunc::FFA_Cold)
+ ColdFunctions.push_back(&F);
+ else if (FreqAttr == PGOUseFunc::FFA_Hot)
+ HotFunctions.push_back(&F);
}
+
+ // Set function hotness attribute from the profile.
+ for (auto &F : HotFunctions) {
+ F->addFnAttr(llvm::Attribute::InlineHint);
+ DEBUG(dbgs() << "Set inline attribute to function: " << F->getName()
+ << "\n");
+ }
+ for (auto &F : ColdFunctions) {
+ F->addFnAttr(llvm::Attribute::Cold);
+ DEBUG(dbgs() << "Set cold attribute to function: " << F->getName() << "\n");
+ }
+
return true;
}
OpenPOWER on IntegriCloud