1 //===- llvm/Analysis/ProfileSummaryInfo.h - profile summary ---*- C++ -*-===// 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 profile summary 11 // information. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_ANALYSIS_PROFILE_SUMMARY_INFO_H 16 #define LLVM_ANALYSIS_PROFILE_SUMMARY_INFO_H 17 18 #include "llvm/ADT/ArrayRef.h" 19 #include "llvm/ADT/DenseMap.h" 20 #include "llvm/ADT/SmallSet.h" 21 #include "llvm/IR/Function.h" 22 #include "llvm/IR/Instructions.h" 23 #include "llvm/IR/PassManager.h" 24 #include "llvm/IR/ProfileSummary.h" 25 #include "llvm/IR/ValueHandle.h" 26 #include "llvm/Pass.h" 27 #include <memory> 28 29 namespace llvm { 30 class BasicBlock; 31 class BlockFrequencyInfo; 32 class CallSite; 33 class ProfileSummary; 34 /// Analysis providing profile information. 35 /// 36 /// This is an immutable analysis pass that provides ability to query global 37 /// (program-level) profile information. The main APIs are isHotCount and 38 /// isColdCount that tells whether a given profile count is considered hot/cold 39 /// based on the profile summary. This also provides convenience methods to 40 /// check whether a function is hot or cold. 41 42 // FIXME: Provide convenience methods to determine hotness/coldness of other IR 43 // units. This would require making this depend on BFI. 44 class ProfileSummaryInfo { 45 private: 46 Module &M; 47 std::unique_ptr<ProfileSummary> Summary; 48 bool computeSummary(); 49 void computeThresholds(); 50 // Count thresholds to answer isHotCount and isColdCount queries. 51 Optional<uint64_t> HotCountThreshold, ColdCountThreshold; 52 // True if the working set size of the code is considered huge, 53 // because the number of profile counts required to reach the hot 54 // percentile is above a huge threshold. 55 Optional<bool> HasHugeWorkingSetSize; 56 57 public: ProfileSummaryInfo(Module & M)58 ProfileSummaryInfo(Module &M) : M(M) {} ProfileSummaryInfo(ProfileSummaryInfo && Arg)59 ProfileSummaryInfo(ProfileSummaryInfo &&Arg) 60 : M(Arg.M), Summary(std::move(Arg.Summary)) {} 61 62 /// Returns true if profile summary is available. hasProfileSummary()63 bool hasProfileSummary() { return computeSummary(); } 64 65 /// Returns true if module \c M has sample profile. hasSampleProfile()66 bool hasSampleProfile() { 67 return hasProfileSummary() && 68 Summary->getKind() == ProfileSummary::PSK_Sample; 69 } 70 71 /// Returns true if module \c M has instrumentation profile. hasInstrumentationProfile()72 bool hasInstrumentationProfile() { 73 return hasProfileSummary() && 74 Summary->getKind() == ProfileSummary::PSK_Instr; 75 } 76 77 /// Handle the invalidation of this information. 78 /// 79 /// When used as a result of \c ProfileSummaryAnalysis this method will be 80 /// called when the module this was computed for changes. Since profile 81 /// summary is immutable after it is annotated on the module, we return false 82 /// here. invalidate(Module &,const PreservedAnalyses &,ModuleAnalysisManager::Invalidator &)83 bool invalidate(Module &, const PreservedAnalyses &, 84 ModuleAnalysisManager::Invalidator &) { 85 return false; 86 } 87 88 /// Returns the profile count for \p CallInst. 89 Optional<uint64_t> getProfileCount(const Instruction *CallInst, 90 BlockFrequencyInfo *BFI); 91 /// Returns true if the working set size of the code is considered huge. 92 bool hasHugeWorkingSetSize(); 93 /// Returns true if \p F has hot function entry. 94 bool isFunctionEntryHot(const Function *F); 95 /// Returns true if \p F contains hot code. 96 bool isFunctionHotInCallGraph(const Function *F, BlockFrequencyInfo &BFI); 97 /// Returns true if \p F has cold function entry. 98 bool isFunctionEntryCold(const Function *F); 99 /// Returns true if \p F contains only cold code. 100 bool isFunctionColdInCallGraph(const Function *F, BlockFrequencyInfo &BFI); 101 /// Returns true if \p F is a hot function. 102 bool isHotCount(uint64_t C); 103 /// Returns true if count \p C is considered cold. 104 bool isColdCount(uint64_t C); 105 /// Returns true if BasicBlock \p B is considered hot. 106 bool isHotBB(const BasicBlock *B, BlockFrequencyInfo *BFI); 107 /// Returns true if BasicBlock \p B is considered cold. 108 bool isColdBB(const BasicBlock *B, BlockFrequencyInfo *BFI); 109 /// Returns true if CallSite \p CS is considered hot. 110 bool isHotCallSite(const CallSite &CS, BlockFrequencyInfo *BFI); 111 /// Returns true if Callsite \p CS is considered cold. 112 bool isColdCallSite(const CallSite &CS, BlockFrequencyInfo *BFI); 113 /// Returns HotCountThreshold if set. Recompute HotCountThreshold 114 /// if not set. 115 uint64_t getOrCompHotCountThreshold(); 116 /// Returns ColdCountThreshold if set. Recompute HotCountThreshold 117 /// if not set. 118 uint64_t getOrCompColdCountThreshold(); 119 /// Returns HotCountThreshold if set. getHotCountThreshold()120 uint64_t getHotCountThreshold() { 121 return HotCountThreshold ? HotCountThreshold.getValue() : 0; 122 } 123 /// Returns ColdCountThreshold if set. getColdCountThreshold()124 uint64_t getColdCountThreshold() { 125 return ColdCountThreshold ? ColdCountThreshold.getValue() : 0; 126 } 127 }; 128 129 /// An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo. 130 class ProfileSummaryInfoWrapperPass : public ImmutablePass { 131 std::unique_ptr<ProfileSummaryInfo> PSI; 132 133 public: 134 static char ID; 135 ProfileSummaryInfoWrapperPass(); 136 getPSI()137 ProfileSummaryInfo *getPSI() { 138 return &*PSI; 139 } 140 141 bool doInitialization(Module &M) override; 142 bool doFinalization(Module &M) override; getAnalysisUsage(AnalysisUsage & AU)143 void getAnalysisUsage(AnalysisUsage &AU) const override { 144 AU.setPreservesAll(); 145 } 146 }; 147 148 /// An analysis pass based on the new PM to deliver ProfileSummaryInfo. 149 class ProfileSummaryAnalysis 150 : public AnalysisInfoMixin<ProfileSummaryAnalysis> { 151 public: 152 typedef ProfileSummaryInfo Result; 153 154 Result run(Module &M, ModuleAnalysisManager &); 155 156 private: 157 friend AnalysisInfoMixin<ProfileSummaryAnalysis>; 158 static AnalysisKey Key; 159 }; 160 161 /// Printer pass that uses \c ProfileSummaryAnalysis. 162 class ProfileSummaryPrinterPass 163 : public PassInfoMixin<ProfileSummaryPrinterPass> { 164 raw_ostream &OS; 165 166 public: ProfileSummaryPrinterPass(raw_ostream & OS)167 explicit ProfileSummaryPrinterPass(raw_ostream &OS) : OS(OS) {} 168 PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); 169 }; 170 171 } // end namespace llvm 172 173 #endif 174