LLVM 22.0.0git
CFGPrinter.h
Go to the documentation of this file.
1//===-- CFGPrinter.h - CFG printer external interface -----------*- 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 defines a 'dot-cfg' analysis pass, which emits the
10// cfg.<fnname>.dot file for each function in the program, with a graph of the
11// CFG for that function.
12//
13// This file defines external functions that can be called to explicitly
14// instantiate the CFG printer.
15//
16//===----------------------------------------------------------------------===//
17
18#ifndef LLVM_ANALYSIS_CFGPRINTER_H
19#define LLVM_ANALYSIS_CFGPRINTER_H
20
24#include "llvm/IR/CFG.h"
25#include "llvm/IR/Constants.h"
26#include "llvm/IR/Function.h"
28#include "llvm/IR/PassManager.h"
33
34namespace llvm {
35class ModuleSlotTracker;
36
37template <class GraphType> struct GraphTraits;
38class CFGViewerPass : public PassInfoMixin<CFGViewerPass> {
39public:
41 static bool isRequired() { return true; }
42};
43
44class CFGOnlyViewerPass : public PassInfoMixin<CFGOnlyViewerPass> {
45public:
47 static bool isRequired() { return true; }
48};
49
50class CFGPrinterPass : public PassInfoMixin<CFGPrinterPass> {
51public:
53 static bool isRequired() { return true; }
54};
55
56class CFGOnlyPrinterPass : public PassInfoMixin<CFGOnlyPrinterPass> {
57public:
59 static bool isRequired() { return true; }
60};
61
63private:
64 const Function *F;
65 const BlockFrequencyInfo *BFI;
66 const BranchProbabilityInfo *BPI;
67 std::unique_ptr<ModuleSlotTracker> MSTStorage;
68 uint64_t MaxFreq;
69 bool ShowHeat;
70 bool EdgeWeights;
71 bool RawWeights;
72
73public:
74 DOTFuncInfo(const Function *F) : DOTFuncInfo(F, nullptr, nullptr, 0) {}
76
78 const BranchProbabilityInfo *BPI, uint64_t MaxFreq);
79
80 const BlockFrequencyInfo *getBFI() const { return BFI; }
81
82 const BranchProbabilityInfo *getBPI() const { return BPI; }
83
84 const Function *getFunction() const { return this->F; }
85
87
88 uint64_t getMaxFreq() const { return MaxFreq; }
89
90 uint64_t getFreq(const BasicBlock *BB) const {
91 return BFI->getBlockFreq(BB).getFrequency();
92 }
93
94 void setHeatColors(bool ShowHeat) { this->ShowHeat = ShowHeat; }
95
96 bool showHeatColors() { return ShowHeat; }
97
98 void setRawEdgeWeights(bool RawWeights) { this->RawWeights = RawWeights; }
99
100 bool useRawEdgeWeights() { return RawWeights; }
101
102 void setEdgeWeights(bool EdgeWeights) { this->EdgeWeights = EdgeWeights; }
103
104 bool showEdgeWeights() { return EdgeWeights; }
105};
106
107template <>
110 return &(CFGInfo->getFunction()->getEntryBlock());
111 }
112
113 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
115
117 return nodes_iterator(CFGInfo->getFunction()->begin());
118 }
119
121 return nodes_iterator(CFGInfo->getFunction()->end());
122 }
123
124 static size_t size(DOTFuncInfo *CFGInfo) {
125 return CFGInfo->getFunction()->size();
126 }
127};
128
129template <typename BasicBlockT>
130std::string SimpleNodeLabelString(const BasicBlockT *Node) {
131 if (!Node->getName().empty())
132 return Node->getName().str();
133
134 std::string Str;
136
137 Node->printAsOperand(OS, false);
138 return Str;
139}
140
141template <typename BasicBlockT>
143 const BasicBlockT *Node,
144 function_ref<void(raw_string_ostream &, const BasicBlockT &)>
145 HandleBasicBlock,
146 function_ref<void(std::string &, unsigned &, unsigned)>
147 HandleComment) {
148
149 enum { MaxColumns = 80 };
150 std::string OutStr;
151 raw_string_ostream OS(OutStr);
152 HandleBasicBlock(OS, *Node);
153 // Remove "%" from BB name
154 if (OutStr[0] == '%') {
155 OutStr.erase(OutStr.begin());
156 }
157 // Place | after BB name to separate it into header
158 OutStr.insert(OutStr.find_first_of('\n') + 1, "\\|");
159
160 unsigned ColNum = 0;
161 unsigned LastSpace = 0;
162 for (unsigned i = 0; i != OutStr.length(); ++i) {
163 if (OutStr[i] == '\n') { // Left justify
164 OutStr[i] = '\\';
165 OutStr.insert(OutStr.begin() + i + 1, 'l');
166 ColNum = 0;
167 LastSpace = 0;
168 } else if (OutStr[i] == ';') { // Delete comments!
169 unsigned Idx = OutStr.find('\n', i + 1); // Find end of line
170 HandleComment(OutStr, i, Idx);
171 } else if (ColNum == MaxColumns) { // Wrap lines.
172 // Wrap very long names even though we can't find a space.
173 if (!LastSpace)
174 LastSpace = i;
175 OutStr.insert(LastSpace, "\\l...");
176 ColNum = i - LastSpace;
177 LastSpace = 0;
178 i += 3; // The loop will advance 'i' again.
179 } else
180 ++ColNum;
181 if (OutStr[i] == ' ')
182 LastSpace = i;
183 }
184 return OutStr;
185}
186
187template <>
189
190 // Cache for is hidden property
192
194
195 static void eraseComment(std::string &OutStr, unsigned &I, unsigned Idx) {
196 OutStr.erase(OutStr.begin() + I, OutStr.begin() + Idx);
197 --I;
198 }
199
200 static std::string getGraphName(DOTFuncInfo *CFGInfo) {
201 return "CFG for '" + CFGInfo->getFunction()->getName().str() + "' function";
202 }
203
204 static std::string getSimpleNodeLabel(const BasicBlock *Node, DOTFuncInfo *) {
206 }
207
208 LLVM_ABI static std::string getCompleteNodeLabel(
209 const BasicBlock *Node, DOTFuncInfo *,
211 HandleBasicBlock = {},
212 function_ref<void(std::string &, unsigned &, unsigned)> HandleComment =
213 eraseComment);
214
215 std::string getNodeLabel(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
216
217 if (isSimple())
218 return getSimpleNodeLabel(Node, CFGInfo);
219 else
220 return getCompleteNodeLabel(Node, CFGInfo);
221 }
222
223 static std::string getEdgeSourceLabel(const BasicBlock *Node,
225 // Label source of conditional branches with "T" or "F"
226 if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
227 if (BI->isConditional())
228 return (I == succ_begin(Node)) ? "T" : "F";
229
230 // Label source of switch edges with the associated value.
231 if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
232 unsigned SuccNo = I.getSuccessorIndex();
233
234 if (SuccNo == 0)
235 return "def";
236
237 std::string Str;
240 OS << Case.getCaseValue()->getValue();
241 return Str;
242 }
243 return "";
244 }
245
246 static std::string getBBName(const BasicBlock *Node) {
247 std::string NodeName = Node->getName().str();
248 if (NodeName.empty()) {
249 raw_string_ostream NodeOS(NodeName);
250 Node->printAsOperand(NodeOS, false);
251 // Removing %
252 NodeName.erase(NodeName.begin());
253 }
254 return NodeName;
255 }
256
257 /// Display the raw branch weights from PGO.
259 DOTFuncInfo *CFGInfo) {
260 // If BPI is not provided do not display any edge attributes
261 if (!CFGInfo->showEdgeWeights())
262 return "";
263
264 unsigned OpNo = I.getSuccessorIndex();
265 const Instruction *TI = Node->getTerminator();
266 BasicBlock *SuccBB = TI->getSuccessor(OpNo);
267 auto BranchProb = CFGInfo->getBPI()->getEdgeProbability(Node, SuccBB);
268 double WeightPercent = ((double)BranchProb.getNumerator()) /
269 ((double)BranchProb.getDenominator());
270 std::string TTAttr =
271 formatv("tooltip=\"{0} -> {1}\\nProbability {2:P}\" ", getBBName(Node),
272 getBBName(SuccBB), WeightPercent);
273
274 if (TI->getNumSuccessors() == 1)
275 return TTAttr + "penwidth=2";
276
277 if (OpNo >= TI->getNumSuccessors())
278 return TTAttr;
279
280 double Width = 1 + WeightPercent;
281
282 if (!CFGInfo->useRawEdgeWeights())
283 return TTAttr +
284 formatv("label=\"{0:P}\" penwidth={1}", WeightPercent, Width)
285 .str();
286
287 // Prepend a 'W' to indicate that this is a weight rather than the actual
288 // profile count (due to scaling).
289
290 uint64_t Freq = CFGInfo->getFreq(Node);
291 std::string Attrs =
292 TTAttr + formatv("label=\"W:{0}\" penwidth={1}",
293 (uint64_t)(Freq * WeightPercent), Width)
294 .str();
295 if (Attrs.size())
296 return Attrs;
297
298 MDNode *WeightsNode = getBranchWeightMDNode(*TI);
299 if (!WeightsNode)
300 return TTAttr;
301
302 OpNo = I.getSuccessorIndex() + 1;
303 if (OpNo >= WeightsNode->getNumOperands())
304 return TTAttr;
305 ConstantInt *Weight =
306 mdconst::dyn_extract<ConstantInt>(WeightsNode->getOperand(OpNo));
307 if (!Weight)
308 return TTAttr;
309 return (TTAttr + "label=\"W:" + std::to_string(Weight->getZExtValue()) +
310 "\" penwidth=" + std::to_string(Width));
311 }
312
313 std::string getNodeAttributes(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
314
315 if (!CFGInfo->showHeatColors())
316 return "";
317
318 uint64_t Freq = CFGInfo->getFreq(Node);
319 std::string Color = getHeatColor(Freq, CFGInfo->getMaxFreq());
320 std::string EdgeColor = (Freq <= (CFGInfo->getMaxFreq() / 2))
321 ? (getHeatColor(0))
322 : (getHeatColor(1));
323
324 std::string Attrs = "color=\"" + EdgeColor + "ff\", style=filled," +
325 " fillcolor=\"" + Color + "70\"" +
326 " fontname=\"Courier\"";
327 return Attrs;
328 }
330 const DOTFuncInfo *CFGInfo);
332};
333} // namespace llvm
334
335#endif
#define LLVM_ABI
Definition: Compiler.h:213
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
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:55
#define I(x, y, z)
Definition: MD5.cpp:58
StandardInstrumentations SI(Mod->getContext(), Debug, VerifyEach)
This file contains the declarations for profiling metadata utility functions.
static bool isSimple(Instruction *I)
raw_pwrite_stream & OS
void printAsOperand(OutputBuffer &OB, Prec P=Prec::Default, bool StrictlyWorse=false) const
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:255
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Conditional or Unconditional Branch instruction.
Analysis providing branch probability information.
LLVM_ABI BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
static bool isRequired()
Definition: CFGPrinter.h:59
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: CFGPrinter.cpp:139
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: CFGPrinter.cpp:119
static bool isRequired()
Definition: CFGPrinter.h:47
static bool isRequired()
Definition: CFGPrinter.h:53
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: CFGPrinter.cpp:129
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: CFGPrinter.cpp:110
static bool isRequired()
Definition: CFGPrinter.h:41
This is the shared class of boolean and integer constants.
Definition: Constants.h:87
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition: Constants.h:163
void setRawEdgeWeights(bool RawWeights)
Definition: CFGPrinter.h:98
uint64_t getMaxFreq() const
Definition: CFGPrinter.h:88
LLVM_ABI ~DOTFuncInfo()
void setEdgeWeights(bool EdgeWeights)
Definition: CFGPrinter.h:102
DOTFuncInfo(const Function *F)
Definition: CFGPrinter.h:74
uint64_t getFreq(const BasicBlock *BB) const
Definition: CFGPrinter.h:90
const BranchProbabilityInfo * getBPI() const
Definition: CFGPrinter.h:82
bool showEdgeWeights()
Definition: CFGPrinter.h:104
bool showHeatColors()
Definition: CFGPrinter.h:96
LLVM_ABI ModuleSlotTracker * getModuleSlotTracker()
Definition: CFGPrinter.cpp:104
bool useRawEdgeWeights()
Definition: CFGPrinter.h:100
const Function * getFunction() const
Definition: CFGPrinter.h:84
const BlockFrequencyInfo * getBFI() const
Definition: CFGPrinter.h:80
void setHeatColors(bool ShowHeat)
Definition: CFGPrinter.h:94
const BasicBlock & getEntryBlock() const
Definition: Function.h:807
iterator begin()
Definition: Function.h:851
size_t size() const
Definition: Function.h:856
iterator end()
Definition: Function.h:853
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
Metadata node.
Definition: Metadata.h:1077
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1445
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1451
Manage lifetime of a slot tracker for printing IR.
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:112
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:233
static CaseIteratorImpl fromSuccessorIndex(SwitchInstT *SI, unsigned SuccessorIndex)
Initializes case iterator for given SwitchInst and for given successor index.
Multiway switch.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:322
An efficient, type-erasing, non-owning reference to a callable.
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:662
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
LLVM_ABI MDNode * getBranchWeightMDNode(const Instruction &I)
Get the branch weights metadata node.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
std::string SimpleNodeLabelString(const BasicBlockT *Node)
Definition: CFGPrinter.h:130
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
LLVM_ABI std::string getHeatColor(uint64_t freq, uint64_t maxFreq)
Definition: HeatUtils.cpp:63
std::string CompleteNodeLabelString(const BasicBlockT *Node, function_ref< void(raw_string_ostream &, const BasicBlockT &)> HandleBasicBlock, function_ref< void(std::string &, unsigned &, unsigned)> HandleComment)
Definition: CFGPrinter.h:142
std::string getEdgeAttributes(const BasicBlock *Node, const_succ_iterator I, DOTFuncInfo *CFGInfo)
Display the raw branch weights from PGO.
Definition: CFGPrinter.h:258
static LLVM_ABI std::string getCompleteNodeLabel(const BasicBlock *Node, DOTFuncInfo *, function_ref< void(raw_string_ostream &, const BasicBlock &)> HandleBasicBlock={}, function_ref< void(std::string &, unsigned &, unsigned)> HandleComment=eraseComment)
LLVM_ABI bool isNodeHidden(const BasicBlock *Node, const DOTFuncInfo *CFGInfo)
static std::string getSimpleNodeLabel(const BasicBlock *Node, DOTFuncInfo *)
Definition: CFGPrinter.h:204
static std::string getGraphName(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:200
DenseMap< const BasicBlock *, bool > isOnDeoptOrUnreachablePath
Definition: CFGPrinter.h:191
LLVM_ABI void computeDeoptOrUnreachablePaths(const Function *F)
DOTGraphTraits(bool isSimple=false)
Definition: CFGPrinter.h:193
std::string getNodeAttributes(const BasicBlock *Node, DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:313
static std::string getEdgeSourceLabel(const BasicBlock *Node, const_succ_iterator I)
Definition: CFGPrinter.h:223
static void eraseComment(std::string &OutStr, unsigned &I, unsigned Idx)
Definition: CFGPrinter.h:195
std::string getNodeLabel(const BasicBlock *Node, DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:215
static std::string getBBName(const BasicBlock *Node)
Definition: CFGPrinter.h:246
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to 'dot...
DefaultDOTGraphTraits - This class provides the default implementations of all of the DOTGraphTraits ...
static nodes_iterator nodes_begin(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:116
static size_t size(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:124
static NodeRef getEntryNode(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:109
static nodes_iterator nodes_end(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:120
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:70