LLVM 20.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 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 OutStr;
149 raw_string_ostream OS(OutStr);
150 HandleBasicBlock(OS, *Node);
151 // Remove "%" from BB name
152 if (OutStr[0] == '%') {
153 OutStr.erase(OutStr.begin());
154 }
155 // Place | after BB name to separate it into header
156 OutStr.insert(OutStr.find_first_of('\n') + 1, "\\|");
157
158 unsigned ColNum = 0;
159 unsigned LastSpace = 0;
160 for (unsigned i = 0; i != OutStr.length(); ++i) {
161 if (OutStr[i] == '\n') { // Left justify
162 OutStr[i] = '\\';
163 OutStr.insert(OutStr.begin() + i + 1, 'l');
164 ColNum = 0;
165 LastSpace = 0;
166 } else if (OutStr[i] == ';') { // Delete comments!
167 unsigned Idx = OutStr.find('\n', i + 1); // Find end of line
168 HandleComment(OutStr, i, Idx);
169 } else if (ColNum == MaxColumns) { // Wrap lines.
170 // Wrap very long names even though we can't find a space.
171 if (!LastSpace)
172 LastSpace = i;
173 OutStr.insert(LastSpace, "\\l...");
174 ColNum = i - LastSpace;
175 LastSpace = 0;
176 i += 3; // The loop will advance 'i' again.
177 } else
178 ++ColNum;
179 if (OutStr[i] == ' ')
180 LastSpace = i;
181 }
182 return OutStr;
183}
184
185template <>
187
188 // Cache for is hidden property
190
192
193 static void eraseComment(std::string &OutStr, unsigned &I, unsigned Idx) {
194 OutStr.erase(OutStr.begin() + I, OutStr.begin() + Idx);
195 --I;
196 }
197
198 static std::string getGraphName(DOTFuncInfo *CFGInfo) {
199 return "CFG for '" + CFGInfo->getFunction()->getName().str() + "' function";
200 }
201
202 static std::string getSimpleNodeLabel(const BasicBlock *Node, DOTFuncInfo *) {
204 }
205
207 // Prepend label name
208 Node.printAsOperand(OS, false);
209 OS << ":\n";
210 for (const Instruction &Inst : Node)
211 OS << Inst << "\n";
212 }
213
214 static std::string getCompleteNodeLabel(
215 const BasicBlock *Node, DOTFuncInfo *,
217 HandleBasicBlock = printBasicBlock,
218 function_ref<void(std::string &, unsigned &, unsigned)>
219 HandleComment = eraseComment) {
220 return CompleteNodeLabelString(Node, HandleBasicBlock, HandleComment);
221 }
222
223 std::string getNodeLabel(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
224
225 if (isSimple())
226 return getSimpleNodeLabel(Node, CFGInfo);
227 else
228 return getCompleteNodeLabel(Node, CFGInfo);
229 }
230
231 static std::string getEdgeSourceLabel(const BasicBlock *Node,
233 // Label source of conditional branches with "T" or "F"
234 if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
235 if (BI->isConditional())
236 return (I == succ_begin(Node)) ? "T" : "F";
237
238 // Label source of switch edges with the associated value.
239 if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
240 unsigned SuccNo = I.getSuccessorIndex();
241
242 if (SuccNo == 0)
243 return "def";
244
245 std::string Str;
248 OS << Case.getCaseValue()->getValue();
249 return Str;
250 }
251 return "";
252 }
253
254 static std::string getBBName(const BasicBlock *Node) {
255 std::string NodeName = Node->getName().str();
256 if (NodeName.empty()) {
257 raw_string_ostream NodeOS(NodeName);
258 Node->printAsOperand(NodeOS, false);
259 // Removing %
260 NodeName.erase(NodeName.begin());
261 }
262 return NodeName;
263 }
264
265 /// Display the raw branch weights from PGO.
267 DOTFuncInfo *CFGInfo) {
268 // If BPI is not provided do not display any edge attributes
269 if (!CFGInfo->showEdgeWeights())
270 return "";
271
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 std::string TTAttr =
279 formatv("tooltip=\"{0} -> {1}\\nProbability {2:P}\" ", getBBName(Node),
280 getBBName(SuccBB), WeightPercent);
281
282 if (TI->getNumSuccessors() == 1)
283 return TTAttr + "penwidth=2";
284
285 if (OpNo >= TI->getNumSuccessors())
286 return TTAttr;
287
288 double Width = 1 + WeightPercent;
289
290 if (!CFGInfo->useRawEdgeWeights())
291 return TTAttr +
292 formatv("label=\"{0:P}\" penwidth={1}", WeightPercent, Width)
293 .str();
294
295 // Prepend a 'W' to indicate that this is a weight rather than the actual
296 // profile count (due to scaling).
297
298 uint64_t Freq = CFGInfo->getFreq(Node);
299 std::string Attrs =
300 TTAttr + formatv("label=\"W:{0}\" penwidth={1}",
301 (uint64_t)(Freq * WeightPercent), Width)
302 .str();
303 if (Attrs.size())
304 return Attrs;
305
306 MDNode *WeightsNode = getBranchWeightMDNode(*TI);
307 if (!WeightsNode)
308 return TTAttr;
309
310 OpNo = I.getSuccessorIndex() + 1;
311 if (OpNo >= WeightsNode->getNumOperands())
312 return TTAttr;
313 ConstantInt *Weight =
314 mdconst::dyn_extract<ConstantInt>(WeightsNode->getOperand(OpNo));
315 if (!Weight)
316 return TTAttr;
317 return (TTAttr + "label=\"W:" + std::to_string(Weight->getZExtValue()) +
318 "\" penwidth=" + std::to_string(Width));
319 }
320
321 std::string getNodeAttributes(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
322
323 if (!CFGInfo->showHeatColors())
324 return "";
325
326 uint64_t Freq = CFGInfo->getFreq(Node);
327 std::string Color = getHeatColor(Freq, CFGInfo->getMaxFreq());
328 std::string EdgeColor = (Freq <= (CFGInfo->getMaxFreq() / 2))
329 ? (getHeatColor(0))
330 : (getHeatColor(1));
331
332 std::string Attrs = "color=\"" + EdgeColor + "ff\", style=filled," +
333 " fillcolor=\"" + Color + "70\"" +
334 " fontname=\"Courier\"";
335 return Attrs;
336 }
337 bool isNodeHidden(const BasicBlock *Node, const DOTFuncInfo *CFGInfo);
339};
340} // End llvm namespace
341
342#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:807
iterator begin()
Definition: Function.h:851
size_t size() const
Definition: Function.h:856
iterator end()
Definition: Function.h:853
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:1069
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1430
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1436
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:215
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(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:266
void computeDeoptOrUnreachablePaths(const Function *F)
static std::string getSimpleNodeLabel(const BasicBlock *Node, DOTFuncInfo *)
Definition: CFGPrinter.h:202
static std::string getGraphName(DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:198
DenseMap< const BasicBlock *, bool > isOnDeoptOrUnreachablePath
Definition: CFGPrinter.h:189
bool isNodeHidden(const BasicBlock *Node, const DOTFuncInfo *CFGInfo)
DOTGraphTraits(bool isSimple=false)
Definition: CFGPrinter.h:191
std::string getNodeAttributes(const BasicBlock *Node, DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:321
static std::string getEdgeSourceLabel(const BasicBlock *Node, const_succ_iterator I)
Definition: CFGPrinter.h:231
static void eraseComment(std::string &OutStr, unsigned &I, unsigned Idx)
Definition: CFGPrinter.h:193
std::string getNodeLabel(const BasicBlock *Node, DOTFuncInfo *CFGInfo)
Definition: CFGPrinter.h:223
static std::string getBBName(const BasicBlock *Node)
Definition: CFGPrinter.h:254
static void printBasicBlock(raw_string_ostream &OS, const BasicBlock &Node)
Definition: CFGPrinter.h:206
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:214
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