LLVM  4.0.0
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 
12 #include "llvm/Analysis/Passes.h"
15 #include "llvm/ADT/Statistic.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()
static void viewRegionInfo(RegionInfo *RI, bool ShortNames)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
void Print(const Unit &v, const char *PrintAfter)
Definition: FuzzerUtil.cpp:34
void viewRegion(llvm::RegionInfo *RI)
Open a viewer to display the GraphViz vizualization of the analysis result.
regions
Definition: RegionInfo.cpp:167
static void printRegionCluster(const Region &R, GraphWriter< RegionInfo * > &GW, unsigned depth=0)
bool isSimple() const
Is this a simple region?
void initializeRegionViewerPass(PassRegistry &)
void initializeRegionPrinterPass(PassRegistry &)
std::string getNodeLabel(RegionNode *Node, RegionNode *Graph)
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:100
INITIALIZE_PASS(RegionPrinter,"dot-regions","Print regions of function to 'dot' file", true, true) INITIALIZE_PASS(RegionOnlyPrinter
bool isSubRegion() const
Is this RegionNode a subregion?
Definition: RegionInfo.h:183
RegionT * getTopLevelRegion() const
Definition: RegionInfo.h:838
dot regions only
T * getNodeAs() const
Get the content of this RegionNode.
RegionT * getRegionFor(BlockT *BB) const
Get the smallest region that contains a BasicBlock.
void viewRegionOnly(llvm::RegionInfo *RI)
Open a viewer to display the GraphViz vizualization of the analysis result.
raw_ostream & getOStream()
getOStream - Get the raw output stream into the graph file.
Definition: GraphWriter.h:294
FunctionPass * createRegionOnlyViewerPass()
dot regions Print regions of function to dot true
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:191
static void addCustomGraphFeatures(const RegionInfo *G, GraphWriter< RegionInfo * > &GW)
unsigned getDepth() const
Get the nesting level of this Region.
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:918
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)
#define F(x, y, z)
Definition: MD5.cpp:51
Function Alias Analysis false
void add(Pass *P) override
Add a pass to the queue of passes to run.
FunctionPass * createRegionOnlyPrinterPass()
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:395
LLVM Basic Block Representation.
Definition: BasicBlock.h:51
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 'dot', run gv on the postscript file, then cleanup.
Definition: GraphWriter.h:339
static void invokeFunctionPass(const Function *F, FunctionPass *ViewerPass)
dot regions Print regions of function to dot file(with no function bodies)"
FunctionPassManager manages FunctionPasses and BasicBlockPassManagers.
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to '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 &)
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:188
void initializeRegionOnlyPrinterPass(PassRegistry &)
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 *)
static std::string getGraphName(const GraphType &)
getGraphName - Return the label for the graph as a whole.
std::string getEdgeAttributes(RegionNode *srcNode, GraphTraits< RegionInfo * >::ChildIteratorType CI, RegionInfo *G)