diff options
Diffstat (limited to 'contrib/llvm/lib/Analysis/ProfileSummaryInfo.cpp')
-rw-r--r-- | contrib/llvm/lib/Analysis/ProfileSummaryInfo.cpp | 72 |
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(); |