LLVM 17.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};
39
40class CFGOnlyViewerPass : public PassInfoMixin<CFGOnlyViewerPass> {
41public:
43};
44
45class CFGPrinterPass : public PassInfoMixin<CFGPrinterPass> {
46public:
48};
49
50class CFGOnlyPrinterPass : public PassInfoMixin<CFGOnlyPrinterPass> {
51public:
53};
54
56private:
57 const Function *F;
58 const BlockFrequencyInfo *BFI;
59 const BranchProbabilityInfo *BPI;
60 uint64_t MaxFreq;
61 bool ShowHeat;
62 bool EdgeWeights;
63 bool RawWeights;
64
65public:
66 DOTFuncInfo(const Function *F) : DOTFuncInfo(F, nullptr, nullptr, 0) {}
67
69 const BranchProbabilityInfo *BPI, uint64_t MaxFreq)
70 : F(F), BFI(BFI), BPI(BPI), MaxFreq(MaxFreq) {
71 ShowHeat = false;
72 EdgeWeights = !!BPI; // Print EdgeWeights when BPI is available.
73 RawWeights = !!BFI; // Print RawWeights when BFI is available.
74 }
75
76 const BlockFrequencyInfo *getBFI() const { return BFI; }
77
78 const BranchProbabilityInfo *getBPI() const { return BPI; }
79
80 const Function *getFunction() const { return this->F; }
81
82 uint64_t getMaxFreq() const { return MaxFreq; }
83
84 uint64_t getFreq(const BasicBlock *BB) const {
85 return BFI->getBlockFreq(BB).getFrequency();
86 }
87
88 void setHeatColors(bool ShowHeat) { this->ShowHeat = ShowHeat; }
89
90 bool showHeatColors() { return ShowHeat; }
91
92 void setRawEdgeWeights(bool RawWeights) { this->RawWeights = RawWeights; }
93
94 bool useRawEdgeWeights() { return RawWeights; }
95
96 void setEdgeWeights(bool EdgeWeights) { this->EdgeWeights = EdgeWeights; }
97
98 bool showEdgeWeights() { return EdgeWeights; }
99};
100
101template <>
104 return &(CFGInfo->getFunction()->getEntryBlock());
105 }
106
107 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
109
111 return nodes_iterator(CFGInfo->getFunction()->begin());
112 }
113
115 return nodes_iterator(CFGInfo->getFunction()->end());
116 }
117
118 static size_t size(DOTFuncInfo *CFGInfo) {
119 return CFGInfo->getFunction()->size();
120 }
121};
122
123template <typename BasicBlockT>
124std::string SimpleNodeLabelString(const BasicBlockT *Node) {
125 if (!Node->getName().empty())
126 return Node->getName().str();
127
128 std::string Str;
130
131 Node->printAsOperand(OS, false);
132 return OS.str();
133}
134
135template <typename BasicBlockT>
137 const BasicBlockT *Node,
138 function_ref<void(raw_string_ostream &, const BasicBlockT &)>
139 HandleBasicBlock,
140 function_ref<void(std::string &, unsigned &, unsigned)>
141 HandleComment) {
142
143 enum { MaxColumns = 80 };
144 std::string Str;
146
147 if (Node->getName().empty()) {
148 Node->printAsOperand(OS, false);
149 OS << ':';
150 }
151
152 HandleBasicBlock(OS, *Node);
153 std::string OutStr = OS.str();
154 if (OutStr[0] == '\n')
155 OutStr.erase(OutStr.begin());
156
157 unsigned ColNum = 0;
158 unsigned LastSpace = 0;
159 for (unsigned i = 0; i != OutStr.length(); ++i) {
160 if (OutStr[i] == '\n') { // Left justify
161 OutStr[i] = '\\';
162 OutStr.insert(OutStr.begin() + i + 1, 'l');
163 ColNum = 0;
164 LastSpace = 0;
165 } else if (OutStr[i] == ';') { // Delete comments!
166 unsigned Idx = OutStr.find('\n', i + 1); // Find end of line
167 HandleComment(OutStr, i, Idx);
168 } else if (ColNum == MaxColumns) { // Wrap lines.
169 // Wrap very long names even though we can't find a space.
170 if (!LastSpace)
171 LastSpace = i;
172 OutStr.insert(LastSpace, "\\l...");
173 ColNum = i - LastSpace;
174 LastSpace = 0;
175 i += 3; // The loop will advance 'i' again.
176 } else
177 ++ColNum;
178 if (OutStr[i] == ' ')
179 LastSpace = i;
180 }
181 return OutStr;
182}
183
184template <>
186
187 // Cache for is hidden property
189
191
192 static void eraseComment(std::string &OutStr, unsigned &I, unsigned Idx) {
193 OutStr.erase(OutStr.begin() + I, OutStr.begin() + Idx);
194 --I;
195 }
196
197 static std::string getGraphName(DOTFuncInfo *CFGInfo) {
198 return "CFG for '" + CFGInfo->getFunction()->getName().str() + "' function";
199 }
200
201 static std::string getSimpleNodeLabel(const BasicBlock *Node, DOTFuncInfo *) {
203 }
204
205 static std::string getCompleteNodeLabel(
206 const BasicBlock *Node, DOTFuncInfo *,
208 HandleBasicBlock = [](raw_string_ostream &OS,
209 const BasicBlock &Node) -> void { OS << Node; },
210 function_ref<void(std::string &, unsigned &, unsigned)>
211 HandleComment = eraseComment) {
212 return CompleteNodeLabelString(Node, HandleBasicBlock, HandleComment);
213 }
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 OS.str();
242 }
243 return "";
244 }
245
246 /// Display the raw branch weights from PGO.
248 DOTFuncInfo *CFGInfo) {
249 if (!CFGInfo->showEdgeWeights())
250 return "";
251
252 const Instruction *TI = Node->getTerminator();
253 if (TI->getNumSuccessors() == 1)
254 return "penwidth=2";
255
256 unsigned OpNo = I.getSuccessorIndex();
257
258 if (OpNo >= TI->getNumSuccessors())
259 return "";
260
261 BasicBlock *SuccBB = TI->getSuccessor(OpNo);
262 auto BranchProb = CFGInfo->getBPI()->getEdgeProbability(Node, SuccBB);
263 double WeightPercent = ((double)BranchProb.getNumerator()) /
264 ((double)BranchProb.getDenominator());
265 double Width = 1 + WeightPercent;
266
267 if (!CFGInfo->useRawEdgeWeights())
268 return formatv("label=\"{0:P}\" penwidth={1}", WeightPercent, Width)
269 .str();
270
271 // Prepend a 'W' to indicate that this is a weight rather than the actual
272 // profile count (due to scaling).
273
274 uint64_t Freq = CFGInfo->getFreq(Node);
275 std::string Attrs = formatv("label=\"W:{0}\" penwidth={1}",
276 (uint64_t)(Freq * WeightPercent), Width);
277 if (Attrs.size())
278 return Attrs;
279
280 MDNode *WeightsNode = getBranchWeightMDNode(*TI);
281 if (!WeightsNode)
282 return "";
283
284 OpNo = I.getSuccessorIndex() + 1;
285 if (OpNo >= WeightsNode->getNumOperands())
286 return "";
287 ConstantInt *Weight =
288 mdconst::dyn_extract<ConstantInt>(WeightsNode->getOperand(OpNo));
289 if (!Weight)
290 return "";
291 return ("label=\"W:" + std::to_string(Weight->getZExtValue()) +
292 "\" penwidth=" + std::to_string(Width));
293 }
294
295 std::string getNodeAttributes(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
296
297 if (!CFGInfo->showHeatColors())
298 return "";
299
300 uint64_t Freq = CFGInfo->getFreq(Node);
301 std::string Color = getHeatColor(Freq, CFGInfo->getMaxFreq());
302 std::string EdgeColor = (Freq <= (CFGInfo->getMaxFreq() / 2))
303 ? (getHeatColor(0))
304 : (getHeatColor(1));
305
306 std::string Attrs = "color=\"" + EdgeColor + "ff\", style=filled," +
307 " fillcolor=\"" + Color + "70\"";
308 return Attrs;
309 }
310 bool isNodeHidden(const BasicBlock *Node, const DOTFuncInfo *CFGInfo);
312};
313} // End llvm namespace
314
315namespace llvm {
316class FunctionPass;
317FunctionPass *createCFGPrinterLegacyPassPass();
319} // End llvm namespace
320
321#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
This header defines various interfaces for pass management in LLVM.
This file contains the declarations for profiling metadata utility functions.
@ SI
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:620
LLVM Basic Block Representation.
Definition: BasicBlock.h:56
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.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
This is the shared class of boolean and integer constants.
Definition: Constants.h:78
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:145
void setRawEdgeWeights(bool RawWeights)
Definition: CFGPrinter.h:92
DOTFuncInfo(const Function *F, const BlockFrequencyInfo *BFI, const BranchProbabilityInfo *BPI, uint64_t MaxFreq)
Definition: CFGPrinter.h:68
uint64_t getMaxFreq() const
Definition: CFGPrinter.h:82
void setEdgeWeights(bool EdgeWeights)
Definition: CFGPrinter.h:96
DOTFuncInfo(const Function *F)
Definition: CFGPrinter.h:66
uint64_t getFreq(const BasicBlock *BB) const
Definition: CFGPrinter.h:84
const BranchProbabilityInfo * getBPI() const
Definition: CFGPrinter.h:78
bool showEdgeWeights()
Definition: CFGPrinter.h:98
bool showHeatColors()
Definition: CFGPrinter.h:90
bool useRawEdgeWeights()
Definition: CFGPrinter.h:94
const Function * getFunction() const
Definition: CFGPrinter.h:80
const BlockFrequencyInfo * getBFI() const
Definition: CFGPrinter.h:76
void setHeatColors(bool ShowHeat)
Definition: CFGPrinter.h:88
const BasicBlock & getEntryBlock() const
Definition: Function.h:740
iterator begin()
Definition: Function.h:756
size_t size() const
Definition: Function.h:761
iterator end()
Definition: Function.h:758
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:943
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1291
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1297
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:222
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:308
An efficient, type-erasing, non-owning reference to a callable.
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:642
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
MDNode * getBranchWeightMDNode(const Instruction &I)
Get the branch weights metadata node.
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
Definition: Interval.h:99
FunctionPass * createCFGPrinterLegacyPassPass()
Definition: CFGPrinter.cpp:285
std::string SimpleNodeLabelString(const BasicBlockT *Node)
Definition: CFGPrinter.h:124
FunctionPass * createCFGOnlyPrinterLegacyPassPass()
Definition: CFGPrinter.cpp:289
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:136
std::string getEdgeAttributes(const BasicBlock *Node, const_succ_iterator I, DOTFuncInfo *CFGInfo)
Display the raw branch weights from PGO.
Definition: CFGPrinter.h:247
void computeDeoptOrUnreachablePaths(const Function *F)
static std::string getSimpleNodeLabel(const BasicBlock *Node, DOTFuncInfo *)
Definition: CFGPrinter.h:201
static std::string getGraphName(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:197
DenseMap< const BasicBlock *, bool > isOnDeoptOrUnreachablePath
Definition: CFGPrinter.h:188
bool isNodeHidden(const BasicBlock *Node, const DOTFuncInfo *CFGInfo)
DOTGraphTraits(bool isSimple=false)
Definition: CFGPrinter.h:190
std::string getNodeAttributes(const BasicBlock *Node, DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:295
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:192
std::string getNodeLabel(const BasicBlock *Node, DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:215
static std::string getCompleteNodeLabel(const BasicBlock *Node, DOTFuncInfo *, function_ref< void(raw_string_ostream &, const BasicBlock &)> HandleBasicBlock=[](raw_string_ostream &OS, const BasicBlock &Node) -> void { OS<< Node;}, function_ref< void(std::string &, unsigned &, unsigned)> HandleComment=eraseComment)
Definition: CFGPrinter.h:205
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:110
static size_t size(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:118
static NodeRef getEntryNode(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:103
static nodes_iterator nodes_end(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:114
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:371