1 //===- ProfileSummaryInfo.cpp - Global profile summary information --------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains a pass that provides access to the global profile summary 11 // information. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/Analysis/ProfileSummaryInfo.h" 16 #include "llvm/Analysis/BlockFrequencyInfo.h" 17 #include "llvm/IR/BasicBlock.h" 18 #include "llvm/IR/CallSite.h" 19 #include "llvm/IR/Metadata.h" 20 #include "llvm/IR/Module.h" 21 #include "llvm/IR/ProfileSummary.h" 22 using namespace llvm; 23 24 // The following two parameters determine the threshold for a count to be 25 // considered hot/cold. These two parameters are percentile values (multiplied 26 // by 10000). If the counts are sorted in descending order, the minimum count to 27 // reach ProfileSummaryCutoffHot gives the threshold to determine a hot count. 28 // Similarly, the minimum count to reach ProfileSummaryCutoffCold gives the 29 // threshold for determining cold count (everything <= this threshold is 30 // considered cold). 31 32 static cl::opt<int> ProfileSummaryCutoffHot( 33 "profile-summary-cutoff-hot", cl::Hidden, cl::init(990000), cl::ZeroOrMore, 34 cl::desc("A count is hot if it exceeds the minimum count to" 35 " reach this percentile of total counts.")); 36 37 static cl::opt<int> ProfileSummaryCutoffCold( 38 "profile-summary-cutoff-cold", cl::Hidden, cl::init(999999), cl::ZeroOrMore, 39 cl::desc("A count is cold if it is below the minimum count" 40 " to reach this percentile of total counts.")); 41 42 static cl::opt<bool> ProfileSampleAccurate( 43 "profile-sample-accurate", cl::Hidden, cl::init(false), 44 cl::desc("If the sample profile is accurate, we will mark all un-sampled " 45 "callsite as cold. Otherwise, treat un-sampled callsites as if " 46 "we have no profile.")); 47 static cl::opt<unsigned> ProfileSummaryHugeWorkingSetSizeThreshold( 48 "profile-summary-huge-working-set-size-threshold", cl::Hidden, 49 cl::init(15000), cl::ZeroOrMore, 50 cl::desc("The code working set size is considered huge if the number of" 51 " blocks required to reach the -profile-summary-cutoff-hot" 52 " percentile exceeds this count.")); 53 54 // The next two options override the counts derived from summary computation and 55 // are useful for debugging purposes. 56 static cl::opt<int> ProfileSummaryHotCount( 57 "profile-summary-hot-count", cl::ReallyHidden, cl::ZeroOrMore, 58 cl::desc("A fixed hot count that overrides the count derived from" 59 " profile-summary-cutoff-hot")); 60 61 static cl::opt<int> ProfileSummaryColdCount( 62 "profile-summary-cold-count", cl::ReallyHidden, cl::ZeroOrMore, 63 cl::desc("A fixed cold count that overrides the count derived from" 64 " profile-summary-cutoff-cold")); 65 66 // Find the summary entry for a desired percentile of counts. 67 static const ProfileSummaryEntry &getEntryForPercentile(SummaryEntryVector &DS, 68 uint64_t Percentile) { 69 auto Compare = [](const ProfileSummaryEntry &Entry, uint64_t Percentile) { 70 return Entry.Cutoff < Percentile; 71 }; 72 auto It = std::lower_bound(DS.begin(), DS.end(), Percentile, Compare); 73 // The required percentile has to be <= one of the percentiles in the 74 // detailed summary. 75 if (It == DS.end()) 76 report_fatal_error("Desired percentile exceeds the maximum cutoff"); 77 return *It; 78 } 79 80 // The profile summary metadata may be attached either by the frontend or by 81 // any backend passes (IR level instrumentation, for example). This method 82 // checks if the Summary is null and if so checks if the summary metadata is now 83 // available in the module and parses it to get the Summary object. Returns true 84 // if a valid Summary is available. 85 bool ProfileSummaryInfo::computeSummary() { 86 if (Summary) 87 return true; 88 auto *SummaryMD = M.getProfileSummary(); 89 if (!SummaryMD) 90 return false; 91 Summary.reset(ProfileSummary::getFromMD(SummaryMD)); 92 return true; 93 } 94 95 Optional<uint64_t> 96 ProfileSummaryInfo::getProfileCount(const Instruction *Inst, 97 BlockFrequencyInfo *BFI) { 98 if (!Inst) 99 return None; 100 assert((isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) && 101 "We can only get profile count for call/invoke instruction."); 102 if (hasSampleProfile()) { 103 // In sample PGO mode, check if there is a profile metadata on the 104 // instruction. If it is present, determine hotness solely based on that, 105 // since the sampled entry count may not be accurate. If there is no 106 // annotated on the instruction, return None. 107 uint64_t TotalCount; 108 if (Inst->extractProfTotalWeight(TotalCount)) 109 return TotalCount; 110 return None; 111 } 112 if (BFI) 113 return BFI->getBlockProfileCount(Inst->getParent()); 114 return None; 115 } 116 117 /// Returns true if the function's entry is hot. If it returns false, it 118 /// either means it is not hot or it is unknown whether it is hot or not (for 119 /// example, no profile data is available). 120 bool ProfileSummaryInfo::isFunctionEntryHot(const Function *F) { 121 if (!F || !computeSummary()) 122 return false; 123 auto FunctionCount = F->getEntryCount(); 124 // FIXME: The heuristic used below for determining hotness is based on 125 // preliminary SPEC tuning for inliner. This will eventually be a 126 // convenience method that calls isHotCount. 127 return FunctionCount && isHotCount(FunctionCount.getCount()); 128 } 129 130 /// Returns true if the function contains hot code. This can include a hot 131 /// function entry count, hot basic block, or (in the case of Sample PGO) 132 /// hot total call edge count. 133 /// If it returns false, it either means it is not hot or it is unknown 134 /// (for example, no profile data is available). 135 bool ProfileSummaryInfo::isFunctionHotInCallGraph(const Function *F, 136 BlockFrequencyInfo &BFI) { 137 if (!F || !computeSummary()) 138 return false; 139 if (auto FunctionCount = F->getEntryCount()) 140 if (isHotCount(FunctionCount.getCount())) 141 return true; 142 143 if (hasSampleProfile()) { 144 uint64_t TotalCallCount = 0; 145 for (const auto &BB : *F) 146 for (const auto &I : BB) 147 if (isa<CallInst>(I) || isa<InvokeInst>(I)) 148 if (auto CallCount = getProfileCount(&I, nullptr)) 149 TotalCallCount += CallCount.getValue(); 150 if (isHotCount(TotalCallCount)) 151 return true; 152 } 153 for (const auto &BB : *F) 154 if (isHotBB(&BB, &BFI)) 155 return true; 156 return false; 157 } 158 159 /// Returns true if the function only contains cold code. This means that 160 /// the function entry and blocks are all cold, and (in the case of Sample PGO) 161 /// the total call edge count is cold. 162 /// If it returns false, it either means it is not cold or it is unknown 163 /// (for example, no profile data is available). 164 bool ProfileSummaryInfo::isFunctionColdInCallGraph(const Function *F, 165 BlockFrequencyInfo &BFI) { 166 if (!F || !computeSummary()) 167 return false; 168 if (auto FunctionCount = F->getEntryCount()) 169 if (!isColdCount(FunctionCount.getCount())) 170 return false; 171 172 if (hasSampleProfile()) { 173 uint64_t TotalCallCount = 0; 174 for (const auto &BB : *F) 175 for (const auto &I : BB) 176 if (isa<CallInst>(I) || isa<InvokeInst>(I)) 177 if (auto CallCount = getProfileCount(&I, nullptr)) 178 TotalCallCount += CallCount.getValue(); 179 if (!isColdCount(TotalCallCount)) 180 return false; 181 } 182 for (const auto &BB : *F) 183 if (!isColdBB(&BB, &BFI)) 184 return false; 185 return true; 186 } 187 188 /// Returns true if the function's entry is a cold. If it returns false, it 189 /// either means it is not cold or it is unknown whether it is cold or not (for 190 /// example, no profile data is available). 191 bool ProfileSummaryInfo::isFunctionEntryCold(const Function *F) { 192 if (!F) 193 return false; 194 if (F->hasFnAttribute(Attribute::Cold)) 195 return true; 196 if (!computeSummary()) 197 return false; 198 auto FunctionCount = F->getEntryCount(); 199 // FIXME: The heuristic used below for determining coldness is based on 200 // preliminary SPEC tuning for inliner. This will eventually be a 201 // convenience method that calls isHotCount. 202 return FunctionCount && isColdCount(FunctionCount.getCount()); 203 } 204 205 /// Compute the hot and cold thresholds. 206 void ProfileSummaryInfo::computeThresholds() { 207 if (!computeSummary()) 208 return; 209 auto &DetailedSummary = Summary->getDetailedSummary(); 210 auto &HotEntry = 211 getEntryForPercentile(DetailedSummary, ProfileSummaryCutoffHot); 212 HotCountThreshold = HotEntry.MinCount; 213 if (ProfileSummaryHotCount.getNumOccurrences() > 0) 214 HotCountThreshold = ProfileSummaryHotCount; 215 auto &ColdEntry = 216 getEntryForPercentile(DetailedSummary, ProfileSummaryCutoffCold); 217 ColdCountThreshold = ColdEntry.MinCount; 218 if (ProfileSummaryColdCount.getNumOccurrences() > 0) 219 ColdCountThreshold = ProfileSummaryColdCount; 220 assert(ColdCountThreshold <= HotCountThreshold && 221 "Cold count threshold cannot exceed hot count threshold!"); 222 HasHugeWorkingSetSize = 223 HotEntry.NumCounts > ProfileSummaryHugeWorkingSetSizeThreshold; 224 } 225 226 bool ProfileSummaryInfo::hasHugeWorkingSetSize() { 227 if (!HasHugeWorkingSetSize) 228 computeThresholds(); 229 return HasHugeWorkingSetSize && HasHugeWorkingSetSize.getValue(); 230 } 231 232 bool ProfileSummaryInfo::isHotCount(uint64_t C) { 233 if (!HotCountThreshold) 234 computeThresholds(); 235 return HotCountThreshold && C >= HotCountThreshold.getValue(); 236 } 237 238 bool ProfileSummaryInfo::isColdCount(uint64_t C) { 239 if (!ColdCountThreshold) 240 computeThresholds(); 241 return ColdCountThreshold && C <= ColdCountThreshold.getValue(); 242 } 243 244 uint64_t ProfileSummaryInfo::getOrCompHotCountThreshold() { 245 if (!HotCountThreshold) 246 computeThresholds(); 247 return HotCountThreshold ? HotCountThreshold.getValue() : UINT64_MAX; 248 } 249 250 uint64_t ProfileSummaryInfo::getOrCompColdCountThreshold() { 251 if (!ColdCountThreshold) 252 computeThresholds(); 253 return ColdCountThreshold ? ColdCountThreshold.getValue() : 0; 254 } 255 256 bool ProfileSummaryInfo::isHotBB(const BasicBlock *B, BlockFrequencyInfo *BFI) { 257 auto Count = BFI->getBlockProfileCount(B); 258 return Count && isHotCount(*Count); 259 } 260 261 bool ProfileSummaryInfo::isColdBB(const BasicBlock *B, 262 BlockFrequencyInfo *BFI) { 263 auto Count = BFI->getBlockProfileCount(B); 264 return Count && isColdCount(*Count); 265 } 266 267 bool ProfileSummaryInfo::isHotCallSite(const CallSite &CS, 268 BlockFrequencyInfo *BFI) { 269 auto C = getProfileCount(CS.getInstruction(), BFI); 270 return C && isHotCount(*C); 271 } 272 273 bool ProfileSummaryInfo::isColdCallSite(const CallSite &CS, 274 BlockFrequencyInfo *BFI) { 275 auto C = getProfileCount(CS.getInstruction(), BFI); 276 if (C) 277 return isColdCount(*C); 278 279 // In SamplePGO, if the caller has been sampled, and there is no profile 280 // annotated on the callsite, we consider the callsite as cold. 281 // If there is no profile for the caller, and we know the profile is 282 // accurate, we consider the callsite as cold. 283 return (hasSampleProfile() && 284 (CS.getCaller()->hasProfileData() || ProfileSampleAccurate || 285 CS.getCaller()->hasFnAttribute("profile-sample-accurate"))); 286 } 287 288 INITIALIZE_PASS(ProfileSummaryInfoWrapperPass, "profile-summary-info", 289 "Profile summary info", false, true) 290 291 ProfileSummaryInfoWrapperPass::ProfileSummaryInfoWrapperPass() 292 : ImmutablePass(ID) { 293 initializeProfileSummaryInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 294 } 295 296 bool ProfileSummaryInfoWrapperPass::doInitialization(Module &M) { 297 PSI.reset(new ProfileSummaryInfo(M)); 298 return false; 299 } 300 301 bool ProfileSummaryInfoWrapperPass::doFinalization(Module &M) { 302 PSI.reset(); 303 return false; 304 } 305 306 AnalysisKey ProfileSummaryAnalysis::Key; 307 ProfileSummaryInfo ProfileSummaryAnalysis::run(Module &M, 308 ModuleAnalysisManager &) { 309 return ProfileSummaryInfo(M); 310 } 311 312 PreservedAnalyses ProfileSummaryPrinterPass::run(Module &M, 313 ModuleAnalysisManager &AM) { 314 ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M); 315 316 OS << "Functions in " << M.getName() << " with hot/cold annotations: \n"; 317 for (auto &F : M) { 318 OS << F.getName(); 319 if (PSI.isFunctionEntryHot(&F)) 320 OS << " :hot entry "; 321 else if (PSI.isFunctionEntryCold(&F)) 322 OS << " :cold entry "; 323 OS << "\n"; 324 } 325 return PreservedAnalyses::all(); 326 } 327 328 char ProfileSummaryInfoWrapperPass::ID = 0; 329