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 53 public: 54 ProfileSummaryInfo(Module &M) : M(M) {} 55 ProfileSummaryInfo(ProfileSummaryInfo &&Arg) 56 : M(Arg.M), Summary(std::move(Arg.Summary)) {} 57 58 /// \brief Returns true if profile summary is available. 59 bool hasProfileSummary() { return computeSummary(); } 60 61 /// \brief Returns true if module \c M has sample profile. 62 bool hasSampleProfile() { 63 return hasProfileSummary() && 64 Summary->getKind() == ProfileSummary::PSK_Sample; 65 } 66 67 /// \brief Returns true if module \c M has instrumentation profile. 68 bool hasInstrumentationProfile() { 69 return hasProfileSummary() && 70 Summary->getKind() == ProfileSummary::PSK_Instr; 71 } 72 73 /// Handle the invalidation of this information. 74 /// 75 /// When used as a result of \c ProfileSummaryAnalysis this method will be 76 /// called when the module this was computed for changes. Since profile 77 /// summary is immutable after it is annotated on the module, we return false 78 /// here. 79 bool invalidate(Module &, const PreservedAnalyses &, 80 ModuleAnalysisManager::Invalidator &) { 81 return false; 82 } 83 84 /// Returns the profile count for \p CallInst. 85 Optional<uint64_t> getProfileCount(const Instruction *CallInst, 86 BlockFrequencyInfo *BFI); 87 /// \brief Returns true if \p F has hot function entry. 88 bool isFunctionEntryHot(const Function *F); 89 /// Returns true if \p F has hot function entry or hot call edge. 90 bool isFunctionHotInCallGraph(const Function *F); 91 /// \brief Returns true if \p F has cold function entry. 92 bool isFunctionEntryCold(const Function *F); 93 /// Returns true if \p F has cold function entry or cold call edge. 94 bool isFunctionColdInCallGraph(const Function *F); 95 /// \brief Returns true if \p F is a hot function. 96 bool isHotCount(uint64_t C); 97 /// \brief Returns true if count \p C is considered cold. 98 bool isColdCount(uint64_t C); 99 /// \brief Returns true if BasicBlock \p B is considered hot. 100 bool isHotBB(const BasicBlock *B, BlockFrequencyInfo *BFI); 101 /// \brief Returns true if BasicBlock \p B is considered cold. 102 bool isColdBB(const BasicBlock *B, BlockFrequencyInfo *BFI); 103 /// \brief Returns true if CallSite \p CS is considered hot. 104 bool isHotCallSite(const CallSite &CS, BlockFrequencyInfo *BFI); 105 /// \brief Returns true if Callsite \p CS is considered cold. 106 bool isColdCallSite(const CallSite &CS, BlockFrequencyInfo *BFI); 107 }; 108 109 /// An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo. 110 class ProfileSummaryInfoWrapperPass : public ImmutablePass { 111 std::unique_ptr<ProfileSummaryInfo> PSI; 112 113 public: 114 static char ID; 115 ProfileSummaryInfoWrapperPass(); 116 117 ProfileSummaryInfo *getPSI() { 118 return &*PSI; 119 } 120 121 bool doInitialization(Module &M) override; 122 bool doFinalization(Module &M) override; 123 void getAnalysisUsage(AnalysisUsage &AU) const override { 124 AU.setPreservesAll(); 125 } 126 }; 127 128 /// An analysis pass based on the new PM to deliver ProfileSummaryInfo. 129 class ProfileSummaryAnalysis 130 : public AnalysisInfoMixin<ProfileSummaryAnalysis> { 131 public: 132 typedef ProfileSummaryInfo Result; 133 134 Result run(Module &M, ModuleAnalysisManager &); 135 136 private: 137 friend AnalysisInfoMixin<ProfileSummaryAnalysis>; 138 static AnalysisKey Key; 139 }; 140 141 /// \brief Printer pass that uses \c ProfileSummaryAnalysis. 142 class ProfileSummaryPrinterPass 143 : public PassInfoMixin<ProfileSummaryPrinterPass> { 144 raw_ostream &OS; 145 146 public: 147 explicit ProfileSummaryPrinterPass(raw_ostream &OS) : OS(OS) {} 148 PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); 149 }; 150 151 } // end namespace llvm 152 153 #endif 154