LLVM 23.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"
33
34#include <functional>
35#include <sstream>
36
37namespace llvm {
39
40template <class GraphType> struct GraphTraits;
41class CFGViewerPass : public RequiredPassInfoMixin<CFGViewerPass> {
42public:
44};
45
46class CFGOnlyViewerPass : public RequiredPassInfoMixin<CFGOnlyViewerPass> {
47public:
49};
50
51class CFGPrinterPass : public RequiredPassInfoMixin<CFGPrinterPass> {
52public:
54};
55
56class CFGOnlyPrinterPass : public RequiredPassInfoMixin<CFGOnlyPrinterPass> {
57public:
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 using NodeIdFormatterTy =
72 std::function<std::optional<std::string>(const BasicBlock *)>;
73 std::optional<NodeIdFormatterTy> NodeIdFormatter;
74
75public:
76 DOTFuncInfo(const Function *F) : DOTFuncInfo(F, nullptr, nullptr, 0) {}
78
80 DOTFuncInfo(const Function *F, const BlockFrequencyInfo *BFI,
81 const BranchProbabilityInfo *BPI, uint64_t MaxFreq,
82 std::optional<NodeIdFormatterTy> NodeIdFormatter = std::nullopt);
83
84 const BlockFrequencyInfo *getBFI() const { return BFI; }
85
86 const BranchProbabilityInfo *getBPI() const { return BPI; }
87
88 const Function *getFunction() const { return this->F; }
89
91
92 uint64_t getMaxFreq() const { return MaxFreq; }
93
94 uint64_t getFreq(const BasicBlock *BB) const {
95 return BFI->getBlockFreq(BB).getFrequency();
96 }
97
98 void setHeatColors(bool ShowHeat) { this->ShowHeat = ShowHeat; }
99
100 bool showHeatColors() { return ShowHeat; }
101
102 void setRawEdgeWeights(bool RawWeights) { this->RawWeights = RawWeights; }
103
104 bool useRawEdgeWeights() { return RawWeights; }
105
106 void setEdgeWeights(bool EdgeWeights) { this->EdgeWeights = EdgeWeights; }
107
108 bool showEdgeWeights() { return EdgeWeights; }
109
110 std::optional<NodeIdFormatterTy> getNodeIdFormatter() {
111 return NodeIdFormatter;
112 }
113};
114
115template <>
118 return &(CFGInfo->getFunction()->getEntryBlock());
119 }
120
121 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
123
125 return nodes_iterator(CFGInfo->getFunction()->begin());
126 }
127
129 return nodes_iterator(CFGInfo->getFunction()->end());
130 }
131
132 static size_t size(DOTFuncInfo *CFGInfo) {
133 return CFGInfo->getFunction()->size();
134 }
135};
136
137template <typename BasicBlockT>
138std::string SimpleNodeLabelString(const BasicBlockT *Node) {
139 if (!Node->getName().empty())
140 return Node->getName().str();
141
142 std::string Str;
143 raw_string_ostream OS(Str);
144
145 Node->printAsOperand(OS, false);
146 return Str;
147}
148
149template <typename BasicBlockT>
151 const BasicBlockT *Node,
152 function_ref<void(raw_string_ostream &, const BasicBlockT &)>
153 HandleBasicBlock,
154 function_ref<void(std::string &, unsigned &, unsigned)>
155 HandleComment) {
156
157 enum { MaxColumns = 80 };
158 std::string OutStr;
159 raw_string_ostream OS(OutStr);
160 HandleBasicBlock(OS, *Node);
161 // Remove "%" from BB name
162 if (OutStr[0] == '%') {
163 OutStr.erase(OutStr.begin());
164 }
165 // Place | after BB name to separate it into header
166 OutStr.insert(OutStr.find_first_of('\n') + 1, "\\|");
167
168 unsigned ColNum = 0;
169 unsigned LastSpace = 0;
170 for (unsigned i = 0; i != OutStr.length(); ++i) {
171 if (OutStr[i] == '\n') { // Left justify
172 OutStr[i] = '\\';
173 OutStr.insert(OutStr.begin() + i + 1, 'l');
174 ColNum = 0;
175 LastSpace = 0;
176 } else if (OutStr[i] == ';') { // Delete comments!
177 unsigned Idx = OutStr.find('\n', i + 1); // Find end of line
178 HandleComment(OutStr, i, Idx);
179 } else if (ColNum == MaxColumns) { // Wrap lines.
180 // Wrap very long names even though we can't find a space.
181 if (!LastSpace)
182 LastSpace = i;
183 OutStr.insert(LastSpace, "\\l...");
184 ColNum = i - LastSpace;
185 LastSpace = 0;
186 i += 3; // The loop will advance 'i' again.
187 } else
188 ++ColNum;
189 if (OutStr[i] == ' ')
190 LastSpace = i;
191 }
192 return OutStr;
193}
194
195template <>
197
198 // Cache for is hidden property
200
202
203 static void eraseComment(std::string &OutStr, unsigned &I, unsigned Idx) {
204 OutStr.erase(OutStr.begin() + I, OutStr.begin() + Idx);
205 --I;
206 }
207
208 static std::string getGraphName(DOTFuncInfo *CFGInfo) {
209 return "CFG for '" + CFGInfo->getFunction()->getName().str() + "' function";
210 }
211
212 static std::string getSimpleNodeLabel(const BasicBlock *Node, DOTFuncInfo *) {
214 }
215
216 LLVM_ABI static std::string getCompleteNodeLabel(
217 const BasicBlock *Node, DOTFuncInfo *,
219 HandleBasicBlock = {},
220 function_ref<void(std::string &, unsigned &, unsigned)> HandleComment =
221 eraseComment);
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 (isa<CondBrInst>(Node->getTerminator()))
235 return (I == succ_begin(Node)) ? "T" : "F";
236
237 // Label source of switch edges with the associated value.
238 if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
239 unsigned SuccNo = std::distance(succ_begin(SI), I);
240
241 if (SuccNo == 0)
242 return "def";
243
244 std::string Str;
245 raw_string_ostream OS(Str);
247 OS << Case.getCaseValue()->getValue();
248 return Str;
249 }
250 return "";
251 }
252
253 static std::string getBBName(const BasicBlock *Node) {
254 std::string NodeName = Node->getName().str();
255 if (NodeName.empty()) {
256 raw_string_ostream NodeOS(NodeName);
257 Node->printAsOperand(NodeOS, false);
258 // Removing %
259 NodeName.erase(NodeName.begin());
260 }
261 return NodeName;
262 }
263
264 /// Display the raw branch weights from PGO.
266 DOTFuncInfo *CFGInfo) {
267 // If BPI is not provided do not display any edge attributes
268 if (!CFGInfo->showEdgeWeights())
269 return "";
270
271 const Instruction *TI = Node->getTerminator();
272 unsigned OpNo = std::distance(succ_begin(TI), I);
273 BasicBlock *SuccBB = TI->getSuccessor(OpNo);
274 auto BranchProb = CFGInfo->getBPI()->getEdgeProbability(Node, SuccBB);
275 double WeightPercent = ((double)BranchProb.getNumerator()) /
276 ((double)BranchProb.getDenominator());
277 std::string TTAttr =
278 formatv("tooltip=\"{0} -> {1}\\nProbability {2:P}\" ", getBBName(Node),
279 getBBName(SuccBB), WeightPercent);
280
281 if (TI->getNumSuccessors() == 1)
282 return TTAttr + "penwidth=2";
283
284 if (OpNo >= TI->getNumSuccessors())
285 return TTAttr;
286
287 double Width = 1 + WeightPercent;
288
289 if (!CFGInfo->useRawEdgeWeights())
290 return TTAttr +
291 formatv("label=\"{0:P}\" penwidth={1}", WeightPercent, Width)
292 .str();
293
294 // Prepend a 'W' to indicate that this is a weight rather than the actual
295 // profile count (due to scaling).
296
297 uint64_t Freq = CFGInfo->getFreq(Node);
298 std::string Attrs =
299 TTAttr + formatv("label=\"W:{0}\" penwidth={1}",
300 (uint64_t)(Freq * WeightPercent), Width)
301 .str();
302 if (Attrs.size())
303 return Attrs;
304
305 MDNode *WeightsNode = getBranchWeightMDNode(*TI);
306 if (!WeightsNode)
307 return TTAttr;
308
309 OpNo += 1;
310 if (OpNo >= WeightsNode->getNumOperands())
311 return TTAttr;
312 ConstantInt *Weight =
314 if (!Weight)
315 return TTAttr;
316 return (TTAttr + "label=\"W:" + std::to_string(Weight->getZExtValue()) +
317 "\" penwidth=" + std::to_string(Width));
318 }
319
320 std::string getNodeAttributes(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
321 std::stringstream Attrs;
322
323 if (auto NodeIdFmt = CFGInfo->getNodeIdFormatter())
324 if (auto NodeId = (*NodeIdFmt)(Node))
325 Attrs << "id=\"" << *NodeId << "\"";
326
327 if (CFGInfo->showHeatColors()) {
328 uint64_t Freq = CFGInfo->getFreq(Node);
329 std::string Color = getHeatColor(Freq, CFGInfo->getMaxFreq());
330 std::string EdgeColor = (Freq <= (CFGInfo->getMaxFreq() / 2))
331 ? (getHeatColor(0))
332 : (getHeatColor(1));
333 if (!Attrs.str().empty())
334 Attrs << ",";
335 Attrs << "color=\"" << EdgeColor << "ff\", style=filled, "
336 << "fillcolor=\"" << Color << "70\", " << "fontname=\"Courier\"";
337 }
338
339 return Attrs.str();
340 }
341
343 const DOTFuncInfo *CFGInfo);
345};
346} // namespace llvm
347
348#endif
#define LLVM_ABI
Definition Compiler.h:213
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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:54
#define I(x, y, z)
Definition MD5.cpp:57
This file contains the declarations for profiling metadata utility functions.
static bool isSimple(Instruction *I)
static std::string getBBName(const MachineBasicBlock *MBB)
void printAsOperand(OutputBuffer &OB, Prec P=Prec::Default, bool StrictlyWorse=false) const
LLVM Basic Block Representation.
Definition BasicBlock.h:62
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Analysis providing branch probability information.
LLVM_ABI BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
This is the shared class of boolean and integer constants.
Definition Constants.h:87
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:168
void setRawEdgeWeights(bool RawWeights)
Definition CFGPrinter.h:102
uint64_t getMaxFreq() const
Definition CFGPrinter.h:92
LLVM_ABI ~DOTFuncInfo()
void setEdgeWeights(bool EdgeWeights)
Definition CFGPrinter.h:106
DOTFuncInfo(const Function *F)
Definition CFGPrinter.h:76
uint64_t getFreq(const BasicBlock *BB) const
Definition CFGPrinter.h:94
std::optional< NodeIdFormatterTy > getNodeIdFormatter()
Definition CFGPrinter.h:110
const BranchProbabilityInfo * getBPI() const
Definition CFGPrinter.h:86
LLVM_ABI ModuleSlotTracker * getModuleSlotTracker()
bool useRawEdgeWeights()
Definition CFGPrinter.h:104
const Function * getFunction() const
Definition CFGPrinter.h:88
const BlockFrequencyInfo * getBFI() const
Definition CFGPrinter.h:84
void setHeatColors(bool ShowHeat)
Definition CFGPrinter.h:98
iterator begin()
Definition Function.h:853
size_t size() const
Definition Function.h:858
iterator end()
Definition Function.h:855
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
Metadata node.
Definition Metadata.h:1080
const MDOperand & getOperand(unsigned I) const
Definition Metadata.h:1444
unsigned getNumOperands() const
Return number of MDNode operands.
Definition Metadata.h:1450
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:112
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
static CaseIteratorImpl fromSuccessorIndex(SwitchInstT *SI, unsigned SuccessorIndex)
Multiway switch.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:318
An efficient, type-erasing, non-owning reference to a callable.
A raw_ostream that writes to an std::string.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract(Y &&MD)
Extract a Value from Metadata, if any.
Definition Metadata.h:696
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI 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:138
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
LLVM_ABI std::string getHeatColor(uint64_t Freq, uint64_t MaxFreq)
Definition HeatUtils.cpp:59
Instruction::const_succ_iterator const_succ_iterator
Definition CFG.h:139
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
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:150
std::string getEdgeAttributes(const BasicBlock *Node, const_succ_iterator I, DOTFuncInfo *CFGInfo)
Display the raw branch weights from PGO.
Definition CFGPrinter.h:265
static LLVM_ABI 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)
LLVM_ABI bool isNodeHidden(const BasicBlock *Node, const DOTFuncInfo *CFGInfo)
static std::string getSimpleNodeLabel(const BasicBlock *Node, DOTFuncInfo *)
Definition CFGPrinter.h:212
static std::string getGraphName(DOTFuncInfo *CFGInfo)
Definition CFGPrinter.h:208
DenseMap< const BasicBlock *, bool > isOnDeoptOrUnreachablePath
Definition CFGPrinter.h:199
LLVM_ABI void computeDeoptOrUnreachablePaths(const Function *F)
DOTGraphTraits(bool isSimple=false)
Definition CFGPrinter.h:201
std::string getNodeAttributes(const BasicBlock *Node, DOTFuncInfo *CFGInfo)
Definition CFGPrinter.h:320
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:203
std::string getNodeLabel(const BasicBlock *Node, DOTFuncInfo *CFGInfo)
Definition CFGPrinter.h:223
static std::string getBBName(const BasicBlock *Node)
Definition CFGPrinter.h:253
DefaultDOTGraphTraits(bool simple=false)
static nodes_iterator nodes_begin(DOTFuncInfo *CFGInfo)
Definition CFGPrinter.h:124
static size_t size(DOTFuncInfo *CFGInfo)
Definition CFGPrinter.h:132
pointer_iterator< Function::const_iterator > nodes_iterator
Definition CFGPrinter.h:122
static NodeRef getEntryNode(DOTFuncInfo *CFGInfo)
Definition CFGPrinter.h:117
static nodes_iterator nodes_end(DOTFuncInfo *CFGInfo)
Definition CFGPrinter.h:128
typename DOTFuncInfo *::UnknownGraphTypeError NodeRef
Definition GraphTraits.h:95
A CRTP mix-in for passes that should not be skipped.