LLVM 22.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 PassInfoMixin<CFGViewerPass> {
42public:
44 static bool isRequired() { return true; }
45};
46
47class CFGOnlyViewerPass : public PassInfoMixin<CFGOnlyViewerPass> {
48public:
50 static bool isRequired() { return true; }
51};
52
53class CFGPrinterPass : public PassInfoMixin<CFGPrinterPass> {
54public:
56 static bool isRequired() { return true; }
57};
58
59class CFGOnlyPrinterPass : public PassInfoMixin<CFGOnlyPrinterPass> {
60public:
62 static bool isRequired() { return true; }
63};
64
66private:
67 const Function *F;
68 const BlockFrequencyInfo *BFI;
69 const BranchProbabilityInfo *BPI;
70 std::unique_ptr<ModuleSlotTracker> MSTStorage;
71 uint64_t MaxFreq;
72 bool ShowHeat;
73 bool EdgeWeights;
74 bool RawWeights;
75 using NodeIdFormatterTy =
76 std::function<std::optional<std::string>(const BasicBlock *)>;
77 std::optional<NodeIdFormatterTy> NodeIdFormatter;
78
79public:
80 DOTFuncInfo(const Function *F) : DOTFuncInfo(F, nullptr, nullptr, 0) {}
82
84 DOTFuncInfo(const Function *F, const BlockFrequencyInfo *BFI,
85 const BranchProbabilityInfo *BPI, uint64_t MaxFreq,
86 std::optional<NodeIdFormatterTy> NodeIdFormatter = std::nullopt);
87
88 const BlockFrequencyInfo *getBFI() const { return BFI; }
89
90 const BranchProbabilityInfo *getBPI() const { return BPI; }
91
92 const Function *getFunction() const { return this->F; }
93
95
96 uint64_t getMaxFreq() const { return MaxFreq; }
97
98 uint64_t getFreq(const BasicBlock *BB) const {
99 return BFI->getBlockFreq(BB).getFrequency();
100 }
101
102 void setHeatColors(bool ShowHeat) { this->ShowHeat = ShowHeat; }
103
104 bool showHeatColors() { return ShowHeat; }
105
106 void setRawEdgeWeights(bool RawWeights) { this->RawWeights = RawWeights; }
107
108 bool useRawEdgeWeights() { return RawWeights; }
109
110 void setEdgeWeights(bool EdgeWeights) { this->EdgeWeights = EdgeWeights; }
111
112 bool showEdgeWeights() { return EdgeWeights; }
113
114 std::optional<NodeIdFormatterTy> getNodeIdFormatter() {
115 return NodeIdFormatter;
116 }
117};
118
119template <>
122 return &(CFGInfo->getFunction()->getEntryBlock());
123 }
124
125 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
127
129 return nodes_iterator(CFGInfo->getFunction()->begin());
130 }
131
133 return nodes_iterator(CFGInfo->getFunction()->end());
134 }
135
136 static size_t size(DOTFuncInfo *CFGInfo) {
137 return CFGInfo->getFunction()->size();
138 }
139};
140
141template <typename BasicBlockT>
142std::string SimpleNodeLabelString(const BasicBlockT *Node) {
143 if (!Node->getName().empty())
144 return Node->getName().str();
145
146 std::string Str;
147 raw_string_ostream OS(Str);
148
149 Node->printAsOperand(OS, false);
150 return Str;
151}
152
153template <typename BasicBlockT>
155 const BasicBlockT *Node,
156 function_ref<void(raw_string_ostream &, const BasicBlockT &)>
157 HandleBasicBlock,
158 function_ref<void(std::string &, unsigned &, unsigned)>
159 HandleComment) {
160
161 enum { MaxColumns = 80 };
162 std::string OutStr;
163 raw_string_ostream OS(OutStr);
164 HandleBasicBlock(OS, *Node);
165 // Remove "%" from BB name
166 if (OutStr[0] == '%') {
167 OutStr.erase(OutStr.begin());
168 }
169 // Place | after BB name to separate it into header
170 OutStr.insert(OutStr.find_first_of('\n') + 1, "\\|");
171
172 unsigned ColNum = 0;
173 unsigned LastSpace = 0;
174 for (unsigned i = 0; i != OutStr.length(); ++i) {
175 if (OutStr[i] == '\n') { // Left justify
176 OutStr[i] = '\\';
177 OutStr.insert(OutStr.begin() + i + 1, 'l');
178 ColNum = 0;
179 LastSpace = 0;
180 } else if (OutStr[i] == ';') { // Delete comments!
181 unsigned Idx = OutStr.find('\n', i + 1); // Find end of line
182 HandleComment(OutStr, i, Idx);
183 } else if (ColNum == MaxColumns) { // Wrap lines.
184 // Wrap very long names even though we can't find a space.
185 if (!LastSpace)
186 LastSpace = i;
187 OutStr.insert(LastSpace, "\\l...");
188 ColNum = i - LastSpace;
189 LastSpace = 0;
190 i += 3; // The loop will advance 'i' again.
191 } else
192 ++ColNum;
193 if (OutStr[i] == ' ')
194 LastSpace = i;
195 }
196 return OutStr;
197}
198
199template <>
201
202 // Cache for is hidden property
204
206
207 static void eraseComment(std::string &OutStr, unsigned &I, unsigned Idx) {
208 OutStr.erase(OutStr.begin() + I, OutStr.begin() + Idx);
209 --I;
210 }
211
212 static std::string getGraphName(DOTFuncInfo *CFGInfo) {
213 return "CFG for '" + CFGInfo->getFunction()->getName().str() + "' function";
214 }
215
216 static std::string getSimpleNodeLabel(const BasicBlock *Node, DOTFuncInfo *) {
218 }
219
220 LLVM_ABI static std::string getCompleteNodeLabel(
221 const BasicBlock *Node, DOTFuncInfo *,
223 HandleBasicBlock = {},
224 function_ref<void(std::string &, unsigned &, unsigned)> HandleComment =
225 eraseComment);
226
227 std::string getNodeLabel(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
228
229 if (isSimple())
230 return getSimpleNodeLabel(Node, CFGInfo);
231 else
232 return getCompleteNodeLabel(Node, CFGInfo);
233 }
234
235 static std::string getEdgeSourceLabel(const BasicBlock *Node,
237 // Label source of conditional branches with "T" or "F"
238 if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
239 if (BI->isConditional())
240 return (I == succ_begin(Node)) ? "T" : "F";
241
242 // Label source of switch edges with the associated value.
243 if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
244 unsigned SuccNo = I.getSuccessorIndex();
245
246 if (SuccNo == 0)
247 return "def";
248
249 std::string Str;
250 raw_string_ostream OS(Str);
252 OS << Case.getCaseValue()->getValue();
253 return Str;
254 }
255 return "";
256 }
257
258 static std::string getBBName(const BasicBlock *Node) {
259 std::string NodeName = Node->getName().str();
260 if (NodeName.empty()) {
261 raw_string_ostream NodeOS(NodeName);
262 Node->printAsOperand(NodeOS, false);
263 // Removing %
264 NodeName.erase(NodeName.begin());
265 }
266 return NodeName;
267 }
268
269 /// Display the raw branch weights from PGO.
271 DOTFuncInfo *CFGInfo) {
272 // If BPI is not provided do not display any edge attributes
273 if (!CFGInfo->showEdgeWeights())
274 return "";
275
276 unsigned OpNo = I.getSuccessorIndex();
277 const Instruction *TI = Node->getTerminator();
278 BasicBlock *SuccBB = TI->getSuccessor(OpNo);
279 auto BranchProb = CFGInfo->getBPI()->getEdgeProbability(Node, SuccBB);
280 double WeightPercent = ((double)BranchProb.getNumerator()) /
281 ((double)BranchProb.getDenominator());
282 std::string TTAttr =
283 formatv("tooltip=\"{0} -> {1}\\nProbability {2:P}\" ", getBBName(Node),
284 getBBName(SuccBB), WeightPercent);
285
286 if (TI->getNumSuccessors() == 1)
287 return TTAttr + "penwidth=2";
288
289 if (OpNo >= TI->getNumSuccessors())
290 return TTAttr;
291
292 double Width = 1 + WeightPercent;
293
294 if (!CFGInfo->useRawEdgeWeights())
295 return TTAttr +
296 formatv("label=\"{0:P}\" penwidth={1}", WeightPercent, Width)
297 .str();
298
299 // Prepend a 'W' to indicate that this is a weight rather than the actual
300 // profile count (due to scaling).
301
302 uint64_t Freq = CFGInfo->getFreq(Node);
303 std::string Attrs =
304 TTAttr + formatv("label=\"W:{0}\" penwidth={1}",
305 (uint64_t)(Freq * WeightPercent), Width)
306 .str();
307 if (Attrs.size())
308 return Attrs;
309
310 MDNode *WeightsNode = getBranchWeightMDNode(*TI);
311 if (!WeightsNode)
312 return TTAttr;
313
314 OpNo = I.getSuccessorIndex() + 1;
315 if (OpNo >= WeightsNode->getNumOperands())
316 return TTAttr;
317 ConstantInt *Weight =
319 if (!Weight)
320 return TTAttr;
321 return (TTAttr + "label=\"W:" + std::to_string(Weight->getZExtValue()) +
322 "\" penwidth=" + std::to_string(Width));
323 }
324
325 std::string getNodeAttributes(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
326 std::stringstream Attrs;
327
328 if (auto NodeIdFmt = CFGInfo->getNodeIdFormatter())
329 if (auto NodeId = (*NodeIdFmt)(Node))
330 Attrs << "id=\"" << *NodeId << "\"";
331
332 if (CFGInfo->showHeatColors()) {
333 uint64_t Freq = CFGInfo->getFreq(Node);
334 std::string Color = getHeatColor(Freq, CFGInfo->getMaxFreq());
335 std::string EdgeColor = (Freq <= (CFGInfo->getMaxFreq() / 2))
336 ? (getHeatColor(0))
337 : (getHeatColor(1));
338 if (!Attrs.str().empty())
339 Attrs << ",";
340 Attrs << "color=\"" << EdgeColor << "ff\", style=filled, "
341 << "fillcolor=\"" << Color << "70\", " << "fontname=\"Courier\"";
342 }
343
344 return Attrs.str();
345 }
346
348 const DOTFuncInfo *CFGInfo);
350};
351} // namespace llvm
352
353#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)
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...
Conditional or Unconditional Branch instruction.
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.
static bool isRequired()
Definition CFGPrinter.h:62
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
static bool isRequired()
Definition CFGPrinter.h:50
static bool isRequired()
Definition CFGPrinter.h:56
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
static bool isRequired()
Definition CFGPrinter.h:44
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:106
uint64_t getMaxFreq() const
Definition CFGPrinter.h:96
LLVM_ABI ~DOTFuncInfo()
void setEdgeWeights(bool EdgeWeights)
Definition CFGPrinter.h:110
DOTFuncInfo(const Function *F)
Definition CFGPrinter.h:80
uint64_t getFreq(const BasicBlock *BB) const
Definition CFGPrinter.h:98
std::optional< NodeIdFormatterTy > getNodeIdFormatter()
Definition CFGPrinter.h:114
const BranchProbabilityInfo * getBPI() const
Definition CFGPrinter.h:90
LLVM_ABI ModuleSlotTracker * getModuleSlotTracker()
bool useRawEdgeWeights()
Definition CFGPrinter.h:108
const Function * getFunction() const
Definition CFGPrinter.h:92
const BlockFrequencyInfo * getBFI() const
Definition CFGPrinter.h:88
void setHeatColors(bool ShowHeat)
Definition CFGPrinter.h:102
iterator begin()
Definition Function.h:851
size_t size() const
Definition Function.h:856
iterator end()
Definition Function.h:853
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:1078
const MDOperand & getOperand(unsigned I) const
Definition Metadata.h:1442
unsigned getNumOperands() const
Return number of MDNode operands.
Definition Metadata.h:1448
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
str - Get the contents as an std::string.
Definition StringRef.h:225
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:322
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:695
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:142
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
LLVM_ABI std::string getHeatColor(uint64_t Freq, uint64_t MaxFreq)
Definition HeatUtils.cpp:59
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
SuccIterator< const Instruction, const BasicBlock > const_succ_iterator
Definition CFG.h:245
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:154
std::string getEdgeAttributes(const BasicBlock *Node, const_succ_iterator I, DOTFuncInfo *CFGInfo)
Display the raw branch weights from PGO.
Definition CFGPrinter.h:270
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:216
static std::string getGraphName(DOTFuncInfo *CFGInfo)
Definition CFGPrinter.h:212
DenseMap< const BasicBlock *, bool > isOnDeoptOrUnreachablePath
Definition CFGPrinter.h:203
LLVM_ABI void computeDeoptOrUnreachablePaths(const Function *F)
DOTGraphTraits(bool isSimple=false)
Definition CFGPrinter.h:205
std::string getNodeAttributes(const BasicBlock *Node, DOTFuncInfo *CFGInfo)
Definition CFGPrinter.h:325
static std::string getEdgeSourceLabel(const BasicBlock *Node, const_succ_iterator I)
Definition CFGPrinter.h:235
static void eraseComment(std::string &OutStr, unsigned &I, unsigned Idx)
Definition CFGPrinter.h:207
std::string getNodeLabel(const BasicBlock *Node, DOTFuncInfo *CFGInfo)
Definition CFGPrinter.h:227
static std::string getBBName(const BasicBlock *Node)
Definition CFGPrinter.h:258
DefaultDOTGraphTraits(bool simple=false)
static nodes_iterator nodes_begin(DOTFuncInfo *CFGInfo)
Definition CFGPrinter.h:128
static size_t size(DOTFuncInfo *CFGInfo)
Definition CFGPrinter.h:136
pointer_iterator< Function::const_iterator > nodes_iterator
Definition CFGPrinter.h:126
static NodeRef getEntryNode(DOTFuncInfo *CFGInfo)
Definition CFGPrinter.h:121
static nodes_iterator nodes_end(DOTFuncInfo *CFGInfo)
Definition CFGPrinter.h:132
typename DOTFuncInfo *::UnknownGraphTypeError NodeRef
Definition GraphTraits.h:95
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition PassManager.h:69