LLVM  6.0.0svn
RegionPrinter.cpp
Go to the documentation of this file.
1 //===- RegionPrinter.cpp - Print regions tree pass ------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // Print out the region tree of a function using dotty/graphviz.
10 //===----------------------------------------------------------------------===//
11 
15 #include "llvm/ADT/Statistic.h"
17 #include "llvm/Analysis/Passes.h"
21 #include "llvm/Support/Debug.h"
23 #ifndef NDEBUG
25 #endif
26 
27 using namespace llvm;
28 
29 //===----------------------------------------------------------------------===//
30 /// onlySimpleRegion - Show only the simple regions in the RegionViewer.
31 static cl::opt<bool>
32 onlySimpleRegions("only-simple-regions",
33  cl::desc("Show only simple regions in the graphviz viewer"),
34  cl::Hidden,
35  cl::init(false));
36 
37 namespace llvm {
38 template<>
40 
41  DOTGraphTraits (bool isSimple=false)
43 
44  std::string getNodeLabel(RegionNode *Node, RegionNode *Graph) {
45 
46  if (!Node->isSubRegion()) {
47  BasicBlock *BB = Node->getNodeAs<BasicBlock>();
48 
49  if (isSimple())
51  ::getSimpleNodeLabel(BB, BB->getParent());
52  else
55  }
56 
57  return "Not implemented";
58  }
59 };
60 
61 template <>
63 
64  DOTGraphTraits (bool isSimple = false)
66 
67  static std::string getGraphName(const RegionInfo *) { return "Region Graph"; }
68 
69  std::string getNodeLabel(RegionNode *Node, RegionInfo *G) {
71  Node, reinterpret_cast<RegionNode *>(G->getTopLevelRegion()));
72  }
73 
74  std::string getEdgeAttributes(RegionNode *srcNode,
76  RegionInfo *G) {
77  RegionNode *destNode = *CI;
78 
79  if (srcNode->isSubRegion() || destNode->isSubRegion())
80  return "";
81 
82  // In case of a backedge, do not use it to define the layout of the nodes.
83  BasicBlock *srcBB = srcNode->getNodeAs<BasicBlock>();
84  BasicBlock *destBB = destNode->getNodeAs<BasicBlock>();
85 
86  Region *R = G->getRegionFor(destBB);
87 
88  while (R && R->getParent())
89  if (R->getParent()->getEntry() == destBB)
90  R = R->getParent();
91  else
92  break;
93 
94  if (R && R->getEntry() == destBB && R->contains(srcBB))
95  return "constraint=false";
96 
97  return "";
98  }
99 
100  // Print the cluster of the subregions. This groups the single basic blocks
101  // and adds a different background color for each group.
103  unsigned depth = 0) {
104  raw_ostream &O = GW.getOStream();
105  O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void*>(&R)
106  << " {\n";
107  O.indent(2 * (depth + 1)) << "label = \"\";\n";
108 
109  if (!onlySimpleRegions || R.isSimple()) {
110  O.indent(2 * (depth + 1)) << "style = filled;\n";
111  O.indent(2 * (depth + 1)) << "color = "
112  << ((R.getDepth() * 2 % 12) + 1) << "\n";
113 
114  } else {
115  O.indent(2 * (depth + 1)) << "style = solid;\n";
116  O.indent(2 * (depth + 1)) << "color = "
117  << ((R.getDepth() * 2 % 12) + 2) << "\n";
118  }
119 
120  for (const auto &RI : R)
121  printRegionCluster(*RI, GW, depth + 1);
122 
123  const RegionInfo &RI = *static_cast<const RegionInfo*>(R.getRegionInfo());
124 
125  for (auto *BB : R.blocks())
126  if (RI.getRegionFor(BB) == &R)
127  O.indent(2 * (depth + 1)) << "Node"
128  << static_cast<const void*>(RI.getTopLevelRegion()->getBBNode(BB))
129  << ";\n";
130 
131  O.indent(2 * depth) << "}\n";
132  }
133 
134  static void addCustomGraphFeatures(const RegionInfo *G,
136  raw_ostream &O = GW.getOStream();
137  O << "\tcolorscheme = \"paired12\"\n";
138  printRegionCluster(*G->getTopLevelRegion(), GW, 4);
139  }
140 };
141 } //end namespace llvm
142 
143 namespace {
144 
145 struct RegionInfoPassGraphTraits {
146  static RegionInfo *getGraph(RegionInfoPass *RIP) {
147  return &RIP->getRegionInfo();
148  }
149 };
150 
151 struct RegionPrinter
152  : public DOTGraphTraitsPrinter<RegionInfoPass, false, RegionInfo *,
153  RegionInfoPassGraphTraits> {
154  static char ID;
155  RegionPrinter()
157  RegionInfoPassGraphTraits>("reg", ID) {
159  }
160 };
161 char RegionPrinter::ID = 0;
162 
163 struct RegionOnlyPrinter
164  : public DOTGraphTraitsPrinter<RegionInfoPass, true, RegionInfo *,
165  RegionInfoPassGraphTraits> {
166  static char ID;
167  RegionOnlyPrinter()
169  RegionInfoPassGraphTraits>("reg", ID) {
171  }
172 };
173 char RegionOnlyPrinter::ID = 0;
174 
175 struct RegionViewer
176  : public DOTGraphTraitsViewer<RegionInfoPass, false, RegionInfo *,
177  RegionInfoPassGraphTraits> {
178  static char ID;
179  RegionViewer()
181  RegionInfoPassGraphTraits>("reg", ID) {
183  }
184 };
185 char RegionViewer::ID = 0;
186 
187 struct RegionOnlyViewer
188  : public DOTGraphTraitsViewer<RegionInfoPass, true, RegionInfo *,
189  RegionInfoPassGraphTraits> {
190  static char ID;
191  RegionOnlyViewer()
193  RegionInfoPassGraphTraits>("regonly", ID) {
195  }
196 };
197 char RegionOnlyViewer::ID = 0;
198 
199 } //end anonymous namespace
200 
201 INITIALIZE_PASS(RegionPrinter, "dot-regions",
202  "Print regions of function to 'dot' file", true, true)
203 
205  RegionOnlyPrinter, "dot-regions-only",
206  "Print regions of function to 'dot' file (with no function bodies)", true,
207  true)
208 
209 INITIALIZE_PASS(RegionViewer, "view-regions", "View regions of function",
210  true, true)
211 
212 INITIALIZE_PASS(RegionOnlyViewer, "view-regions-only",
213  "View regions of function (with no function bodies)",
214  true, true)
215 
216 FunctionPass *llvm::createRegionPrinterPass() { return new RegionPrinter(); }
217 
219  return new RegionOnlyPrinter();
220 }
221 
223  return new RegionViewer();
224 }
225 
227  return new RegionOnlyViewer();
228 }
229 
230 #ifndef NDEBUG
231 static void viewRegionInfo(RegionInfo *RI, bool ShortNames) {
232  assert(RI && "Argument must be non-null");
233 
234  llvm::Function *F = RI->getTopLevelRegion()->getEntry()->getParent();
235  std::string GraphName = DOTGraphTraits<RegionInfo *>::getGraphName(RI);
236 
237  llvm::ViewGraph(RI, "reg", ShortNames,
238  Twine(GraphName) + " for '" + F->getName() + "' function");
239 }
240 
241 static void invokeFunctionPass(const Function *F, FunctionPass *ViewerPass) {
242  assert(F && "Argument must be non-null");
243  assert(!F->isDeclaration() && "Function must have an implementation");
244 
245  // The viewer and analysis passes do not modify anything, so we can safely
246  // remove the const qualifier
247  auto NonConstF = const_cast<Function *>(F);
248 
249  llvm::legacy::FunctionPassManager FPM(NonConstF->getParent());
250  FPM.add(ViewerPass);
251  FPM.doInitialization();
252  FPM.run(*NonConstF);
253  FPM.doFinalization();
254 }
255 
256 void llvm::viewRegion(RegionInfo *RI) { viewRegionInfo(RI, false); }
257 
260 }
261 
263 
266 }
267 #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
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
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.
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
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:81
std::string getNodeLabel(RegionNode *Node, RegionInfo *G)
RegionInfo & getRegionInfo()
Definition: RegionInfo.h:950
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:863
#define F(x, y, z)
Definition: MD5.cpp:55
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:404
LLVM Basic Block Representation.
Definition: BasicBlock.h:59
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:298
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 &#39;dot&#39;, run gv on the postscript file, then cleanup.
Definition: GraphWriter.h:348
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...
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:206
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:218
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:108
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:200
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:44
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