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 /// \brief 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: 58 ProfileSummaryInfo(Module &M) : M(M) {} 59 ProfileSummaryInfo(ProfileSummaryInfo &&Arg) 60 : M(Arg.M), Summary(std::move(Arg.Summary)) {} 61 62 /// \brief Returns true if profile summary is available. 63 bool hasProfileSummary() { return computeSummary(); } 64 65 /// \brief Returns true if module \c M has sample profile. 66 bool hasSampleProfile() { 67 return hasProfileSummary() && 68 Summary->getKind() == ProfileSummary::PSK_Sample; 69 } 70 71 /// \brief Returns true if module \c M has instrumentation profile. 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. 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 /// \brief Returns true if \p F has hot function entry. 94 bool isFunctionEntryHot(const Function *F); 95 /// Returns true if \p F has hot function entry or hot call edge. 96 bool isFunctionHotInCallGraph(const Function *F); 97 /// \brief Returns true if \p F has cold function entry. 98 bool isFunctionEntryCold(const Function *F); 99 /// Returns true if \p F has cold function entry or cold call edge. 100 bool isFunctionColdInCallGraph(const Function *F); 101 /// \brief Returns true if \p F is a hot function. 102 bool isHotCount(uint64_t C); 103 /// \brief Returns true if count \p C is considered cold. 104 bool isColdCount(uint64_t C); 105 /// \brief Returns true if BasicBlock \p B is considered hot. 106 bool isHotBB(const BasicBlock *B, BlockFrequencyInfo *BFI); 107 /// \brief Returns true if BasicBlock \p B is considered cold. 108 bool isColdBB(const BasicBlock *B, BlockFrequencyInfo *BFI); 109 /// \brief Returns true if CallSite \p CS is considered hot. 110 bool isHotCallSite(const CallSite &CS, BlockFrequencyInfo *BFI); 111 /// \brief Returns true if Callsite \p CS is considered cold. 112 bool isColdCallSite(const CallSite &CS, BlockFrequencyInfo *BFI); 113 }; 114 115 /// An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo. 116 class ProfileSummaryInfoWrapperPass : public ImmutablePass { 117 std::unique_ptr<ProfileSummaryInfo> PSI; 118 119 public: 120 static char ID; 121 ProfileSummaryInfoWrapperPass(); 122 123 ProfileSummaryInfo *getPSI() { 124 return &*PSI; 125 } 126 127 bool doInitialization(Module &M) override; 128 bool doFinalization(Module &M) override; 129 void getAnalysisUsage(AnalysisUsage &AU) const override { 130 AU.setPreservesAll(); 131 } 132 }; 133 134 /// An analysis pass based on the new PM to deliver ProfileSummaryInfo. 135 class ProfileSummaryAnalysis 136 : public AnalysisInfoMixin<ProfileSummaryAnalysis> { 137 public: 138 typedef ProfileSummaryInfo Result; 139 140 Result run(Module &M, ModuleAnalysisManager &); 141 142 private: 143 friend AnalysisInfoMixin<ProfileSummaryAnalysis>; 144 static AnalysisKey Key; 145 }; 146 147 /// \brief Printer pass that uses \c ProfileSummaryAnalysis. 148 class ProfileSummaryPrinterPass 149 : public PassInfoMixin<ProfileSummaryPrinterPass> { 150 raw_ostream &OS; 151 152 public: 153 explicit ProfileSummaryPrinterPass(raw_ostream &OS) : OS(OS) {} 154 PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); 155 }; 156 157 } // end namespace llvm 158 159 #endif 160