Line data Source code
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 31 : 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 36285 : ProfileSummaryInfo(Module &M) : M(M) {}
59 : ProfileSummaryInfo(ProfileSummaryInfo &&Arg)
60 182 : : M(Arg.M), Summary(std::move(Arg.Summary)) {}
61 :
62 : /// Returns true if profile summary is available.
63 821 : bool hasProfileSummary() { return computeSummary(); }
64 :
65 : /// Returns true if module \c M has sample profile.
66 : bool hasSampleProfile() {
67 588 : return hasProfileSummary() &&
68 268 : Summary->getKind() == ProfileSummary::PSK_Sample;
69 : }
70 :
71 : /// Returns true if module \c M has instrumentation profile.
72 : bool hasInstrumentationProfile() {
73 7 : return hasProfileSummary() &&
74 6 : 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 0 : bool invalidate(Module &, const PreservedAnalyses &,
84 : ModuleAnalysisManager::Invalidator &) {
85 0 : 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.
120 : uint64_t getHotCountThreshold() {
121 : return HotCountThreshold ? HotCountThreshold.getValue() : 0;
122 : }
123 : /// Returns ColdCountThreshold if set.
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 :
137 : ProfileSummaryInfo *getPSI() {
138 : return &*PSI;
139 : }
140 :
141 : bool doInitialization(Module &M) override;
142 : bool doFinalization(Module &M) override;
143 36257 : void getAnalysisUsage(AnalysisUsage &AU) const override {
144 : AU.setPreservesAll();
145 36257 : }
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:
167 1 : explicit ProfileSummaryPrinterPass(raw_ostream &OS) : OS(OS) {}
168 : PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
169 : };
170 :
171 : } // end namespace llvm
172 :
173 : #endif
|