summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Analysis/ProfileSummaryInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Analysis/ProfileSummaryInfo.cpp')
-rw-r--r--contrib/llvm/lib/Analysis/ProfileSummaryInfo.cpp72
1 files changed, 45 insertions, 27 deletions
diff --git a/contrib/llvm/lib/Analysis/ProfileSummaryInfo.cpp b/contrib/llvm/lib/Analysis/ProfileSummaryInfo.cpp
index 9cf99af..16d3614 100644
--- a/contrib/llvm/lib/Analysis/ProfileSummaryInfo.cpp
+++ b/contrib/llvm/lib/Analysis/ProfileSummaryInfo.cpp
@@ -12,7 +12,9 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ProfileSummary.h"
@@ -63,10 +65,10 @@ void ProfileSummaryInfo::computeSummary() {
Summary.reset(ProfileSummary::getFromMD(SummaryMD));
}
-// Returns true if the function is a hot function. If it returns false, it
-// either means it is not hot or it is unknown whether F is hot or not (for
-// example, no profile data is available).
-bool ProfileSummaryInfo::isHotFunction(const Function *F) {
+/// Returns true if the function's entry is hot. If it returns false, it
+/// either means it is not hot or it is unknown whether it is hot or not (for
+/// example, no profile data is available).
+bool ProfileSummaryInfo::isFunctionEntryHot(const Function *F) {
computeSummary();
if (!F || !Summary)
return false;
@@ -74,15 +76,13 @@ bool ProfileSummaryInfo::isHotFunction(const Function *F) {
// FIXME: The heuristic used below for determining hotness is based on
// preliminary SPEC tuning for inliner. This will eventually be a
// convenience method that calls isHotCount.
- return (FunctionCount &&
- FunctionCount.getValue() >=
- (uint64_t)(0.3 * (double)Summary->getMaxFunctionCount()));
+ return FunctionCount && isHotCount(FunctionCount.getValue());
}
-// Returns true if the function is a cold function. If it returns false, it
-// either means it is not cold or it is unknown whether F is cold or not (for
-// example, no profile data is available).
-bool ProfileSummaryInfo::isColdFunction(const Function *F) {
+/// Returns true if the function's entry is a cold. If it returns false, it
+/// either means it is not cold or it is unknown whether it is cold or not (for
+/// example, no profile data is available).
+bool ProfileSummaryInfo::isFunctionEntryCold(const Function *F) {
computeSummary();
if (!F)
return false;
@@ -95,12 +95,10 @@ bool ProfileSummaryInfo::isColdFunction(const Function *F) {
// FIXME: The heuristic used below for determining coldness is based on
// preliminary SPEC tuning for inliner. This will eventually be a
// convenience method that calls isHotCount.
- return (FunctionCount &&
- FunctionCount.getValue() <=
- (uint64_t)(0.01 * (double)Summary->getMaxFunctionCount()));
+ return FunctionCount && isColdCount(FunctionCount.getValue());
}
-// Compute the hot and cold thresholds.
+/// Compute the hot and cold thresholds.
void ProfileSummaryInfo::computeThresholds() {
if (!Summary)
computeSummary();
@@ -125,10 +123,22 @@ bool ProfileSummaryInfo::isColdCount(uint64_t C) {
return ColdCountThreshold && C <= ColdCountThreshold.getValue();
}
-ProfileSummaryInfo *ProfileSummaryInfoWrapperPass::getPSI(Module &M) {
- if (!PSI)
- PSI.reset(new ProfileSummaryInfo(M));
- return PSI.get();
+bool ProfileSummaryInfo::isHotBB(const BasicBlock *B, BlockFrequencyInfo *BFI) {
+ auto Count = BFI->getBlockProfileCount(B);
+ if (Count && isHotCount(*Count))
+ return true;
+ // Use extractProfTotalWeight to get BB count.
+ // For Sample PGO, BFI may not provide accurate BB count due to errors
+ // magnified during sample count propagation. This serves as a backup plan
+ // to ensure all hot BB will not be missed.
+ // The query currently has false positives as branch instruction cloning does
+ // not update/scale branch weights. Unlike false negatives, this will not cause
+ // performance problem.
+ uint64_t TotalCount;
+ if (B->getTerminator()->extractProfTotalWeight(TotalCount) &&
+ isHotCount(TotalCount))
+ return true;
+ return false;
}
INITIALIZE_PASS(ProfileSummaryInfoWrapperPass, "profile-summary-info",
@@ -139,25 +149,33 @@ ProfileSummaryInfoWrapperPass::ProfileSummaryInfoWrapperPass()
initializeProfileSummaryInfoWrapperPassPass(*PassRegistry::getPassRegistry());
}
-char ProfileSummaryAnalysis::PassID;
+bool ProfileSummaryInfoWrapperPass::doInitialization(Module &M) {
+ PSI.reset(new ProfileSummaryInfo(M));
+ return false;
+}
+
+bool ProfileSummaryInfoWrapperPass::doFinalization(Module &M) {
+ PSI.reset();
+ return false;
+}
+
+AnalysisKey ProfileSummaryAnalysis::Key;
ProfileSummaryInfo ProfileSummaryAnalysis::run(Module &M,
ModuleAnalysisManager &) {
return ProfileSummaryInfo(M);
}
-// FIXME: This only tests isHotFunction and isColdFunction and not the
-// isHotCount and isColdCount calls.
PreservedAnalyses ProfileSummaryPrinterPass::run(Module &M,
- AnalysisManager<Module> &AM) {
+ ModuleAnalysisManager &AM) {
ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M);
OS << "Functions in " << M.getName() << " with hot/cold annotations: \n";
for (auto &F : M) {
OS << F.getName();
- if (PSI.isHotFunction(&F))
- OS << " :hot ";
- else if (PSI.isColdFunction(&F))
- OS << " :cold ";
+ if (PSI.isFunctionEntryHot(&F))
+ OS << " :hot entry ";
+ else if (PSI.isFunctionEntryCold(&F))
+ OS << " :cold entry ";
OS << "\n";
}
return PreservedAnalyses::all();
OpenPOWER on IntegriCloud