xref: /freebsd/contrib/llvm-project/llvm/lib/Analysis/ProfileSummaryInfo.cpp (revision 8bcb0991864975618c09697b1aca10683346d9f0)
10b57cec5SDimitry Andric //===- ProfileSummaryInfo.cpp - Global profile summary information --------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file contains a pass that provides access to the global profile summary
100b57cec5SDimitry Andric // information.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "llvm/Analysis/ProfileSummaryInfo.h"
150b57cec5SDimitry Andric #include "llvm/Analysis/BlockFrequencyInfo.h"
160b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
170b57cec5SDimitry Andric #include "llvm/IR/CallSite.h"
180b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
190b57cec5SDimitry Andric #include "llvm/IR/Module.h"
200b57cec5SDimitry Andric #include "llvm/IR/ProfileSummary.h"
210b57cec5SDimitry Andric using namespace llvm;
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric // The following two parameters determine the threshold for a count to be
240b57cec5SDimitry Andric // considered hot/cold. These two parameters are percentile values (multiplied
250b57cec5SDimitry Andric // by 10000). If the counts are sorted in descending order, the minimum count to
260b57cec5SDimitry Andric // reach ProfileSummaryCutoffHot gives the threshold to determine a hot count.
270b57cec5SDimitry Andric // Similarly, the minimum count to reach ProfileSummaryCutoffCold gives the
280b57cec5SDimitry Andric // threshold for determining cold count (everything <= this threshold is
290b57cec5SDimitry Andric // considered cold).
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric static cl::opt<int> ProfileSummaryCutoffHot(
320b57cec5SDimitry Andric     "profile-summary-cutoff-hot", cl::Hidden, cl::init(990000), cl::ZeroOrMore,
330b57cec5SDimitry Andric     cl::desc("A count is hot if it exceeds the minimum count to"
340b57cec5SDimitry Andric              " reach this percentile of total counts."));
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric static cl::opt<int> ProfileSummaryCutoffCold(
370b57cec5SDimitry Andric     "profile-summary-cutoff-cold", cl::Hidden, cl::init(999999), cl::ZeroOrMore,
380b57cec5SDimitry Andric     cl::desc("A count is cold if it is below the minimum count"
390b57cec5SDimitry Andric              " to reach this percentile of total counts."));
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric static cl::opt<unsigned> ProfileSummaryHugeWorkingSetSizeThreshold(
420b57cec5SDimitry Andric     "profile-summary-huge-working-set-size-threshold", cl::Hidden,
430b57cec5SDimitry Andric     cl::init(15000), cl::ZeroOrMore,
440b57cec5SDimitry Andric     cl::desc("The code working set size is considered huge if the number of"
450b57cec5SDimitry Andric              " blocks required to reach the -profile-summary-cutoff-hot"
460b57cec5SDimitry Andric              " percentile exceeds this count."));
470b57cec5SDimitry Andric 
48*8bcb0991SDimitry Andric static cl::opt<unsigned> ProfileSummaryLargeWorkingSetSizeThreshold(
49*8bcb0991SDimitry Andric     "profile-summary-large-working-set-size-threshold", cl::Hidden,
50*8bcb0991SDimitry Andric     cl::init(12500), cl::ZeroOrMore,
51*8bcb0991SDimitry Andric     cl::desc("The code working set size is considered large if the number of"
52*8bcb0991SDimitry Andric              " blocks required to reach the -profile-summary-cutoff-hot"
53*8bcb0991SDimitry Andric              " percentile exceeds this count."));
54*8bcb0991SDimitry Andric 
550b57cec5SDimitry Andric // The next two options override the counts derived from summary computation and
560b57cec5SDimitry Andric // are useful for debugging purposes.
570b57cec5SDimitry Andric static cl::opt<int> ProfileSummaryHotCount(
580b57cec5SDimitry Andric     "profile-summary-hot-count", cl::ReallyHidden, cl::ZeroOrMore,
590b57cec5SDimitry Andric     cl::desc("A fixed hot count that overrides the count derived from"
600b57cec5SDimitry Andric              " profile-summary-cutoff-hot"));
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric static cl::opt<int> ProfileSummaryColdCount(
630b57cec5SDimitry Andric     "profile-summary-cold-count", cl::ReallyHidden, cl::ZeroOrMore,
640b57cec5SDimitry Andric     cl::desc("A fixed cold count that overrides the count derived from"
650b57cec5SDimitry Andric              " profile-summary-cutoff-cold"));
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric // Find the summary entry for a desired percentile of counts.
680b57cec5SDimitry Andric static const ProfileSummaryEntry &getEntryForPercentile(SummaryEntryVector &DS,
690b57cec5SDimitry Andric                                                         uint64_t Percentile) {
700b57cec5SDimitry Andric   auto It = partition_point(DS, [=](const ProfileSummaryEntry &Entry) {
710b57cec5SDimitry Andric     return Entry.Cutoff < Percentile;
720b57cec5SDimitry Andric   });
730b57cec5SDimitry Andric   // The required percentile has to be <= one of the percentiles in the
740b57cec5SDimitry Andric   // detailed summary.
750b57cec5SDimitry Andric   if (It == DS.end())
760b57cec5SDimitry Andric     report_fatal_error("Desired percentile exceeds the maximum cutoff");
770b57cec5SDimitry Andric   return *It;
780b57cec5SDimitry Andric }
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric // The profile summary metadata may be attached either by the frontend or by
810b57cec5SDimitry Andric // any backend passes (IR level instrumentation, for example). This method
820b57cec5SDimitry Andric // checks if the Summary is null and if so checks if the summary metadata is now
830b57cec5SDimitry Andric // available in the module and parses it to get the Summary object. Returns true
840b57cec5SDimitry Andric // if a valid Summary is available.
850b57cec5SDimitry Andric bool ProfileSummaryInfo::computeSummary() {
860b57cec5SDimitry Andric   if (Summary)
870b57cec5SDimitry Andric     return true;
880b57cec5SDimitry Andric   // First try to get context sensitive ProfileSummary.
890b57cec5SDimitry Andric   auto *SummaryMD = M.getProfileSummary(/* IsCS */ true);
900b57cec5SDimitry Andric   if (SummaryMD) {
910b57cec5SDimitry Andric     Summary.reset(ProfileSummary::getFromMD(SummaryMD));
920b57cec5SDimitry Andric     return true;
930b57cec5SDimitry Andric   }
940b57cec5SDimitry Andric   // This will actually return PSK_Instr or PSK_Sample summary.
950b57cec5SDimitry Andric   SummaryMD = M.getProfileSummary(/* IsCS */ false);
960b57cec5SDimitry Andric   if (!SummaryMD)
970b57cec5SDimitry Andric     return false;
980b57cec5SDimitry Andric   Summary.reset(ProfileSummary::getFromMD(SummaryMD));
990b57cec5SDimitry Andric   return true;
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric Optional<uint64_t>
1030b57cec5SDimitry Andric ProfileSummaryInfo::getProfileCount(const Instruction *Inst,
1040b57cec5SDimitry Andric                                     BlockFrequencyInfo *BFI,
1050b57cec5SDimitry Andric                                     bool AllowSynthetic) {
1060b57cec5SDimitry Andric   if (!Inst)
1070b57cec5SDimitry Andric     return None;
1080b57cec5SDimitry Andric   assert((isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) &&
1090b57cec5SDimitry Andric          "We can only get profile count for call/invoke instruction.");
1100b57cec5SDimitry Andric   if (hasSampleProfile()) {
1110b57cec5SDimitry Andric     // In sample PGO mode, check if there is a profile metadata on the
1120b57cec5SDimitry Andric     // instruction. If it is present, determine hotness solely based on that,
1130b57cec5SDimitry Andric     // since the sampled entry count may not be accurate. If there is no
1140b57cec5SDimitry Andric     // annotated on the instruction, return None.
1150b57cec5SDimitry Andric     uint64_t TotalCount;
1160b57cec5SDimitry Andric     if (Inst->extractProfTotalWeight(TotalCount))
1170b57cec5SDimitry Andric       return TotalCount;
1180b57cec5SDimitry Andric     return None;
1190b57cec5SDimitry Andric   }
1200b57cec5SDimitry Andric   if (BFI)
1210b57cec5SDimitry Andric     return BFI->getBlockProfileCount(Inst->getParent(), AllowSynthetic);
1220b57cec5SDimitry Andric   return None;
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric /// Returns true if the function's entry is hot. If it returns false, it
1260b57cec5SDimitry Andric /// either means it is not hot or it is unknown whether it is hot or not (for
1270b57cec5SDimitry Andric /// example, no profile data is available).
1280b57cec5SDimitry Andric bool ProfileSummaryInfo::isFunctionEntryHot(const Function *F) {
1290b57cec5SDimitry Andric   if (!F || !computeSummary())
1300b57cec5SDimitry Andric     return false;
1310b57cec5SDimitry Andric   auto FunctionCount = F->getEntryCount();
1320b57cec5SDimitry Andric   // FIXME: The heuristic used below for determining hotness is based on
1330b57cec5SDimitry Andric   // preliminary SPEC tuning for inliner. This will eventually be a
1340b57cec5SDimitry Andric   // convenience method that calls isHotCount.
1350b57cec5SDimitry Andric   return FunctionCount && isHotCount(FunctionCount.getCount());
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric /// Returns true if the function contains hot code. This can include a hot
1390b57cec5SDimitry Andric /// function entry count, hot basic block, or (in the case of Sample PGO)
1400b57cec5SDimitry Andric /// hot total call edge count.
1410b57cec5SDimitry Andric /// If it returns false, it either means it is not hot or it is unknown
1420b57cec5SDimitry Andric /// (for example, no profile data is available).
1430b57cec5SDimitry Andric bool ProfileSummaryInfo::isFunctionHotInCallGraph(const Function *F,
1440b57cec5SDimitry Andric                                                   BlockFrequencyInfo &BFI) {
1450b57cec5SDimitry Andric   if (!F || !computeSummary())
1460b57cec5SDimitry Andric     return false;
1470b57cec5SDimitry Andric   if (auto FunctionCount = F->getEntryCount())
1480b57cec5SDimitry Andric     if (isHotCount(FunctionCount.getCount()))
1490b57cec5SDimitry Andric       return true;
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric   if (hasSampleProfile()) {
1520b57cec5SDimitry Andric     uint64_t TotalCallCount = 0;
1530b57cec5SDimitry Andric     for (const auto &BB : *F)
1540b57cec5SDimitry Andric       for (const auto &I : BB)
1550b57cec5SDimitry Andric         if (isa<CallInst>(I) || isa<InvokeInst>(I))
1560b57cec5SDimitry Andric           if (auto CallCount = getProfileCount(&I, nullptr))
1570b57cec5SDimitry Andric             TotalCallCount += CallCount.getValue();
1580b57cec5SDimitry Andric     if (isHotCount(TotalCallCount))
1590b57cec5SDimitry Andric       return true;
1600b57cec5SDimitry Andric   }
1610b57cec5SDimitry Andric   for (const auto &BB : *F)
1620b57cec5SDimitry Andric     if (isHotBlock(&BB, &BFI))
1630b57cec5SDimitry Andric       return true;
1640b57cec5SDimitry Andric   return false;
1650b57cec5SDimitry Andric }
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric /// Returns true if the function only contains cold code. This means that
1680b57cec5SDimitry Andric /// the function entry and blocks are all cold, and (in the case of Sample PGO)
1690b57cec5SDimitry Andric /// the total call edge count is cold.
1700b57cec5SDimitry Andric /// If it returns false, it either means it is not cold or it is unknown
1710b57cec5SDimitry Andric /// (for example, no profile data is available).
1720b57cec5SDimitry Andric bool ProfileSummaryInfo::isFunctionColdInCallGraph(const Function *F,
1730b57cec5SDimitry Andric                                                    BlockFrequencyInfo &BFI) {
1740b57cec5SDimitry Andric   if (!F || !computeSummary())
1750b57cec5SDimitry Andric     return false;
1760b57cec5SDimitry Andric   if (auto FunctionCount = F->getEntryCount())
1770b57cec5SDimitry Andric     if (!isColdCount(FunctionCount.getCount()))
1780b57cec5SDimitry Andric       return false;
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric   if (hasSampleProfile()) {
1810b57cec5SDimitry Andric     uint64_t TotalCallCount = 0;
1820b57cec5SDimitry Andric     for (const auto &BB : *F)
1830b57cec5SDimitry Andric       for (const auto &I : BB)
1840b57cec5SDimitry Andric         if (isa<CallInst>(I) || isa<InvokeInst>(I))
1850b57cec5SDimitry Andric           if (auto CallCount = getProfileCount(&I, nullptr))
1860b57cec5SDimitry Andric             TotalCallCount += CallCount.getValue();
1870b57cec5SDimitry Andric     if (!isColdCount(TotalCallCount))
1880b57cec5SDimitry Andric       return false;
1890b57cec5SDimitry Andric   }
1900b57cec5SDimitry Andric   for (const auto &BB : *F)
1910b57cec5SDimitry Andric     if (!isColdBlock(&BB, &BFI))
1920b57cec5SDimitry Andric       return false;
1930b57cec5SDimitry Andric   return true;
1940b57cec5SDimitry Andric }
1950b57cec5SDimitry Andric 
196*8bcb0991SDimitry Andric // Like isFunctionHotInCallGraph but for a given cutoff.
197*8bcb0991SDimitry Andric bool ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile(
198*8bcb0991SDimitry Andric     int PercentileCutoff, const Function *F, BlockFrequencyInfo &BFI) {
199*8bcb0991SDimitry Andric   if (!F || !computeSummary())
200*8bcb0991SDimitry Andric     return false;
201*8bcb0991SDimitry Andric   if (auto FunctionCount = F->getEntryCount())
202*8bcb0991SDimitry Andric     if (isHotCountNthPercentile(PercentileCutoff, FunctionCount.getCount()))
203*8bcb0991SDimitry Andric       return true;
204*8bcb0991SDimitry Andric 
205*8bcb0991SDimitry Andric   if (hasSampleProfile()) {
206*8bcb0991SDimitry Andric     uint64_t TotalCallCount = 0;
207*8bcb0991SDimitry Andric     for (const auto &BB : *F)
208*8bcb0991SDimitry Andric       for (const auto &I : BB)
209*8bcb0991SDimitry Andric         if (isa<CallInst>(I) || isa<InvokeInst>(I))
210*8bcb0991SDimitry Andric           if (auto CallCount = getProfileCount(&I, nullptr))
211*8bcb0991SDimitry Andric             TotalCallCount += CallCount.getValue();
212*8bcb0991SDimitry Andric     if (isHotCountNthPercentile(PercentileCutoff, TotalCallCount))
213*8bcb0991SDimitry Andric       return true;
214*8bcb0991SDimitry Andric   }
215*8bcb0991SDimitry Andric   for (const auto &BB : *F)
216*8bcb0991SDimitry Andric     if (isHotBlockNthPercentile(PercentileCutoff, &BB, &BFI))
217*8bcb0991SDimitry Andric       return true;
218*8bcb0991SDimitry Andric   return false;
219*8bcb0991SDimitry Andric }
220*8bcb0991SDimitry Andric 
2210b57cec5SDimitry Andric /// Returns true if the function's entry is a cold. If it returns false, it
2220b57cec5SDimitry Andric /// either means it is not cold or it is unknown whether it is cold or not (for
2230b57cec5SDimitry Andric /// example, no profile data is available).
2240b57cec5SDimitry Andric bool ProfileSummaryInfo::isFunctionEntryCold(const Function *F) {
2250b57cec5SDimitry Andric   if (!F)
2260b57cec5SDimitry Andric     return false;
2270b57cec5SDimitry Andric   if (F->hasFnAttribute(Attribute::Cold))
2280b57cec5SDimitry Andric     return true;
2290b57cec5SDimitry Andric   if (!computeSummary())
2300b57cec5SDimitry Andric     return false;
2310b57cec5SDimitry Andric   auto FunctionCount = F->getEntryCount();
2320b57cec5SDimitry Andric   // FIXME: The heuristic used below for determining coldness is based on
2330b57cec5SDimitry Andric   // preliminary SPEC tuning for inliner. This will eventually be a
2340b57cec5SDimitry Andric   // convenience method that calls isHotCount.
2350b57cec5SDimitry Andric   return FunctionCount && isColdCount(FunctionCount.getCount());
2360b57cec5SDimitry Andric }
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric /// Compute the hot and cold thresholds.
2390b57cec5SDimitry Andric void ProfileSummaryInfo::computeThresholds() {
2400b57cec5SDimitry Andric   if (!computeSummary())
2410b57cec5SDimitry Andric     return;
2420b57cec5SDimitry Andric   auto &DetailedSummary = Summary->getDetailedSummary();
2430b57cec5SDimitry Andric   auto &HotEntry =
2440b57cec5SDimitry Andric       getEntryForPercentile(DetailedSummary, ProfileSummaryCutoffHot);
2450b57cec5SDimitry Andric   HotCountThreshold = HotEntry.MinCount;
2460b57cec5SDimitry Andric   if (ProfileSummaryHotCount.getNumOccurrences() > 0)
2470b57cec5SDimitry Andric     HotCountThreshold = ProfileSummaryHotCount;
2480b57cec5SDimitry Andric   auto &ColdEntry =
2490b57cec5SDimitry Andric       getEntryForPercentile(DetailedSummary, ProfileSummaryCutoffCold);
2500b57cec5SDimitry Andric   ColdCountThreshold = ColdEntry.MinCount;
2510b57cec5SDimitry Andric   if (ProfileSummaryColdCount.getNumOccurrences() > 0)
2520b57cec5SDimitry Andric     ColdCountThreshold = ProfileSummaryColdCount;
2530b57cec5SDimitry Andric   assert(ColdCountThreshold <= HotCountThreshold &&
2540b57cec5SDimitry Andric          "Cold count threshold cannot exceed hot count threshold!");
2550b57cec5SDimitry Andric   HasHugeWorkingSetSize =
2560b57cec5SDimitry Andric       HotEntry.NumCounts > ProfileSummaryHugeWorkingSetSizeThreshold;
257*8bcb0991SDimitry Andric   HasLargeWorkingSetSize =
258*8bcb0991SDimitry Andric       HotEntry.NumCounts > ProfileSummaryLargeWorkingSetSizeThreshold;
259*8bcb0991SDimitry Andric }
260*8bcb0991SDimitry Andric 
261*8bcb0991SDimitry Andric Optional<uint64_t> ProfileSummaryInfo::computeThreshold(int PercentileCutoff) {
262*8bcb0991SDimitry Andric   if (!computeSummary())
263*8bcb0991SDimitry Andric     return None;
264*8bcb0991SDimitry Andric   auto iter = ThresholdCache.find(PercentileCutoff);
265*8bcb0991SDimitry Andric   if (iter != ThresholdCache.end()) {
266*8bcb0991SDimitry Andric     return iter->second;
267*8bcb0991SDimitry Andric   }
268*8bcb0991SDimitry Andric   auto &DetailedSummary = Summary->getDetailedSummary();
269*8bcb0991SDimitry Andric   auto &Entry =
270*8bcb0991SDimitry Andric       getEntryForPercentile(DetailedSummary, PercentileCutoff);
271*8bcb0991SDimitry Andric   uint64_t CountThreshold = Entry.MinCount;
272*8bcb0991SDimitry Andric   ThresholdCache[PercentileCutoff] = CountThreshold;
273*8bcb0991SDimitry Andric   return CountThreshold;
2740b57cec5SDimitry Andric }
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric bool ProfileSummaryInfo::hasHugeWorkingSetSize() {
2770b57cec5SDimitry Andric   if (!HasHugeWorkingSetSize)
2780b57cec5SDimitry Andric     computeThresholds();
2790b57cec5SDimitry Andric   return HasHugeWorkingSetSize && HasHugeWorkingSetSize.getValue();
2800b57cec5SDimitry Andric }
2810b57cec5SDimitry Andric 
282*8bcb0991SDimitry Andric bool ProfileSummaryInfo::hasLargeWorkingSetSize() {
283*8bcb0991SDimitry Andric   if (!HasLargeWorkingSetSize)
284*8bcb0991SDimitry Andric     computeThresholds();
285*8bcb0991SDimitry Andric   return HasLargeWorkingSetSize && HasLargeWorkingSetSize.getValue();
286*8bcb0991SDimitry Andric }
287*8bcb0991SDimitry Andric 
2880b57cec5SDimitry Andric bool ProfileSummaryInfo::isHotCount(uint64_t C) {
2890b57cec5SDimitry Andric   if (!HotCountThreshold)
2900b57cec5SDimitry Andric     computeThresholds();
2910b57cec5SDimitry Andric   return HotCountThreshold && C >= HotCountThreshold.getValue();
2920b57cec5SDimitry Andric }
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric bool ProfileSummaryInfo::isColdCount(uint64_t C) {
2950b57cec5SDimitry Andric   if (!ColdCountThreshold)
2960b57cec5SDimitry Andric     computeThresholds();
2970b57cec5SDimitry Andric   return ColdCountThreshold && C <= ColdCountThreshold.getValue();
2980b57cec5SDimitry Andric }
2990b57cec5SDimitry Andric 
300*8bcb0991SDimitry Andric bool ProfileSummaryInfo::isHotCountNthPercentile(int PercentileCutoff, uint64_t C) {
301*8bcb0991SDimitry Andric   auto CountThreshold = computeThreshold(PercentileCutoff);
302*8bcb0991SDimitry Andric   return CountThreshold && C >= CountThreshold.getValue();
303*8bcb0991SDimitry Andric }
304*8bcb0991SDimitry Andric 
3050b57cec5SDimitry Andric uint64_t ProfileSummaryInfo::getOrCompHotCountThreshold() {
3060b57cec5SDimitry Andric   if (!HotCountThreshold)
3070b57cec5SDimitry Andric     computeThresholds();
3080b57cec5SDimitry Andric   return HotCountThreshold ? HotCountThreshold.getValue() : UINT64_MAX;
3090b57cec5SDimitry Andric }
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric uint64_t ProfileSummaryInfo::getOrCompColdCountThreshold() {
3120b57cec5SDimitry Andric   if (!ColdCountThreshold)
3130b57cec5SDimitry Andric     computeThresholds();
3140b57cec5SDimitry Andric   return ColdCountThreshold ? ColdCountThreshold.getValue() : 0;
3150b57cec5SDimitry Andric }
3160b57cec5SDimitry Andric 
3170b57cec5SDimitry Andric bool ProfileSummaryInfo::isHotBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI) {
3180b57cec5SDimitry Andric   auto Count = BFI->getBlockProfileCount(BB);
3190b57cec5SDimitry Andric   return Count && isHotCount(*Count);
3200b57cec5SDimitry Andric }
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric bool ProfileSummaryInfo::isColdBlock(const BasicBlock *BB,
3230b57cec5SDimitry Andric                                   BlockFrequencyInfo *BFI) {
3240b57cec5SDimitry Andric   auto Count = BFI->getBlockProfileCount(BB);
3250b57cec5SDimitry Andric   return Count && isColdCount(*Count);
3260b57cec5SDimitry Andric }
3270b57cec5SDimitry Andric 
328*8bcb0991SDimitry Andric bool ProfileSummaryInfo::isHotBlockNthPercentile(int PercentileCutoff,
329*8bcb0991SDimitry Andric                                                  const BasicBlock *BB,
330*8bcb0991SDimitry Andric                                                  BlockFrequencyInfo *BFI) {
331*8bcb0991SDimitry Andric   auto Count = BFI->getBlockProfileCount(BB);
332*8bcb0991SDimitry Andric   return Count && isHotCountNthPercentile(PercentileCutoff, *Count);
333*8bcb0991SDimitry Andric }
334*8bcb0991SDimitry Andric 
3350b57cec5SDimitry Andric bool ProfileSummaryInfo::isHotCallSite(const CallSite &CS,
3360b57cec5SDimitry Andric                                        BlockFrequencyInfo *BFI) {
3370b57cec5SDimitry Andric   auto C = getProfileCount(CS.getInstruction(), BFI);
3380b57cec5SDimitry Andric   return C && isHotCount(*C);
3390b57cec5SDimitry Andric }
3400b57cec5SDimitry Andric 
3410b57cec5SDimitry Andric bool ProfileSummaryInfo::isColdCallSite(const CallSite &CS,
3420b57cec5SDimitry Andric                                         BlockFrequencyInfo *BFI) {
3430b57cec5SDimitry Andric   auto C = getProfileCount(CS.getInstruction(), BFI);
3440b57cec5SDimitry Andric   if (C)
3450b57cec5SDimitry Andric     return isColdCount(*C);
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric   // In SamplePGO, if the caller has been sampled, and there is no profile
3480b57cec5SDimitry Andric   // annotated on the callsite, we consider the callsite as cold.
3490b57cec5SDimitry Andric   return hasSampleProfile() && CS.getCaller()->hasProfileData();
3500b57cec5SDimitry Andric }
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric INITIALIZE_PASS(ProfileSummaryInfoWrapperPass, "profile-summary-info",
3530b57cec5SDimitry Andric                 "Profile summary info", false, true)
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric ProfileSummaryInfoWrapperPass::ProfileSummaryInfoWrapperPass()
3560b57cec5SDimitry Andric     : ImmutablePass(ID) {
3570b57cec5SDimitry Andric   initializeProfileSummaryInfoWrapperPassPass(*PassRegistry::getPassRegistry());
3580b57cec5SDimitry Andric }
3590b57cec5SDimitry Andric 
3600b57cec5SDimitry Andric bool ProfileSummaryInfoWrapperPass::doInitialization(Module &M) {
3610b57cec5SDimitry Andric   PSI.reset(new ProfileSummaryInfo(M));
3620b57cec5SDimitry Andric   return false;
3630b57cec5SDimitry Andric }
3640b57cec5SDimitry Andric 
3650b57cec5SDimitry Andric bool ProfileSummaryInfoWrapperPass::doFinalization(Module &M) {
3660b57cec5SDimitry Andric   PSI.reset();
3670b57cec5SDimitry Andric   return false;
3680b57cec5SDimitry Andric }
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric AnalysisKey ProfileSummaryAnalysis::Key;
3710b57cec5SDimitry Andric ProfileSummaryInfo ProfileSummaryAnalysis::run(Module &M,
3720b57cec5SDimitry Andric                                                ModuleAnalysisManager &) {
3730b57cec5SDimitry Andric   return ProfileSummaryInfo(M);
3740b57cec5SDimitry Andric }
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric PreservedAnalyses ProfileSummaryPrinterPass::run(Module &M,
3770b57cec5SDimitry Andric                                                  ModuleAnalysisManager &AM) {
3780b57cec5SDimitry Andric   ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M);
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric   OS << "Functions in " << M.getName() << " with hot/cold annotations: \n";
3810b57cec5SDimitry Andric   for (auto &F : M) {
3820b57cec5SDimitry Andric     OS << F.getName();
3830b57cec5SDimitry Andric     if (PSI.isFunctionEntryHot(&F))
3840b57cec5SDimitry Andric       OS << " :hot entry ";
3850b57cec5SDimitry Andric     else if (PSI.isFunctionEntryCold(&F))
3860b57cec5SDimitry Andric       OS << " :cold entry ";
3870b57cec5SDimitry Andric     OS << "\n";
3880b57cec5SDimitry Andric   }
3890b57cec5SDimitry Andric   return PreservedAnalyses::all();
3900b57cec5SDimitry Andric }
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric char ProfileSummaryInfoWrapperPass::ID = 0;
393