• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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