LLVM 21.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 {
34class ModuleSlotTracker;
35
36template <class GraphType> struct GraphTraits;
37class CFGViewerPass : public PassInfoMixin<CFGViewerPass> {
38public:
40 static bool isRequired() { return true; }
41};
42
43class CFGOnlyViewerPass : public PassInfoMixin<CFGOnlyViewerPass> {
44public:
46 static bool isRequired() { return true; }
47};
48
49class CFGPrinterPass : public PassInfoMixin<CFGPrinterPass> {
50public:
52 static bool isRequired() { return true; }
53};
54
55class CFGOnlyPrinterPass : public PassInfoMixin<CFGOnlyPrinterPass> {
56public:
58 static bool isRequired() { return true; }
59};
60
62private:
63 const Function *F;
64 const BlockFrequencyInfo *BFI;
65 const BranchProbabilityInfo *BPI;
66 std::unique_ptr<ModuleSlotTracker> MSTStorage;
67 uint64_t MaxFreq;
68 bool ShowHeat;
69 bool EdgeWeights;
70 bool RawWeights;
71
72public:
73 DOTFuncInfo(const Function *F) : DOTFuncInfo(F, nullptr, nullptr, 0) {}
75
76 DOTFuncInfo(const Function *F, const BlockFrequencyInfo *BFI,
77 const BranchProbabilityInfo *BPI, uint64_t MaxFreq);
78
79 const BlockFrequencyInfo *getBFI() const { return BFI; }
80
81 const BranchProbabilityInfo *getBPI() const { return BPI; }
82
83 const Function *getFunction() const { return this->F; }
84
86
87 uint64_t getMaxFreq() const { return MaxFreq; }
88
89 uint64_t getFreq(const BasicBlock *BB) const {
90 return BFI->getBlockFreq(BB).getFrequency();
91 }
92
93 void setHeatColors(bool ShowHeat) { this->ShowHeat = ShowHeat; }
94
95 bool showHeatColors() { return ShowHeat; }
96
97 void setRawEdgeWeights(bool RawWeights) { this->RawWeights = RawWeights; }
98
99 bool useRawEdgeWeights() { return RawWeights; }
100
101 void setEdgeWeights(bool EdgeWeights) { this->EdgeWeights = EdgeWeights; }
102
103 bool showEdgeWeights() { return EdgeWeights; }
104};
105
106template <>
109 return &(CFGInfo->getFunction()->getEntryBlock());
110 }
111
112 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
114
116 return nodes_iterator(CFGInfo->getFunction()->begin());
117 }
118
120 return nodes_iterator(CFGInfo->getFunction()->end());
121 }
122
123 static size_t size(DOTFuncInfo *CFGInfo) {
124 return CFGInfo->getFunction()->size();
125 }
126};
127
128template <typename BasicBlockT>
129std::string SimpleNodeLabelString(const BasicBlockT *Node) {
130 if (!Node->getName().empty())
131 return Node->getName().str();
132
133 std::string Str;
135
136 Node->printAsOperand(OS, false);
137 return Str;
138}
139
140template <typename BasicBlockT>
142 const BasicBlockT *Node,
143 function_ref<void(raw_string_ostream &, const BasicBlockT &)>
144 HandleBasicBlock,
145 function_ref<void(std::string &, unsigned &, unsigned)>
146 HandleComment) {
147
148 enum { MaxColumns = 80 };
149 std::string OutStr;
150 raw_string_ostream OS(OutStr);
151 HandleBasicBlock(OS, *Node);
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
207 static std::string getCompleteNodeLabel(
208 const BasicBlock *Node, DOTFuncInfo *,
210 HandleBasicBlock = {},
211 function_ref<void(std::string &, unsigned &, unsigned)> HandleComment =
212 eraseComment);
213
214 std::string getNodeLabel(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
215
216 if (isSimple())
217 return getSimpleNodeLabel(Node, CFGInfo);
218 else
219 return getCompleteNodeLabel(Node, CFGInfo);
220 }
221
222 static std::string getEdgeSourceLabel(const BasicBlock *Node,
224 // Label source of conditional branches with "T" or "F"
225 if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
226 if (BI->isConditional())
227 return (I == succ_begin(Node)) ? "T" : "F";
228
229 // Label source of switch edges with the associated value.
230 if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
231 unsigned SuccNo = I.getSuccessorIndex();
232
233 if (SuccNo == 0)
234 return "def";
235
236 std::string Str;
239 OS << Case.getCaseValue()->getValue();
240 return Str;
241 }
242 return "";
243 }
244
245 static std::string getBBName(const BasicBlock *Node) {
246 std::string NodeName = Node->getName().str();
247 if (NodeName.empty()) {
248 raw_string_ostream NodeOS(NodeName);
249 Node->printAsOperand(NodeOS, false);
250 // Removing %
251 NodeName.erase(NodeName.begin());
252 }
253 return NodeName;
254 }
255
256 /// Display the raw branch weights from PGO.
258 DOTFuncInfo *CFGInfo) {
259 // If BPI is not provided do not display any edge attributes
260 if (!CFGInfo->showEdgeWeights())
261 return "";
262
263 unsigned OpNo = I.getSuccessorIndex();
264 const Instruction *TI = Node->getTerminator();
265 BasicBlock *SuccBB = TI->getSuccessor(OpNo);
266 auto BranchProb = CFGInfo->getBPI()->getEdgeProbability(Node, SuccBB);
267 double WeightPercent = ((double)BranchProb.getNumerator()) /
268 ((double)BranchProb.getDenominator());
269 std::string TTAttr =
270 formatv("tooltip=\"{0} -> {1}\\nProbability {2:P}\" ", getBBName(Node),
271 getBBName(SuccBB), WeightPercent);
272
273 if (TI->getNumSuccessors() == 1)
274 return TTAttr + "penwidth=2";
275
276 if (OpNo >= TI->getNumSuccessors())
277 return TTAttr;
278
279 double Width = 1 + WeightPercent;
280
281 if (!CFGInfo->useRawEdgeWeights())
282 return TTAttr +
283 formatv("label=\"{0:P}\" penwidth={1}", WeightPercent, Width)
284 .str();
285
286 // Prepend a 'W' to indicate that this is a weight rather than the actual
287 // profile count (due to scaling).
288
289 uint64_t Freq = CFGInfo->getFreq(Node);
290 std::string Attrs =
291 TTAttr + formatv("label=\"W:{0}\" penwidth={1}",
292 (uint64_t)(Freq * WeightPercent), Width)
293 .str();
294 if (Attrs.size())
295 return Attrs;
296
297 MDNode *WeightsNode = getBranchWeightMDNode(*TI);
298 if (!WeightsNode)
299 return TTAttr;
300
301 OpNo = I.getSuccessorIndex() + 1;
302 if (OpNo >= WeightsNode->getNumOperands())
303 return TTAttr;
304 ConstantInt *Weight =
305 mdconst::dyn_extract<ConstantInt>(WeightsNode->getOperand(OpNo));
306 if (!Weight)
307 return TTAttr;
308 return (TTAttr + "label=\"W:" + std::to_string(Weight->getZExtValue()) +
309 "\" penwidth=" + std::to_string(Width));
310 }
311
312 std::string getNodeAttributes(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
313
314 if (!CFGInfo->showHeatColors())
315 return "";
316
317 uint64_t Freq = CFGInfo->getFreq(Node);
318 std::string Color = getHeatColor(Freq, CFGInfo->getMaxFreq());
319 std::string EdgeColor = (Freq <= (CFGInfo->getMaxFreq() / 2))
320 ? (getHeatColor(0))
321 : (getHeatColor(1));
322
323 std::string Attrs = "color=\"" + EdgeColor + "ff\", style=filled," +
324 " fillcolor=\"" + Color + "70\"" +
325 " fontname=\"Courier\"";
326 return Attrs;
327 }
328 bool isNodeHidden(const BasicBlock *Node, const DOTFuncInfo *CFGInfo);
330};
331} // namespace llvm
332
333#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...
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: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:58
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: CFGPrinter.cpp:139
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: CFGPrinter.cpp:119
static bool isRequired()
Definition: CFGPrinter.h:46
static bool isRequired()
Definition: CFGPrinter.h:52
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: CFGPrinter.cpp:129
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: CFGPrinter.cpp:110
static bool isRequired()
Definition: CFGPrinter.h:40
This is the shared class of boolean and integer constants.
Definition: Constants.h:83
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:157
void setRawEdgeWeights(bool RawWeights)
Definition: CFGPrinter.h:97
uint64_t getMaxFreq() const
Definition: CFGPrinter.h:87
void setEdgeWeights(bool EdgeWeights)
Definition: CFGPrinter.h:101
DOTFuncInfo(const Function *F)
Definition: CFGPrinter.h:73
uint64_t getFreq(const BasicBlock *BB) const
Definition: CFGPrinter.h:89
const BranchProbabilityInfo * getBPI() const
Definition: CFGPrinter.h:81
bool showEdgeWeights()
Definition: CFGPrinter.h:103
bool showHeatColors()
Definition: CFGPrinter.h:95
ModuleSlotTracker * getModuleSlotTracker()
Definition: CFGPrinter.cpp:104
bool useRawEdgeWeights()
Definition: CFGPrinter.h:99
const Function * getFunction() const
Definition: CFGPrinter.h:83
const BlockFrequencyInfo * getBFI() const
Definition: CFGPrinter.h:79
void setHeatColors(bool ShowHeat)
Definition: CFGPrinter.h:93
const BasicBlock & getEntryBlock() const
Definition: Function.h:815
iterator begin()
Definition: Function.h:859
size_t size() const
Definition: Function.h:864
iterator end()
Definition: Function.h:861
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:1073
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1434
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1440
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:111
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:229
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
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(bool Validate, const char *Fmt, Ts &&...Vals)
std::string SimpleNodeLabelString(const BasicBlockT *Node)
Definition: CFGPrinter.h:129
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:141
std::string getEdgeAttributes(const BasicBlock *Node, const_succ_iterator I, DOTFuncInfo *CFGInfo)
Display the raw branch weights from PGO.
Definition: CFGPrinter.h:257
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
static 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)
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:312
static std::string getEdgeSourceLabel(const BasicBlock *Node, const_succ_iterator I)
Definition: CFGPrinter.h:222
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:214
static std::string getBBName(const BasicBlock *Node)
Definition: CFGPrinter.h:245
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:115
static size_t size(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:123
static NodeRef getEntryNode(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:108
static nodes_iterator nodes_end(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:119
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:69