LLVM 17.0.0git
ProfileSummaryInfo.h
Go to the documentation of this file.
1//===- llvm/Analysis/ProfileSummaryInfo.h - profile summary ---*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains a pass that provides access to profile summary
10// information.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ANALYSIS_PROFILESUMMARYINFO_H
15#define LLVM_ANALYSIS_PROFILESUMMARYINFO_H
16
17#include "llvm/ADT/DenseMap.h"
18#include "llvm/IR/PassManager.h"
20#include "llvm/Pass.h"
21#include <memory>
22#include <optional>
23
24namespace llvm {
25class BasicBlock;
26class BlockFrequencyInfo;
27class CallBase;
28class Function;
29
30/// Analysis providing profile information.
31///
32/// This is an immutable analysis pass that provides ability to query global
33/// (program-level) profile information. The main APIs are isHotCount and
34/// isColdCount that tells whether a given profile count is considered hot/cold
35/// based on the profile summary. This also provides convenience methods to
36/// check whether a function is hot or cold.
37
38// FIXME: Provide convenience methods to determine hotness/coldness of other IR
39// units. This would require making this depend on BFI.
41private:
42 const Module *M;
43 std::unique_ptr<ProfileSummary> Summary;
44 void computeThresholds();
45 // Count thresholds to answer isHotCount and isColdCount queries.
46 std::optional<uint64_t> HotCountThreshold, ColdCountThreshold;
47 // True if the working set size of the code is considered huge,
48 // because the number of profile counts required to reach the hot
49 // percentile is above a huge threshold.
50 std::optional<bool> HasHugeWorkingSetSize;
51 // True if the working set size of the code is considered large,
52 // because the number of profile counts required to reach the hot
53 // percentile is above a large threshold.
54 std::optional<bool> HasLargeWorkingSetSize;
55 // Compute the threshold for a given cutoff.
56 std::optional<uint64_t> computeThreshold(int PercentileCutoff) const;
57 // The map that caches the threshold values. The keys are the percentile
58 // cutoff values and the values are the corresponding threshold values.
59 mutable DenseMap<int, uint64_t> ThresholdCache;
60
61public:
62 ProfileSummaryInfo(const Module &M) : M(&M) { refresh(); }
64
65 /// If no summary is present, attempt to refresh.
66 void refresh();
67
68 /// Returns true if profile summary is available.
69 bool hasProfileSummary() const { return Summary != nullptr; }
70
71 /// Returns true if module \c M has sample profile.
72 bool hasSampleProfile() const {
73 return hasProfileSummary() &&
74 Summary->getKind() == ProfileSummary::PSK_Sample;
75 }
76
77 /// Returns true if module \c M has instrumentation profile.
79 return hasProfileSummary() &&
80 Summary->getKind() == ProfileSummary::PSK_Instr;
81 }
82
83 /// Returns true if module \c M has context sensitive instrumentation profile.
85 return hasProfileSummary() &&
86 Summary->getKind() == ProfileSummary::PSK_CSInstr;
87 }
88
89 /// Handle the invalidation of this information.
90 ///
91 /// When used as a result of \c ProfileSummaryAnalysis this method will be
92 /// called when the module this was computed for changes. Since profile
93 /// summary is immutable after it is annotated on the module, we return false
94 /// here.
97 return false;
98 }
99
100 /// Returns the profile count for \p CallInst.
101 std::optional<uint64_t> getProfileCount(const CallBase &CallInst,
103 bool AllowSynthetic = false) const;
104 /// Returns true if module \c M has partial-profile sample profile.
105 bool hasPartialSampleProfile() const;
106 /// Returns true if the working set size of the code is considered huge.
107 bool hasHugeWorkingSetSize() const;
108 /// Returns true if the working set size of the code is considered large.
109 bool hasLargeWorkingSetSize() const;
110 /// Returns true if \p F has hot function entry.
111 bool isFunctionEntryHot(const Function *F) const;
112 /// Returns true if \p F contains hot code.
114 BlockFrequencyInfo &BFI) const;
115 /// Returns true if \p F has cold function entry.
116 bool isFunctionEntryCold(const Function *F) const;
117 /// Returns true if \p F contains only cold code.
119 BlockFrequencyInfo &BFI) const;
120 /// Returns true if the hotness of \p F is unknown.
121 bool isFunctionHotnessUnknown(const Function &F) const;
122 /// Returns true if \p F contains hot code with regard to a given hot
123 /// percentile cutoff value.
125 const Function *F,
126 BlockFrequencyInfo &BFI) const;
127 /// Returns true if \p F contains cold code with regard to a given cold
128 /// percentile cutoff value.
130 const Function *F,
131 BlockFrequencyInfo &BFI) const;
132 /// Returns true if count \p C is considered hot.
133 bool isHotCount(uint64_t C) const;
134 /// Returns true if count \p C is considered cold.
135 bool isColdCount(uint64_t C) const;
136 /// Returns true if count \p C is considered hot with regard to a given
137 /// hot percentile cutoff value.
138 /// PercentileCutoff is encoded as a 6 digit decimal fixed point number, where
139 /// the first two digits are the whole part. E.g. 995000 for 99.5 percentile.
141 /// Returns true if count \p C is considered cold with regard to a given
142 /// cold percentile cutoff value.
143 /// PercentileCutoff is encoded as a 6 digit decimal fixed point number, where
144 /// the first two digits are the whole part. E.g. 995000 for 99.5 percentile.
146 /// Returns true if BasicBlock \p BB is considered hot.
147 bool isHotBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI) const;
148 /// Returns true if BasicBlock \p BB is considered cold.
149 bool isColdBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI) const;
150 /// Returns true if BasicBlock \p BB is considered hot with regard to a given
151 /// hot percentile cutoff value.
152 /// PercentileCutoff is encoded as a 6 digit decimal fixed point number, where
153 /// the first two digits are the whole part. E.g. 995000 for 99.5 percentile.
155 BlockFrequencyInfo *BFI) const;
156 /// Returns true if BasicBlock \p BB is considered cold with regard to a given
157 /// cold percentile cutoff value.
158 /// PercentileCutoff is encoded as a 6 digit decimal fixed point number, where
159 /// the first two digits are the whole part. E.g. 995000 for 99.5 percentile.
161 BlockFrequencyInfo *BFI) const;
162 /// Returns true if the call site \p CB is considered hot.
163 bool isHotCallSite(const CallBase &CB, BlockFrequencyInfo *BFI) const;
164 /// Returns true if call site \p CB is considered cold.
165 bool isColdCallSite(const CallBase &CB, BlockFrequencyInfo *BFI) const;
166 /// Returns HotCountThreshold if set. Recompute HotCountThreshold
167 /// if not set.
169 /// Returns ColdCountThreshold if set. Recompute HotCountThreshold
170 /// if not set.
172 /// Returns HotCountThreshold if set.
174 return HotCountThreshold.value_or(0);
175 }
176 /// Returns ColdCountThreshold if set.
178 return ColdCountThreshold.value_or(0);
179 }
180
181 private:
182 template <bool isHot>
183 bool isFunctionHotOrColdInCallGraphNthPercentile(
184 int PercentileCutoff, const Function *F, BlockFrequencyInfo &BFI) const;
185 template <bool isHot>
186 bool isHotOrColdCountNthPercentile(int PercentileCutoff, uint64_t C) const;
187 template <bool isHot>
188 bool isHotOrColdBlockNthPercentile(int PercentileCutoff,
189 const BasicBlock *BB,
190 BlockFrequencyInfo *BFI) const;
191};
192
193/// An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
195 std::unique_ptr<ProfileSummaryInfo> PSI;
196
197public:
198 static char ID;
200
201 ProfileSummaryInfo &getPSI() { return *PSI; }
202 const ProfileSummaryInfo &getPSI() const { return *PSI; }
203
204 bool doInitialization(Module &M) override;
205 bool doFinalization(Module &M) override;
206 void getAnalysisUsage(AnalysisUsage &AU) const override {
207 AU.setPreservesAll();
208 }
209};
210
211/// An analysis pass based on the new PM to deliver ProfileSummaryInfo.
213 : public AnalysisInfoMixin<ProfileSummaryAnalysis> {
214public:
216
218
219private:
221 static AnalysisKey Key;
222};
223
224/// Printer pass that uses \c ProfileSummaryAnalysis.
226 : public PassInfoMixin<ProfileSummaryPrinterPass> {
227 raw_ostream &OS;
228
229public:
232};
233
234} // end namespace llvm
235
236#endif
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
This file defines the DenseMap class.
#define F(x, y, z)
Definition: MD5.cpp:55
static cl::opt< unsigned > PercentileCutoff("mfs-psi-cutoff", cl::desc("Percentile profile summary cutoff used to " "determine cold blocks. Unused if set to zero."), cl::init(999950), cl::Hidden)
This header defines various interfaces for pass management in LLVM.
raw_pwrite_stream & OS
API to communicate dependencies between analyses during invalidation.
Definition: PassManager.h:661
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:620
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
LLVM Basic Block Representation.
Definition: BasicBlock.h:56
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1190
This class represents a function call, abstracting a target machine's calling convention.
ImmutablePass class - This class is used to provide information that does not need to be run.
Definition: Pass.h:282
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
Result run(Module &M, ModuleAnalysisManager &)
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
bool doFinalization(Module &M) override
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool doInitialization(Module &M) override
doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...
const ProfileSummaryInfo & getPSI() const
Analysis providing profile information.
bool isFunctionEntryHot(const Function *F) const
Returns true if F has hot function entry.
bool hasCSInstrumentationProfile() const
Returns true if module M has context sensitive instrumentation profile.
bool isHotBlockNthPercentile(int PercentileCutoff, const BasicBlock *BB, BlockFrequencyInfo *BFI) const
Returns true if BasicBlock BB is considered hot with regard to a given hot percentile cutoff value.
uint64_t getOrCompColdCountThreshold() const
Returns ColdCountThreshold if set.
bool hasProfileSummary() const
Returns true if profile summary is available.
bool isHotBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI) const
Returns true if BasicBlock BB is considered hot.
bool isFunctionHotnessUnknown(const Function &F) const
Returns true if the hotness of F is unknown.
bool hasInstrumentationProfile() const
Returns true if module M has instrumentation profile.
void refresh()
If no summary is present, attempt to refresh.
bool isColdBlockNthPercentile(int PercentileCutoff, const BasicBlock *BB, BlockFrequencyInfo *BFI) const
Returns true if BasicBlock BB is considered cold with regard to a given cold percentile cutoff value.
std::optional< uint64_t > getProfileCount(const CallBase &CallInst, BlockFrequencyInfo *BFI, bool AllowSynthetic=false) const
Returns the profile count for CallInst.
bool hasSampleProfile() const
Returns true if module M has sample profile.
bool isColdCount(uint64_t C) const
Returns true if count C is considered cold.
bool isColdCountNthPercentile(int PercentileCutoff, uint64_t C) const
Returns true if count C is considered cold with regard to a given cold percentile cutoff value.
bool isHotCountNthPercentile(int PercentileCutoff, uint64_t C) const
Returns true if count C is considered hot with regard to a given hot percentile cutoff value.
uint64_t getColdCountThreshold() const
Returns ColdCountThreshold if set.
bool isFunctionColdInCallGraphNthPercentile(int PercentileCutoff, const Function *F, BlockFrequencyInfo &BFI) const
Returns true if F contains cold code with regard to a given cold percentile cutoff value.
bool hasPartialSampleProfile() const
Returns true if module M has partial-profile sample profile.
bool hasLargeWorkingSetSize() const
Returns true if the working set size of the code is considered large.
bool isColdCallSite(const CallBase &CB, BlockFrequencyInfo *BFI) const
Returns true if call site CB is considered cold.
ProfileSummaryInfo(ProfileSummaryInfo &&Arg)=default
bool isFunctionHotInCallGraphNthPercentile(int PercentileCutoff, const Function *F, BlockFrequencyInfo &BFI) const
Returns true if F contains hot code with regard to a given hot percentile cutoff value.
bool isFunctionHotInCallGraph(const Function *F, BlockFrequencyInfo &BFI) const
Returns true if F contains hot code.
bool isHotCallSite(const CallBase &CB, BlockFrequencyInfo *BFI) const
Returns true if the call site CB is considered hot.
bool isColdBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI) const
Returns true if BasicBlock BB is considered cold.
ProfileSummaryInfo(const Module &M)
uint64_t getHotCountThreshold() const
Returns HotCountThreshold if set.
bool isFunctionColdInCallGraph(const Function *F, BlockFrequencyInfo &BFI) const
Returns true if F contains only cold code.
bool isHotCount(uint64_t C) const
Returns true if count C is considered hot.
bool hasHugeWorkingSetSize() const
Returns true if the working set size of the code is considered huge.
uint64_t getOrCompHotCountThreshold() const
Returns HotCountThreshold if set.
bool invalidate(Module &, const PreservedAnalyses &, ModuleAnalysisManager::Invalidator &)
Handle the invalidation of this information.
bool isFunctionEntryCold(const Function *F) const
Returns true if F has cold function entry.
Printer pass that uses ProfileSummaryAnalysis.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ BasicBlock
Various leaf nodes.
Definition: ISDOpcodes.h:71
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
A CRTP mix-in that provides informational APIs needed for analysis passes.
Definition: PassManager.h:394
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: PassManager.h:69
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:371