LLVM 24.0.0git
RegionPrinter.cpp
Go to the documentation of this file.
1//===- RegionPrinter.cpp - Print regions tree pass ------------------------===//
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// Print out the region tree of a function using dotty/graphviz.
9//===----------------------------------------------------------------------===//
10
12#include "AnalysisOptions.h"
18#ifndef NDEBUG
20#endif
21
22using namespace llvm;
23
24std::string
27 if (!Node->isSubRegion()) {
28 BasicBlock *BB = Node->getNodeAs<BasicBlock>();
29
30 if (isSimple())
32 else
34 }
35
36 return "Not implemented";
37}
38
39template <>
42
45
46 static std::string getGraphName(const RegionInfo *) { return "Region Graph"; }
47
50 Node, reinterpret_cast<RegionNode *>(G->getTopLevelRegion()));
51 }
52
53 std::string getEdgeAttributes(RegionNode *srcNode,
55 RegionInfo *G) {
56 RegionNode *destNode = *CI;
57
58 if (srcNode->isSubRegion() || destNode->isSubRegion())
59 return "";
60
61 // In case of a backedge, do not use it to define the layout of the nodes.
62 BasicBlock *srcBB = srcNode->getNodeAs<BasicBlock>();
63 BasicBlock *destBB = destNode->getNodeAs<BasicBlock>();
64
65 Region *R = G->getRegionFor(destBB);
66
67 while (R && R->getParent())
68 if (R->getParent()->getEntry() == destBB)
69 R = R->getParent();
70 else
71 break;
72
73 if (R && R->getEntry() == destBB && R->contains(srcBB))
74 return "constraint=false";
75
76 return "";
77 }
78
79 // Print the cluster of the subregions. This groups the single basic blocks
80 // and adds a different background color for each group.
81 static void printRegionCluster(const AnalysisOptions &Opts, const Region &R,
83 unsigned depth = 0) {
84 raw_ostream &O = GW.getOStream();
85 O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void*>(&R)
86 << " {\n";
87 O.indent(2 * (depth + 1)) << "label = \"\";\n";
88
89 if (!Opts.only_simple_regions || R.isSimple()) {
90 O.indent(2 * (depth + 1)) << "style = filled;\n";
91 O.indent(2 * (depth + 1)) << "color = "
92 << ((R.getDepth() * 2 % 12) + 1) << "\n";
93
94 } else {
95 O.indent(2 * (depth + 1)) << "style = solid;\n";
96 O.indent(2 * (depth + 1)) << "color = "
97 << ((R.getDepth() * 2 % 12) + 2) << "\n";
98 }
99
100 for (const auto &RI : R)
101 printRegionCluster(Opts, *RI, GW, depth + 1);
102
103 const RegionInfo &RI = *static_cast<const RegionInfo*>(R.getRegionInfo());
104
105 for (auto *BB : R.blocks())
106 if (RI.getRegionFor(BB) == &R)
107 O.indent(2 * (depth + 1)) << "Node"
108 << static_cast<const void*>(RI.getTopLevelRegion()->getBBNode(BB))
109 << ";\n";
110
111 O.indent(2 * depth) << "}\n";
112 }
113
116 raw_ostream &O = GW.getOStream();
117 O << "\tcolorscheme = \"paired12\"\n";
118 const Region *TopLevel = G->getTopLevelRegion();
119 printRegionCluster(getAnalysisOptions(*TopLevel->getEntry()->getParent()),
120 *TopLevel, GW, 4);
121 }
122};
123
124namespace {
125
126struct RegionInfoPassGraphTraits {
127 static RegionInfo *getGraph(RegionInfoPass *RIP) {
128 return &RIP->getRegionInfo();
129 }
130};
131
132struct RegionPrinter
133 : public DOTGraphTraitsPrinterWrapperPass<
134 RegionInfoPass, false, RegionInfo *, RegionInfoPassGraphTraits> {
135 static char ID;
136 RegionPrinter()
137 : DOTGraphTraitsPrinterWrapperPass<RegionInfoPass, false, RegionInfo *,
138 RegionInfoPassGraphTraits>("reg", ID) {
139 }
140};
141char RegionPrinter::ID = 0;
142
143struct RegionOnlyPrinter
144 : public DOTGraphTraitsPrinterWrapperPass<
145 RegionInfoPass, true, RegionInfo *, RegionInfoPassGraphTraits> {
146 static char ID;
147 RegionOnlyPrinter()
148 : DOTGraphTraitsPrinterWrapperPass<RegionInfoPass, true, RegionInfo *,
149 RegionInfoPassGraphTraits>("reg", ID) {
150 }
151};
152char RegionOnlyPrinter::ID = 0;
153
154struct RegionViewer
155 : public DOTGraphTraitsViewerWrapperPass<
156 RegionInfoPass, false, RegionInfo *, RegionInfoPassGraphTraits> {
157 static char ID;
158 RegionViewer()
159 : DOTGraphTraitsViewerWrapperPass<RegionInfoPass, false, RegionInfo *,
160 RegionInfoPassGraphTraits>("reg", ID) {}
161};
162char RegionViewer::ID = 0;
163
164struct RegionOnlyViewer
165 : public DOTGraphTraitsViewerWrapperPass<RegionInfoPass, true, RegionInfo *,
166 RegionInfoPassGraphTraits> {
167 static char ID;
168 RegionOnlyViewer()
169 : DOTGraphTraitsViewerWrapperPass<RegionInfoPass, true, RegionInfo *,
170 RegionInfoPassGraphTraits>("regonly",
171 ID) {}
172};
173char RegionOnlyViewer::ID = 0;
174
175} //end anonymous namespace
176
177INITIALIZE_PASS(RegionPrinter, "dot-regions",
178 "Print regions of function to 'dot' file", true, true)
179
181 RegionOnlyPrinter, "dot-regions-only",
182 "Print regions of function to 'dot' file (with no function bodies)", true,
183 true)
184
185INITIALIZE_PASS(RegionViewer, "view-regions", "View regions of function",
186 true, true)
187
188INITIALIZE_PASS(RegionOnlyViewer, "view-regions-only",
189 "View regions of function (with no function bodies)",
190 true, true)
191
192FunctionPass *llvm::createRegionPrinterPass() { return new RegionPrinter(); }
193
195 return new RegionOnlyPrinter();
196}
197
199 return new RegionViewer();
200}
201
203 return new RegionOnlyViewer();
204}
205
206#ifndef NDEBUG
207static void viewRegionInfo(RegionInfo *RI, bool ShortNames) {
208 assert(RI && "Argument must be non-null");
209
210 llvm::Function *F = RI->getTopLevelRegion()->getEntry()->getParent();
211 std::string GraphName = DOTGraphTraits<RegionInfo *>::getGraphName(RI);
212
213 llvm::ViewGraph(RI, "reg", ShortNames,
214 Twine(GraphName) + " for '" + F->getName() + "' function");
215}
216
217static void invokeFunctionPass(const Function *F, FunctionPass *ViewerPass) {
218 assert(F && "Argument must be non-null");
219 assert(!F->isDeclaration() && "Function must have an implementation");
220
221 // The viewer and analysis passes do not modify anything, so we can safely
222 // remove the const qualifier
223 auto NonConstF = const_cast<Function *>(F);
224
225 llvm::legacy::FunctionPassManager FPM(NonConstF->getParent());
226 FPM.add(ViewerPass);
227 FPM.doInitialization();
228 FPM.run(*NonConstF);
229 FPM.doFinalization();
230}
231
233
237
239
243#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Function Alias Analysis false
basic Basic Alias true
#define F(x, y, z)
Definition MD5.cpp:54
#define G(x, y, z)
Definition MD5.cpp:55
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
static void viewRegionInfo(RegionInfo *RI, bool ShortNames)
static void invokeFunctionPass(const Function *F, FunctionPass *ViewerPass)
LLVM Basic Block Representation.
Definition BasicBlock.h:62
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
raw_ostream & getOStream()
getOStream - Get the raw output stream into the graph file.
BlockT * getEntry() const
Get the entry BasicBlock of the Region.
Definition RegionInfo.h:323
RegionT * getTopLevelRegion() const
Definition RegionInfo.h:857
RegionT * getRegionFor(BlockT *BB) const
Get the smallest region that contains a BasicBlock.
RegionInfo & getRegionInfo()
Definition RegionInfo.h:937
bool isSubRegion() const
Is this RegionNode a subregion?
Definition RegionInfo.h:189
BasicBlock * getNodeAs() const
Definition RegionInfo.h:983
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
FunctionPassManager manages FunctionPasses.
bool run(Function &F)
run - Execute all of the passes scheduled for execution.
void add(Pass *P) override
Add a pass to the queue of passes to run.
bool doInitialization()
doInitialization - Run all of the initializers for the function passes.
bool doFinalization()
doFinalization - Run all of the finalizers for the function passes.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
TargetPassConfig.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI FunctionPass * createRegionOnlyViewerPass()
LLVM_ABI FunctionPass * createRegionPrinterPass()
const AnalysisOptions & getAnalysisOptions(const LLVMContext &C)
LLVM_ABI FunctionPass * createRegionOnlyPrinterPass()
void ViewGraph(const GraphType &G, const Twine &Name, bool ShortNames=false, const Twine &Title="", GraphProgram::Name Program=GraphProgram::DOT)
ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file, then cleanup.
LLVM_ABI FunctionPass * createRegionViewerPass()
void viewRegion(llvm::RegionInfo *RI)
Open a viewer to display the GraphViz vizualization of the analysis result.
void viewRegionOnly(llvm::RegionInfo *RI)
Open a viewer to display the GraphViz vizualization of the analysis result.
static void addCustomGraphFeatures(const RegionInfo *G, GraphWriter< RegionInfo * > &GW)
std::string getNodeLabel(RegionNode *Node, RegionInfo *G)
std::string getEdgeAttributes(RegionNode *srcNode, GraphTraits< RegionInfo * >::ChildIteratorType CI, RegionInfo *G)
static void printRegionCluster(const AnalysisOptions &Opts, const Region &R, GraphWriter< RegionInfo * > &GW, unsigned depth=0)
static std::string getGraphName(const RegionInfo *)
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to 'dot...
std::string getNodeLabel(const void *, const GraphType &)
getNodeLabel - Given a node and a pointer to the top level graph, return the label to print in the no...