LLVM  9.0.0svn
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 
14 #include "llvm/ADT/Statistic.h"
16 #include "llvm/Analysis/Passes.h"
20 #include "llvm/Support/Debug.h"
22 #ifndef NDEBUG
24 #endif
25 
26 using namespace llvm;
27 
28 //===----------------------------------------------------------------------===//
29 /// onlySimpleRegion - Show only the simple regions in the RegionViewer.
30 static cl::opt<bool>
31 onlySimpleRegions("only-simple-regions",
32  cl::desc("Show only simple regions in the graphviz viewer"),
33  cl::Hidden,
34  cl::init(false));
35 
36 namespace llvm {
37 template<>
39 
40  DOTGraphTraits (bool isSimple=false)
42 
43  std::string getNodeLabel(RegionNode *Node, RegionNode *Graph) {
44 
45  if (!Node->isSubRegion()) {
46  BasicBlock *BB = Node->getNodeAs<BasicBlock>();
47 
48  if (isSimple())
50  ::getSimpleNodeLabel(BB, BB->getParent());
51  else
54  }
55 
56  return "Not implemented";
57  }
58 };
59 
60 template <>
62 
63  DOTGraphTraits (bool isSimple = false)
65 
66  static std::string getGraphName(const RegionInfo *) { return "Region Graph"; }
67 
68  std::string getNodeLabel(RegionNode *Node, RegionInfo *G) {
70  Node, reinterpret_cast<RegionNode *>(G->getTopLevelRegion()));
71  }
72 
73  std::string getEdgeAttributes(RegionNode *srcNode,
75  RegionInfo *G) {
76  RegionNode *destNode = *CI;
77 
78  if (srcNode->isSubRegion() || destNode->isSubRegion())
79  return "";
80 
81  // In case of a backedge, do not use it to define the layout of the nodes.
82  BasicBlock *srcBB = srcNode->getNodeAs<BasicBlock>();
83  BasicBlock *destBB = destNode->getNodeAs<BasicBlock>();
84 
85  Region *R = G->getRegionFor(destBB);
86 
87  while (R && R->getParent())
88  if (R->getParent()->getEntry() == destBB)
89  R = R->getParent();
90  else
91  break;
92 
93  if (R && R->getEntry() == destBB && R->contains(srcBB))
94  return "constraint=false";
95 
96  return "";
97  }
98 
99  // Print the cluster of the subregions. This groups the single basic blocks
100  // and adds a different background color for each group.
102  unsigned depth = 0) {
103  raw_ostream &O = GW.getOStream();
104  O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void*>(&R)
105  << " {\n";
106  O.indent(2 * (depth + 1)) << "label = \"\";\n";
107 
108  if (!onlySimpleRegions || R.isSimple()) {
109  O.indent(2 * (depth + 1)) << "style = filled;\n";
110  O.indent(2 * (depth + 1)) << "color = "
111  << ((R.getDepth() * 2 % 12) + 1) << "\n";
112 
113  } else {
114  O.indent(2 * (depth + 1)) << "style = solid;\n";
115  O.indent(2 * (depth + 1)) << "color = "
116  << ((R.getDepth() * 2 % 12) + 2) << "\n";
117  }
118 
119  for (const auto &RI : R)
120  printRegionCluster(*RI, GW, depth + 1);
121 
122  const RegionInfo &RI = *static_cast<const RegionInfo*>(R.getRegionInfo());
123 
124  for (auto *BB : R.blocks())
125  if (RI.getRegionFor(BB) == &R)
126  O.indent(2 * (depth + 1)) << "Node"
127  << static_cast<const void*>(RI.getTopLevelRegion()->getBBNode(BB))
128  << ";\n";
129 
130  O.indent(2 * depth) << "}\n";
131  }
132 
133  static void addCustomGraphFeatures(const RegionInfo *G,
135  raw_ostream &O = GW.getOStream();
136  O << "\tcolorscheme = \"paired12\"\n";
137  printRegionCluster(*G->getTopLevelRegion(), GW, 4);
138  }
139 };
140 } //end namespace llvm
141 
142 namespace {
143 
144 struct RegionInfoPassGraphTraits {
145  static RegionInfo *getGraph(RegionInfoPass *RIP) {
146  return &RIP->getRegionInfo();
147  }
148 };
149 
150 struct RegionPrinter
151  : public DOTGraphTraitsPrinter<RegionInfoPass, false, RegionInfo *,
152  RegionInfoPassGraphTraits> {
153  static char ID;
154  RegionPrinter()
156  RegionInfoPassGraphTraits>("reg", ID) {
158  }
159 };
160 char RegionPrinter::ID = 0;
161 
162 struct RegionOnlyPrinter
163  : public DOTGraphTraitsPrinter<RegionInfoPass, true, RegionInfo *,
164  RegionInfoPassGraphTraits> {
165  static char ID;
166  RegionOnlyPrinter()
168  RegionInfoPassGraphTraits>("reg", ID) {
170  }
171 };
172 char RegionOnlyPrinter::ID = 0;
173 
174 struct RegionViewer
175  : public DOTGraphTraitsViewer<RegionInfoPass, false, RegionInfo *,
176  RegionInfoPassGraphTraits> {
177  static char ID;
178  RegionViewer()
180  RegionInfoPassGraphTraits>("reg", ID) {
182  }
183 };
184 char RegionViewer::ID = 0;
185 
186 struct RegionOnlyViewer
187  : public DOTGraphTraitsViewer<RegionInfoPass, true, RegionInfo *,
188  RegionInfoPassGraphTraits> {
189  static char ID;
190  RegionOnlyViewer()
192  RegionInfoPassGraphTraits>("regonly", ID) {
194  }
195 };
196 char RegionOnlyViewer::ID = 0;
197 
198 } //end anonymous namespace
199 
200 INITIALIZE_PASS(RegionPrinter, "dot-regions",
201  "Print regions of function to 'dot' file", true, true)
202 
204  RegionOnlyPrinter, "dot-regions-only",
205  "Print regions of function to 'dot' file (with no function bodies)", true,
206  true)
207 
208 INITIALIZE_PASS(RegionViewer, "view-regions", "View regions of function",
209  true, true)
210 
211 INITIALIZE_PASS(RegionOnlyViewer, "view-regions-only",
212  "View regions of function (with no function bodies)",
213  true, true)
214 
215 FunctionPass *llvm::createRegionPrinterPass() { return new RegionPrinter(); }
216 
218  return new RegionOnlyPrinter();
219 }
220 
222  return new RegionViewer();
223 }
224 
226  return new RegionOnlyViewer();
227 }
228 
229 #ifndef NDEBUG
230 static void viewRegionInfo(RegionInfo *RI, bool ShortNames) {
231  assert(RI && "Argument must be non-null");
232 
233  llvm::Function *F = RI->getTopLevelRegion()->getEntry()->getParent();
234  std::string GraphName = DOTGraphTraits<RegionInfo *>::getGraphName(RI);
235 
236  llvm::ViewGraph(RI, "reg", ShortNames,
237  Twine(GraphName) + " for '" + F->getName() + "' function");
238 }
239 
240 static void invokeFunctionPass(const Function *F, FunctionPass *ViewerPass) {
241  assert(F && "Argument must be non-null");
242  assert(!F->isDeclaration() && "Function must have an implementation");
243 
244  // The viewer and analysis passes do not modify anything, so we can safely
245  // remove the const qualifier
246  auto NonConstF = const_cast<Function *>(F);
247 
248  llvm::legacy::FunctionPassManager FPM(NonConstF->getParent());
249  FPM.add(ViewerPass);
250  FPM.doInitialization();
251  FPM.run(*NonConstF);
252  FPM.doFinalization();
253 }
254 
255 void llvm::viewRegion(RegionInfo *RI) { viewRegionInfo(RI, false); }
256 
259 }
260 
262 
265 }
266 #endif
FunctionPass * createRegionViewerPass()
T * getNodeAs() const
Get the content of this RegionNode.
static void viewRegionInfo(RegionInfo *RI, bool ShortNames)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
void viewRegion(llvm::RegionInfo *RI)
Open a viewer to display the GraphViz vizualization of the analysis result.
regions
Definition: RegionInfo.cpp:168
This class represents lattice values for constants.
Definition: AllocatorList.h:23
void initializeRegionViewerPass(PassRegistry &)
void initializeRegionPrinterPass(PassRegistry &)
static void addCustomGraphFeatures(const RegionInfo *G, GraphWriter< RegionInfo *> &GW)
std::string getNodeLabel(RegionNode *Node, RegionNode *Graph)
raw_ostream & indent(unsigned NumSpaces)
indent - Insert &#39;NumSpaces&#39; spaces.
unsigned getDepth() const
Get the nesting level of this Region.
F(f)
dot regions only
bool isSubRegion() const
Is this RegionNode a subregion?
Definition: RegionInfo.h:189
void viewRegionOnly(llvm::RegionInfo *RI)
Open a viewer to display the GraphViz vizualization of the analysis result.
FunctionPass * createRegionOnlyViewerPass()
dot regions Print regions of function to dot true
*ViewGraph Emit a dot run run gv on the postscript *then cleanup For use from the debugger *void ViewGraph(const GraphType &G, const Twine &Name, bool ShortNames=false, const Twine &Title="", GraphProgram::Name Program=GraphProgram::DOT)
Definition: GraphWriter.h:366
std::string getEdgeAttributes(RegionNode *srcNode, GraphTraits< RegionInfo *>::ChildIteratorType CI, RegionInfo *G)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
std::string getNodeLabel(RegionNode *Node, RegionInfo *G)
RegionInfo & getRegionInfo()
Definition: RegionInfo.h:955
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...
static bool isSimple(Instruction *I)
RegionT * getTopLevelRegion() const
Definition: RegionInfo.h:868
void add(Pass *P) override
Add a pass to the queue of passes to run.
FunctionPass * createRegionOnlyPrinterPass()
bool isSimple() const
Is this a simple region?
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:432
LLVM Basic Block Representation.
Definition: BasicBlock.h:57
static void printRegionCluster(const Region &R, GraphWriter< RegionInfo *> &GW, unsigned depth=0)
FunctionPass * createRegionPrinterPass()
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
static void invokeFunctionPass(const Function *F, FunctionPass *ViewerPass)
FunctionPassManager manages FunctionPasses and BasicBlockPassManagers.
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to &#39;dot...
TargetPassConfig.
dot regions Print regions of function to dot true view regions View regions of function(with no function bodies)"
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
void initializeRegionOnlyViewerPass(PassRegistry &)
raw_ostream & getOStream()
getOStream - Get the raw output stream into the graph file.
Definition: GraphWriter.h:303
void initializeRegionOnlyPrinterPass(PassRegistry &)
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:214
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:106
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:227
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static cl::opt< bool > onlySimpleRegions("only-simple-regions", cl::desc("Show only simple regions in the graphviz viewer"), cl::Hidden, cl::init(false))
onlySimpleRegion - Show only the simple regions in the RegionViewer.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
DefaultDOTGraphTraits - This class provides the default implementations of all of the DOTGraphTraits ...
static std::string getGraphName(const RegionInfo *)
RegionT * getRegionFor(BlockT *BB) const
Get the smallest region that contains a BasicBlock.
static std::string getGraphName(const GraphType &)
getGraphName - Return the label for the graph as a whole.
INITIALIZE_PASS(RegionPrinter, "dot-regions", "Print regions of function to 'dot' file", true, true) INITIALIZE_PASS(RegionOnlyPrinter