public:
PGOUseFunc(Function &Func, Module *Modu, BranchProbabilityInfo *BPI = nullptr,
BlockFrequencyInfo *BFI = nullptr)
- : F(Func), M(Modu), FuncInfo(Func, false, BPI, BFI) {}
+ : F(Func), M(Modu), FuncInfo(Func, false, BPI, BFI),
+ FreqAttr(FFA_Normal) {}
// Read counts for the instrumented BB from profile.
bool readCounters(IndexedInstrProfReader *PGOReader);
// Annotate the indirect call sites.
void annotateIndirectCallSites();
- // Return the profile record for this function;
- InstrProfRecord &getProfileRecord() { return ProfileRecord; }
+ // The hotness of the function from the profile count.
+ enum FuncFreqAttr { FFA_Normal, FFA_Cold, FFA_Hot };
- // The entry count of this function.
- uint64_t EntryCount;
+ // Return the function hotness from the profile.
+ FuncFreqAttr getFuncFreqAttr() const { return FreqAttr; }
- // The maximum count value of any BB in this function.
- uint64_t MaxBBCount;
+ // Return the profile record for this function;
+ InstrProfRecord &getProfileRecord() { return ProfileRecord; }
private:
Function &F;
return FuncInfo.getBBInfo(BB);
}
+ // The maximum count value in the profile. This is only used in PGO use
+ // compilation.
+ uint64_t ProgramMaxCount;
+
// 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);
// Return FuncName string;
const std::string getFuncName() const { return FuncInfo.FuncName; }
+
+ // 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 markFunctionAttributes(uint64_t EntryCount, uint64_t MaxCount) {
+ if (ProgramMaxCount == 0)
+ return;
+ // Threshold of the hot functions.
+ const BranchProbability HotFunctionThreshold(1, 100);
+ // Threshold of the cold functions.
+ const BranchProbability ColdFunctionThreshold(2, 10000);
+ if (EntryCount >= HotFunctionThreshold.scale(ProgramMaxCount))
+ FreqAttr = FFA_Hot;
+ else if (MaxCount <= ColdFunctionThreshold.scale(ProgramMaxCount))
+ FreqAttr = FFA_Cold;
+ }
};
// Visit all the edges and assign the count value for the instrumented
getBBInfo(nullptr).UnknownCountInEdge = 2;
setInstrumentedCounts(CountFromProfile);
+ ProgramMaxCount = PGOReader->getMaximumFunctionCount();
return true;
}
}
DEBUG(dbgs() << "Populate counts in " << NumPasses << " passes.\n");
-
- EntryCount = getBBInfo(&*F.begin()).CountValue;
- MaxBBCount = 0;
+ // Assert every BB has a valid counter.
+ uint64_t FuncEntryCount = getBBInfo(&*F.begin()).CountValue;
+ uint64_t FuncMaxCount = FuncEntryCount;
for (auto &BB : F) {
- // Assert every BB has a valid counter.
assert(getBBInfo(&BB).CountValid && "BB count is not valid");
- MaxBBCount = std::max(MaxBBCount, getBBInfo(&BB).CountValue);
+ uint64_t Count = getBBInfo(&BB).CountValue;
+ if (Count > FuncMaxCount)
+ FuncMaxCount = Count;
}
+ markFunctionAttributes(FuncEntryCount, FuncMaxCount);
DEBUG(FuncInfo.dumpInfo("after reading profile."));
}
std::vector<Function *> HotFunctions;
std::vector<Function *> ColdFunctions;
InstrProfSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs);
- uint64_t ProgramMaxCount = PGOReader->getMaximumFunctionCount();
- bool HasProgramMaxCount = ProgramMaxCount != 0;
for (auto &F : M) {
if (F.isDeclaration())
continue;
auto *BFI = LookupBFI(F);
PGOUseFunc Func(F, &M, BPI, BFI);
setPGOCountOnFunc(Func, PGOReader.get());
- F.setEntryCount(Func.EntryCount);
if (!Func.getProfileRecord().Counts.empty())
Builder.addRecord(Func.getProfileRecord());
-
- if (!HasProgramMaxCount)
- continue;
- // Set the hot/cold inline hints based on the count values.
- // FIXME: This should be removed once the functionality in
- // the inliner is implemented.
- const BranchProbability HotFunctionThreshold(1, 100);
- const BranchProbability ColdFunctionThreshold(2, 10000);
- if (Func.EntryCount >= HotFunctionThreshold.scale(ProgramMaxCount))
- HotFunctions.push_back(&F);
- else if (Func.MaxBBCount <= ColdFunctionThreshold.scale(ProgramMaxCount))
+ PGOUseFunc::FuncFreqAttr FreqAttr = Func.getFuncFreqAttr();
+ if (FreqAttr == PGOUseFunc::FFA_Cold)
ColdFunctions.push_back(&F);
+ else if (FreqAttr == PGOUseFunc::FFA_Hot)
+ HotFunctions.push_back(&F);
}
M.setProfileSummary(Builder.getSummary()->getMD(M.getContext()));
-
// Set function hotness attribute from the profile.
- // We have to apply these attributes at the end because their presence
- // can affect the BranchProbabilityInfo of any callers, resulting in an
- // inconsistent MST between prof-gen and prof-use.
for (auto &F : HotFunctions) {
F->addFnAttr(llvm::Attribute::InlineHint);
DEBUG(dbgs() << "Set inline attribute to function: " << F->getName()