LLVM 24.0.0git
BlockFrequencyInfo.cpp
Go to the documentation of this file.
1//===- BlockFrequencyInfo.cpp - Block Frequency Analysis ------------------===//
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// Loops should be simplified before this analysis.
10//
11//===----------------------------------------------------------------------===//
12
14#include "AnalysisOptions.h"
15#include "llvm/ADT/APInt.h"
16#include "llvm/ADT/iterator.h"
20#include "llvm/IR/CFG.h"
21#include "llvm/IR/Function.h"
22#include "llvm/IR/PassManager.h"
24#include "llvm/Pass.h"
27#include <cassert>
28#include <optional>
29#include <string>
30
31using namespace llvm;
32
33#define DEBUG_TYPE "block-freq"
34
36 return getAnalysisOptions(C).view_bfi_func_name;
37}
39 return getAnalysisOptions(C).view_hot_freq_percent;
40}
45 return getAnalysisOptions(C).print_bfi_func_name;
46}
47
48namespace llvm {
49
52 return GVDAGType::Count;
53 return getAnalysisOptions(C).view_block_freq_propagation_dags;
54}
55
56template <>
58 using NodeRef = const BasicBlock *;
61
63 return &G->getFunction()->front();
64 }
65
67 return succ_begin(N);
68 }
69
70 static ChildIteratorType child_end(const NodeRef N) { return succ_end(N); }
71
73 return nodes_iterator(G->getFunction()->begin());
74 }
75
77 return nodes_iterator(G->getFunction()->end());
78 }
79};
80
83
84template <>
86 explicit DOTGraphTraits(bool isSimple = false)
88
89 std::string getNodeLabel(const BasicBlock *Node,
91
93 getGVDT(Node->getContext()));
94 }
95
101
103 const BlockFrequencyInfo *BFI) {
105 Node, EI, BFI, BFI->getBPI(),
106 getViewHotFreqPercent(Node->getContext()));
107 }
108};
109
110} // end namespace llvm
111
113
115 const BranchProbabilityInfo &BPI,
116 const CycleInfo &CI) {
117 calculate(F, BPI, CI);
118}
119
122
125 BFI = std::move(RHS.BFI);
126 return *this;
127}
128
129// Explicitly define the default constructor otherwise it would be implicitly
130// defined at the first ODR-use which is the BFI member in the
131// LazyBlockFrequencyInfo header. The dtor needs the BlockFrequencyInfoImpl
132// template instantiated which is not available in the header.
134
136 FunctionAnalysisManager::Invalidator &) {
137 // Check whether the analysis, all analyses on functions, or the function's
138 // CFG have been preserved.
139 auto PAC = PA.getChecker<BlockFrequencyAnalysis>();
140 return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>() ||
141 PAC.preservedSet<CFGAnalyses>());
142}
143
145 const BranchProbabilityInfo &BPI,
146 const CycleInfo &CI) {
147 if (!BFI)
148 BFI.reset(new ImplType);
149 BFI->calculate(F, BPI, CI);
150 const AnalysisOptions &Opts = getAnalysisOptions(F);
151 if (Opts.view_block_freq_propagation_dags != GVDAGType::None &&
152 (Opts.view_bfi_func_name.empty() ||
153 F.getName() == Opts.view_bfi_func_name)) {
154 view();
155 }
156 if (Opts.print_bfi && (Opts.print_bfi_func_name.empty() ||
157 F.getName() == Opts.print_bfi_func_name)) {
158 print(dbgs());
159 }
160}
161
163 return BFI ? BFI->getBlockFreq(BB) : BlockFrequency(0);
164}
165
166std::optional<uint64_t>
168 if (!BFI)
169 return std::nullopt;
170
171 return BFI->getBlockProfileCount(*getFunction(), BB);
172}
173
174std::optional<uint64_t>
176 if (!BFI)
177 return std::nullopt;
178 return BFI->getProfileCountFromFreq(*getFunction(), Freq);
179}
180
182 assert(BFI && "Expected analysis to be available");
183 return BFI->isIrrLoopHeader(BB);
184}
185
187 BlockFrequency Freq) {
188 assert(BFI && "Expected analysis to be available");
189 BFI->setBlockFreq(BB, Freq);
190}
191
193 const BasicBlock *ReferenceBB, BlockFrequency Freq,
194 SmallPtrSetImpl<BasicBlock *> &BlocksToScale) {
195 assert(BFI && "Expected analysis to be available");
196 // Use 128 bits APInt to avoid overflow.
197 APInt NewFreq(128, Freq.getFrequency());
198 APInt OldFreq(128, BFI->getBlockFreq(ReferenceBB).getFrequency());
199 APInt BBFreq(128, 0);
200 for (auto *BB : BlocksToScale) {
201 BBFreq = BFI->getBlockFreq(BB).getFrequency();
202 // Multiply first by NewFreq and then divide by OldFreq
203 // to minimize loss of precision.
204 BBFreq *= NewFreq;
205 // udiv is an expensive operation in the general case. If this ends up being
206 // a hot spot, one of the options proposed in
207 // https://reviews.llvm.org/D28535#650071 could be used to avoid this.
208 BBFreq = BBFreq.udiv(OldFreq);
209 BFI->setBlockFreq(BB, BlockFrequency(BBFreq.getLimitedValue()));
210 }
211 BFI->setBlockFreq(ReferenceBB, Freq);
212}
213
214/// Pop up a ghostview window with the current block frequency propagation
215/// rendered using dot.
217 ViewGraph(const_cast<BlockFrequencyInfo *>(this), title);
218}
219
221 return BFI ? BFI->getFunction() : nullptr;
222}
223
225 return BFI ? &BFI->getBPI() : nullptr;
226}
227
229 return BFI ? BFI->getEntryFreq() : BlockFrequency(0);
230}
231
233
235 if (BFI)
236 BFI->print(OS);
237}
238
240 if (BFI)
241 BFI->verifyMatch(*Other.BFI);
242}
243
245 BlockFrequency Freq) {
246 return Printable([&BFI, Freq](raw_ostream &OS) {
247 printRelativeBlockFreq(OS, BFI.getEntryFreq(), Freq);
248 });
249}
250
252 const BasicBlock &BB) {
253 return printBlockFreq(BFI, BFI.getBlockFreq(&BB));
254}
255
257 "Block Frequency Analysis", true, true)
261 "Block Frequency Analysis", true, true)
262
264
267
269
271 const Module *) const {
272 BFI.print(OS);
273}
274
280
281void BlockFrequencyInfoWrapperPass::releaseMemory() { BFI.releaseMemory(); }
282
287 BFI.calculate(F, BPI, LI);
288 return false;
289}
290
291AnalysisKey BlockFrequencyAnalysis::Key;
294 auto &BP = AM.getResult<BranchProbabilityAnalysis>(F);
295 auto &LI = AM.getResult<CycleAnalysis>(F);
297 BFI.calculate(F, BP, LI);
298 return BFI;
299}
300
303 OS << "Printing analysis results of BFI for function "
304 << "'" << F.getName() << "':"
305 << "\n";
307 return PreservedAnalyses::all();
308}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition MD5.cpp:54
#define G(x, y, z)
Definition MD5.cpp:55
static GVDAGType getGVDT()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
Class for arbitrary precision integers.
Definition APInt.h:78
This templated class represents "all analyses that operate over <aparticular IR unit>" (e....
Definition Analysis.h:50
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Analysis pass which computes BlockFrequencyInfo.
LLVM_ABI Result run(Function &F, FunctionAnalysisManager &AM)
Run the analysis pass over a function and produce BFI.
Legacy analysis pass which computes BlockFrequencyInfo.
void print(raw_ostream &OS, const Module *M) const override
print - Print out the internal state of the pass.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI bool isIrrLoopHeader(const BasicBlock *BB)
Returns true if BB is an irreducible loop header block.
LLVM_ABI std::optional< uint64_t > getProfileCountFromFreq(BlockFrequency Freq) const
Returns the estimated profile count of Freq.
LLVM_ABI void setBlockFreq(const BasicBlock *BB, BlockFrequency Freq)
LLVM_ABI ~BlockFrequencyInfo()
LLVM_ABI const Function * getFunction() const
LLVM_ABI std::optional< uint64_t > getBlockProfileCount(const BasicBlock *BB) const
Returns the estimated profile count of BB.
BlockFrequencyInfo & operator=(const BlockFrequencyInfo &)=delete
LLVM_ABI void calculate(const Function &F, const BranchProbabilityInfo &BPI, const CycleInfo &CI)
calculate - compute block frequency info for the given function.
LLVM_ABI void view(StringRef="BlockFrequencyDAGs") const
Pop up a ghostview window with the current block frequency propagation rendered using dot.
LLVM_ABI void setBlockFreqAndScale(const BasicBlock *ReferenceBB, BlockFrequency Freq, SmallPtrSetImpl< BasicBlock * > &BlocksToScale)
Set the frequency of ReferenceBB to Freq and scale the frequencies of the blocks in BlocksToScale suc...
LLVM_ABI const BranchProbabilityInfo * getBPI() const
LLVM_ABI BlockFrequency getEntryFreq() const
LLVM_ABI BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
LLVM_ABI void print(raw_ostream &OS) const
LLVM_ABI bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &)
Handle invalidation explicitly.
LLVM_ABI void verifyMatch(BlockFrequencyInfo &Other) const
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
Analysis pass which computes BranchProbabilityInfo.
Legacy analysis pass which computes BranchProbabilityInfo.
Analysis providing branch probability information.
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
Analysis pass which computes a CycleInfo.
Legacy analysis pass which computes a CycleInfo.
FunctionPass(char &pid)
Definition Pass.h:314
const Function & getFunction() const
Definition Function.h:167
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
Definition Analysis.h:275
Simple wrapper around std::function<void(raw_ostream&)>.
Definition Printable.h:38
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
const AnalysisOptions & getAnalysisOptions(const LLVMContext &C)
BFIDOTGraphTraitsBase< BlockFrequencyInfo, BranchProbabilityInfo > BFIDOTGTraitsBase
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI PGOViewCountsType getPGOViewCounts(const LLVMContext &C)
Return -pgo-view-counts.
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
@ Other
Any other memory.
Definition ModRef.h:68
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
void ViewGraph(const GraphType &G, const Twine &Name, bool ShortNames=false, const Twine &Title="", GraphProgram::Name Program=GraphProgram::DOT)
ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file, then cleanup.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
LLVM_ABI void printRelativeBlockFreq(raw_ostream &OS, BlockFrequency EntryFreq, BlockFrequency Freq)
Instruction::const_succ_iterator const_succ_iterator
Definition CFG.h:127
LLVM_ABI Printable printBlockFreq(const BlockFrequencyInfo &BFI, BlockFrequency Freq)
Print the block frequency Freq relative to the current functions entry frequency.
LLVM_ABI StringRef getPrintBFIFuncName(const LLVMContext &C)
Return -print-bfi-func-name.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI StringRef getViewBlockFreqFuncName(const LLVMContext &C)
Return -view-bfi-func-name.
LLVM_ABI unsigned getViewHotFreqPercent(const LLVMContext &C)
Return -view-hot-freq-percent.
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
#define N
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29
std::string getNodeAttributes(NodeRef Node, const BlockFrequencyInfo *Graph, unsigned HotPercentThreshold=0)
std::string getNodeLabel(NodeRef Node, const BlockFrequencyInfo *Graph, GVDAGType GType, int layout_order=-1)
std::string getEdgeAttributes(NodeRef Node, EdgeIter EI, const BlockFrequencyInfo *BFI, const BranchProbabilityInfo *BPI, unsigned HotPercentThreshold=0)
std::string getNodeAttributes(const BasicBlock *Node, const BlockFrequencyInfo *Graph)
std::string getEdgeAttributes(const BasicBlock *Node, EdgeIter EI, const BlockFrequencyInfo *BFI)
std::string getNodeLabel(const BasicBlock *Node, const BlockFrequencyInfo *Graph)
static ChildIteratorType child_begin(const NodeRef N)
static NodeRef getEntryNode(const BlockFrequencyInfo *G)
static ChildIteratorType child_end(const NodeRef N)
static nodes_iterator nodes_end(const BlockFrequencyInfo *G)
pointer_iterator< Function::const_iterator > nodes_iterator
static nodes_iterator nodes_begin(const BlockFrequencyInfo *G)