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 (const Instruction &Inst : Node)
212 OS << Inst << "\n";
213 }
214
215 static std::string getCompleteNodeLabel(
216 const BasicBlock *Node, DOTFuncInfo *,
218 HandleBasicBlock = printBasicBlock,
219 function_ref<void(std::string &, unsigned &, unsigned)>
220 HandleComment = eraseComment) {
221 return CompleteNodeLabelString(Node, HandleBasicBlock, HandleComment);
222 }
223
224 std::string getNodeLabel(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
225
226 if (isSimple())
227 return getSimpleNodeLabel(Node, CFGInfo);
228 else
229 return getCompleteNodeLabel(Node, CFGInfo);
230 }
231
232 static std::string getEdgeSourceLabel(const BasicBlock *Node,
234 // Label source of conditional branches with "T" or "F"
235 if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
236 if (BI->isConditional())
237 return (I == succ_begin(Node)) ? "T" : "F";
238
239 // Label source of switch edges with the associated value.
240 if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
241 unsigned SuccNo = I.getSuccessorIndex();
242
243 if (SuccNo == 0)
244 return "def";
245
246 std::string Str;
249 OS << Case.getCaseValue()->getValue();
250 return OS.str();
251 }
252 return "";
253 }
254
255 static std::string getBBName(const BasicBlock *Node) {
256 std::string NodeName = Node->getName().str();
257 if (NodeName.empty()) {
258 raw_string_ostream NodeOS(NodeName);
259 Node->printAsOperand(NodeOS, false);
260 NodeName = NodeOS.str();
261 // Removing %
262 NodeName.erase(NodeName.begin());
263 }
264 return NodeName;
265 }
266
267 /// Display the raw branch weights from PGO.
269 DOTFuncInfo *CFGInfo) {
270 unsigned OpNo = I.getSuccessorIndex();
271 const Instruction *TI = Node->getTerminator();
272 BasicBlock *SuccBB = TI->getSuccessor(OpNo);
273 auto BranchProb = CFGInfo->getBPI()->getEdgeProbability(Node, SuccBB);
274 double WeightPercent = ((double)BranchProb.getNumerator()) /
275 ((double)BranchProb.getDenominator());
276
277 std::string TTAttr =
278 formatv("tooltip=\"{0} -> {1}\\nProbability {2:P}\" ", getBBName(Node),
279 getBBName(SuccBB), WeightPercent);
280 if (!CFGInfo->showEdgeWeights())
281 return TTAttr;
282
283 if (TI->getNumSuccessors() == 1)
284 return TTAttr + "penwidth=2";
285
286 if (OpNo >= TI->getNumSuccessors())
287 return TTAttr;
288
289 double Width = 1 + WeightPercent;
290
291 if (!CFGInfo->useRawEdgeWeights())
292 return TTAttr +
293 formatv("label=\"{0:P}\" penwidth={1}", WeightPercent, Width)
294 .str();
295
296 // Prepend a 'W' to indicate that this is a weight rather than the actual
297 // profile count (due to scaling).
298
299 uint64_t Freq = CFGInfo->getFreq(Node);
300 std::string Attrs =
301 TTAttr + formatv("label=\"W:{0}\" penwidth={1}",
302 (uint64_t)(Freq * WeightPercent), Width)
303 .str();
304 if (Attrs.size())
305 return Attrs;
306
307 MDNode *WeightsNode = getBranchWeightMDNode(*TI);
308 if (!WeightsNode)
309 return TTAttr;
310
311 OpNo = I.getSuccessorIndex() + 1;
312 if (OpNo >= WeightsNode->getNumOperands())
313 return TTAttr;
314 ConstantInt *Weight =
315 mdconst::dyn_extract<ConstantInt>(WeightsNode->getOperand(OpNo));
316 if (!Weight)
317 return TTAttr;
318 return (TTAttr + "label=\"W:" + std::to_string(Weight->getZExtValue()) +
319 "\" penwidth=" + std::to_string(Width));
320 }
321
322 std::string getNodeAttributes(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
323
324 if (!CFGInfo->showHeatColors())
325 return "";
326
327 uint64_t Freq = CFGInfo->getFreq(Node);
328 std::string Color = getHeatColor(Freq, CFGInfo->getMaxFreq());
329 std::string EdgeColor = (Freq <= (CFGInfo->getMaxFreq() / 2))
330 ? (getHeatColor(0))
331 : (getHeatColor(1));
332
333 std::string Attrs = "color=\"" + EdgeColor + "ff\", style=filled," +
334 " fillcolor=\"" + Color + "70\"" +
335 " fontname=\"Courier\"";
336 return Attrs;
337 }
338 bool isNodeHidden(const BasicBlock *Node, const DOTFuncInfo *CFGInfo);
340};
341} // End llvm namespace
342
343#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:253
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
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:81
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:155
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:800
iterator begin()
Definition: Function.h:816
size_t size() const
Definition: Function.h:821
iterator end()
Definition: Function.h:818
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:111
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:661
std::string & str()
Returns the string's reference.
Definition: raw_ostream.h:679
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:268
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:322
static std::string getEdgeSourceLabel(const BasicBlock *Node, const_succ_iterator I)
Definition: CFGPrinter.h:232
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:224
static std::string getBBName(const BasicBlock *Node)
Definition: CFGPrinter.h:255
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:215
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:69