LLVM 19.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"
32
33namespace llvm {
34template <class GraphType> struct GraphTraits;
35class CFGViewerPass : public PassInfoMixin<CFGViewerPass> {
36public:
38 static bool isRequired() { return true; }
39};
40
41class CFGOnlyViewerPass : public PassInfoMixin<CFGOnlyViewerPass> {
42public:
44 static bool isRequired() { return true; }
45};
46
47class CFGPrinterPass : public PassInfoMixin<CFGPrinterPass> {
48public:
50 static bool isRequired() { return true; }
51};
52
53class CFGOnlyPrinterPass : public PassInfoMixin<CFGOnlyPrinterPass> {
54public:
56 static bool isRequired() { return true; }
57};
58
60private:
61 const Function *F;
62 const BlockFrequencyInfo *BFI;
63 const BranchProbabilityInfo *BPI;
64 uint64_t MaxFreq;
65 bool ShowHeat;
66 bool EdgeWeights;
67 bool RawWeights;
68
69public:
70 DOTFuncInfo(const Function *F) : DOTFuncInfo(F, nullptr, nullptr, 0) {}
71
73 const BranchProbabilityInfo *BPI, uint64_t MaxFreq)
74 : F(F), BFI(BFI), BPI(BPI), MaxFreq(MaxFreq) {
75 ShowHeat = false;
76 EdgeWeights = !!BPI; // Print EdgeWeights when BPI is available.
77 RawWeights = !!BFI; // Print RawWeights when BFI is available.
78 }
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
86 uint64_t getMaxFreq() const { return MaxFreq; }
87
88 uint64_t getFreq(const BasicBlock *BB) const {
89 return BFI->getBlockFreq(BB).getFrequency();
90 }
91
92 void setHeatColors(bool ShowHeat) { this->ShowHeat = ShowHeat; }
93
94 bool showHeatColors() { return ShowHeat; }
95
96 void setRawEdgeWeights(bool RawWeights) { this->RawWeights = RawWeights; }
97
98 bool useRawEdgeWeights() { return RawWeights; }
99
100 void setEdgeWeights(bool EdgeWeights) { this->EdgeWeights = EdgeWeights; }
101
102 bool showEdgeWeights() { return EdgeWeights; }
103};
104
105template <>
108 return &(CFGInfo->getFunction()->getEntryBlock());
109 }
110
111 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
113
115 return nodes_iterator(CFGInfo->getFunction()->begin());
116 }
117
119 return nodes_iterator(CFGInfo->getFunction()->end());
120 }
121
122 static size_t size(DOTFuncInfo *CFGInfo) {
123 return CFGInfo->getFunction()->size();
124 }
125};
126
127template <typename BasicBlockT>
128std::string SimpleNodeLabelString(const BasicBlockT *Node) {
129 if (!Node->getName().empty())
130 return Node->getName().str();
131
132 std::string Str;
134
135 Node->printAsOperand(OS, false);
136 return OS.str();
137}
138
139template <typename BasicBlockT>
141 const BasicBlockT *Node,
142 function_ref<void(raw_string_ostream &, const BasicBlockT &)>
143 HandleBasicBlock,
144 function_ref<void(std::string &, unsigned &, unsigned)>
145 HandleComment) {
146
147 enum { MaxColumns = 80 };
148 std::string Str;
150 HandleBasicBlock(OS, *Node);
151 std::string OutStr = OS.str();
152 // Remove "%" from BB name
153 if (OutStr[0] == '%') {
154 OutStr.erase(OutStr.begin());
155 }
156 // Place | after BB name to separate it into header
157 OutStr.insert(OutStr.find_first_of('\n') + 1, "\\|");
158
159 unsigned ColNum = 0;
160 unsigned LastSpace = 0;
161 for (unsigned i = 0; i != OutStr.length(); ++i) {
162 if (OutStr[i] == '\n') { // Left justify
163 OutStr[i] = '\\';
164 OutStr.insert(OutStr.begin() + i + 1, 'l');
165 ColNum = 0;
166 LastSpace = 0;
167 } else if (OutStr[i] == ';') { // Delete comments!
168 unsigned Idx = OutStr.find('\n', i + 1); // Find end of line
169 HandleComment(OutStr, i, Idx);
170 } else if (ColNum == MaxColumns) { // Wrap lines.
171 // Wrap very long names even though we can't find a space.
172 if (!LastSpace)
173 LastSpace = i;
174 OutStr.insert(LastSpace, "\\l...");
175 ColNum = i - LastSpace;
176 LastSpace = 0;
177 i += 3; // The loop will advance 'i' again.
178 } else
179 ++ColNum;
180 if (OutStr[i] == ' ')
181 LastSpace = i;
182 }
183 return OutStr;
184}
185
186template <>
188
189 // Cache for is hidden property
191
193
194 static void eraseComment(std::string &OutStr, unsigned &I, unsigned Idx) {
195 OutStr.erase(OutStr.begin() + I, OutStr.begin() + Idx);
196 --I;
197 }
198
199 static std::string getGraphName(DOTFuncInfo *CFGInfo) {
200 return "CFG for '" + CFGInfo->getFunction()->getName().str() + "' function";
201 }
202
203 static std::string getSimpleNodeLabel(const BasicBlock *Node, DOTFuncInfo *) {
205 }
206
208 // Prepend label name
209 Node.printAsOperand(OS, false);
210 OS << ":\n";
211 for (auto J = Node.begin(), JE = Node.end(); J != JE; ++J) {
212 const Instruction *Inst = &*J;
213 OS << *Inst << "\n";
214 }
215 }
216
217 static std::string getCompleteNodeLabel(
218 const BasicBlock *Node, DOTFuncInfo *,
220 HandleBasicBlock = printBasicBlock,
221 function_ref<void(std::string &, unsigned &, unsigned)>
222 HandleComment = eraseComment) {
223 return CompleteNodeLabelString(Node, HandleBasicBlock, HandleComment);
224 }
225
226 std::string getNodeLabel(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
227
228 if (isSimple())
229 return getSimpleNodeLabel(Node, CFGInfo);
230 else
231 return getCompleteNodeLabel(Node, CFGInfo);
232 }
233
234 static std::string getEdgeSourceLabel(const BasicBlock *Node,
236 // Label source of conditional branches with "T" or "F"
237 if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
238 if (BI->isConditional())
239 return (I == succ_begin(Node)) ? "T" : "F";
240
241 // Label source of switch edges with the associated value.
242 if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
243 unsigned SuccNo = I.getSuccessorIndex();
244
245 if (SuccNo == 0)
246 return "def";
247
248 std::string Str;
251 OS << Case.getCaseValue()->getValue();
252 return OS.str();
253 }
254 return "";
255 }
256
257 static std::string getBBName(const BasicBlock *Node) {
258 std::string NodeName = Node->getName().str();
259 if (NodeName.empty()) {
260 raw_string_ostream NodeOS(NodeName);
261 Node->printAsOperand(NodeOS, false);
262 NodeName = NodeOS.str();
263 // Removing %
264 NodeName.erase(NodeName.begin());
265 }
266 return NodeName;
267 }
268
269 /// Display the raw branch weights from PGO.
271 DOTFuncInfo *CFGInfo) {
272 unsigned OpNo = I.getSuccessorIndex();
273 const Instruction *TI = Node->getTerminator();
274 BasicBlock *SuccBB = TI->getSuccessor(OpNo);
275 auto BranchProb = CFGInfo->getBPI()->getEdgeProbability(Node, SuccBB);
276 double WeightPercent = ((double)BranchProb.getNumerator()) /
277 ((double)BranchProb.getDenominator());
278
279 std::string TTAttr =
280 formatv("tooltip=\"{0} -> {1}\\nProbability {2:P}\" ", getBBName(Node),
281 getBBName(SuccBB), WeightPercent);
282 if (!CFGInfo->showEdgeWeights())
283 return TTAttr;
284
285 if (TI->getNumSuccessors() == 1)
286 return TTAttr + "penwidth=2";
287
288 if (OpNo >= TI->getNumSuccessors())
289 return TTAttr;
290
291 double Width = 1 + WeightPercent;
292
293 if (!CFGInfo->useRawEdgeWeights())
294 return TTAttr +
295 formatv("label=\"{0:P}\" penwidth={1}", WeightPercent, Width)
296 .str();
297
298 // Prepend a 'W' to indicate that this is a weight rather than the actual
299 // profile count (due to scaling).
300
301 uint64_t Freq = CFGInfo->getFreq(Node);
302 std::string Attrs =
303 TTAttr + formatv("label=\"W:{0}\" penwidth={1}",
304 (uint64_t)(Freq * WeightPercent), Width)
305 .str();
306 if (Attrs.size())
307 return Attrs;
308
309 MDNode *WeightsNode = getBranchWeightMDNode(*TI);
310 if (!WeightsNode)
311 return TTAttr;
312
313 OpNo = I.getSuccessorIndex() + 1;
314 if (OpNo >= WeightsNode->getNumOperands())
315 return TTAttr;
316 ConstantInt *Weight =
317 mdconst::dyn_extract<ConstantInt>(WeightsNode->getOperand(OpNo));
318 if (!Weight)
319 return TTAttr;
320 return (TTAttr + "label=\"W:" + std::to_string(Weight->getZExtValue()) +
321 "\" penwidth=" + std::to_string(Width));
322 }
323
324 std::string getNodeAttributes(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
325
326 if (!CFGInfo->showHeatColors())
327 return "";
328
329 uint64_t Freq = CFGInfo->getFreq(Node);
330 std::string Color = getHeatColor(Freq, CFGInfo->getMaxFreq());
331 std::string EdgeColor = (Freq <= (CFGInfo->getMaxFreq() / 2))
332 ? (getHeatColor(0))
333 : (getHeatColor(1));
334
335 std::string Attrs = "color=\"" + EdgeColor + "ff\", style=filled," +
336 " fillcolor=\"" + Color + "70\"" +
337 " fontname=\"Courier\"";
338 return Attrs;
339 }
340 bool isNodeHidden(const BasicBlock *Node, const DOTFuncInfo *CFGInfo);
342};
343} // End llvm namespace
344
345#endif
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...
#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 header defines various interfaces for pass management in LLVM.
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:321
LLVM Basic Block Representation.
Definition: BasicBlock.h:60
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Conditional or Unconditional Branch instruction.
Analysis providing branch probability information.
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:56
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: CFGPrinter.cpp:122
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: CFGPrinter.cpp:102
static bool isRequired()
Definition: CFGPrinter.h:44
static bool isRequired()
Definition: CFGPrinter.h:50
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: CFGPrinter.cpp:112
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: CFGPrinter.cpp:93
static bool isRequired()
Definition: CFGPrinter.h:38
This is the shared class of boolean and integer constants.
Definition: Constants.h:80
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:154
void setRawEdgeWeights(bool RawWeights)
Definition: CFGPrinter.h:96
DOTFuncInfo(const Function *F, const BlockFrequencyInfo *BFI, const BranchProbabilityInfo *BPI, uint64_t MaxFreq)
Definition: CFGPrinter.h:72
uint64_t getMaxFreq() const
Definition: CFGPrinter.h:86
void setEdgeWeights(bool EdgeWeights)
Definition: CFGPrinter.h:100
DOTFuncInfo(const Function *F)
Definition: CFGPrinter.h:70
uint64_t getFreq(const BasicBlock *BB) const
Definition: CFGPrinter.h:88
const BranchProbabilityInfo * getBPI() const
Definition: CFGPrinter.h:82
bool showEdgeWeights()
Definition: CFGPrinter.h:102
bool showHeatColors()
Definition: CFGPrinter.h:94
bool useRawEdgeWeights()
Definition: CFGPrinter.h:98
const Function * getFunction() const
Definition: CFGPrinter.h:84
const BlockFrequencyInfo * getBFI() const
Definition: CFGPrinter.h:80
void setHeatColors(bool ShowHeat)
Definition: CFGPrinter.h:92
const BasicBlock & getEntryBlock() const
Definition: Function.h:787
iterator begin()
Definition: Function.h:803
size_t size() const
Definition: Function.h:808
iterator end()
Definition: Function.h:805
unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
Metadata node.
Definition: Metadata.h:1067
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1428
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1434
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:109
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:223
static CaseIteratorImpl fromSuccessorIndex(SwitchInstT *SI, unsigned SuccessorIndex)
Initializes case iterator for given SwitchInst and for given successor index.
Multiway switch.
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
An efficient, type-erasing, non-owning reference to a callable.
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:660
std::string & str()
Returns the string's reference.
Definition: raw_ostream.h:678
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MDNode * getBranchWeightMDNode(const Instruction &I)
Get the branch weights metadata node.
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
std::string SimpleNodeLabelString(const BasicBlockT *Node)
Definition: CFGPrinter.h:128
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
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:140
std::string getEdgeAttributes(const BasicBlock *Node, const_succ_iterator I, DOTFuncInfo *CFGInfo)
Display the raw branch weights from PGO.
Definition: CFGPrinter.h:270
void computeDeoptOrUnreachablePaths(const Function *F)
static std::string getSimpleNodeLabel(const BasicBlock *Node, DOTFuncInfo *)
Definition: CFGPrinter.h:203
static std::string getGraphName(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:199
DenseMap< const BasicBlock *, bool > isOnDeoptOrUnreachablePath
Definition: CFGPrinter.h:190
bool isNodeHidden(const BasicBlock *Node, const DOTFuncInfo *CFGInfo)
DOTGraphTraits(bool isSimple=false)
Definition: CFGPrinter.h:192
std::string getNodeAttributes(const BasicBlock *Node, DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:324
static std::string getEdgeSourceLabel(const BasicBlock *Node, const_succ_iterator I)
Definition: CFGPrinter.h:234
static void eraseComment(std::string &OutStr, unsigned &I, unsigned Idx)
Definition: CFGPrinter.h:194
std::string getNodeLabel(const BasicBlock *Node, DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:226
static std::string getBBName(const BasicBlock *Node)
Definition: CFGPrinter.h:257
static void printBasicBlock(raw_string_ostream &OS, const BasicBlock &Node)
Definition: CFGPrinter.h:207
static std::string getCompleteNodeLabel(const BasicBlock *Node, DOTFuncInfo *, function_ref< void(raw_string_ostream &, const BasicBlock &)> HandleBasicBlock=printBasicBlock, function_ref< void(std::string &, unsigned &, unsigned)> HandleComment=eraseComment)
Definition: CFGPrinter.h:217
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:114
static size_t size(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:122
static NodeRef getEntryNode(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:107
static nodes_iterator nodes_end(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:118
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:74