1 //===- RegionPrinter.cpp - Print regions tree pass ------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
9 // Print out the region tree of a function using dotty/graphviz.
10 //===----------------------------------------------------------------------===//
12 #include "llvm/Analysis/RegionInfo.h"
13 #include "llvm/Analysis/RegionIterator.h"
14 #include "llvm/Analysis/RegionPrinter.h"
15 #include "llvm/Analysis/Passes.h"
16 #include "llvm/Analysis/DOTGraphTraitsPass.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/ADT/PostOrderIterator.h"
19 #include "llvm/ADT/DepthFirstIterator.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/CommandLine.h"
22 #include "llvm/Support/raw_ostream.h"
26 //===----------------------------------------------------------------------===//
27 /// onlySimpleRegion - Show only the simple regions in the RegionViewer.
29 onlySimpleRegions("only-simple-regions",
30 cl::desc("Show only simple regions in the graphviz viewer"),
36 struct DOTGraphTraits
<RegionNode
*> : public DefaultDOTGraphTraits
{
38 DOTGraphTraits (bool isSimple
=false)
39 : DefaultDOTGraphTraits(isSimple
) {}
41 std::string
getNodeLabel(RegionNode
*Node
, RegionNode
*Graph
) {
43 if (!Node
->isSubRegion()) {
44 BasicBlock
*BB
= Node
->getNodeAs
<BasicBlock
>();
47 return DOTGraphTraits
<const Function
*>
48 ::getSimpleNodeLabel(BB
, BB
->getParent());
50 return DOTGraphTraits
<const Function
*>
51 ::getCompleteNodeLabel(BB
, BB
->getParent());
54 return "Not implemented";
59 struct DOTGraphTraits
<RegionInfo
*> : public DOTGraphTraits
<RegionNode
*> {
61 DOTGraphTraits (bool isSimple
=false)
62 : DOTGraphTraits
<RegionNode
*>(isSimple
) {}
64 static std::string
getGraphName(RegionInfo
*DT
) {
65 return "Region Graph";
68 std::string
getNodeLabel(RegionNode
*Node
, RegionInfo
*G
) {
69 return DOTGraphTraits
<RegionNode
*>::getNodeLabel(Node
,
70 G
->getTopLevelRegion());
73 // Print the cluster of the subregions. This groups the single basic blocks
74 // and adds a different background color for each group.
75 static void printRegionCluster(const Region
*R
, GraphWriter
<RegionInfo
*> &GW
,
77 raw_ostream
&O
= GW
.getOStream();
78 O
.indent(2 * depth
) << "subgraph cluster_" << static_cast<const void*>(R
)
80 O
.indent(2 * (depth
+ 1)) << "label = \"\";\n";
82 if (!onlySimpleRegions
|| R
->isSimple()) {
83 O
.indent(2 * (depth
+ 1)) << "style = filled;\n";
84 O
.indent(2 * (depth
+ 1)) << "color = "
85 << ((R
->getDepth() * 2 % 12) + 1) << "\n";
88 O
.indent(2 * (depth
+ 1)) << "style = solid;\n";
89 O
.indent(2 * (depth
+ 1)) << "color = "
90 << ((R
->getDepth() * 2 % 12) + 2) << "\n";
93 for (Region::const_iterator RI
= R
->begin(), RE
= R
->end(); RI
!= RE
; ++RI
)
94 printRegionCluster(*RI
, GW
, depth
+ 1);
96 RegionInfo
*RI
= R
->getRegionInfo();
98 for (Region::const_block_iterator BI
= R
->block_begin(),
99 BE
= R
->block_end(); BI
!= BE
; ++BI
) {
100 BasicBlock
*BB
= (*BI
)->getNodeAs
<BasicBlock
>();
101 if (RI
->getRegionFor(BB
) == R
)
102 O
.indent(2 * (depth
+ 1)) << "Node"
103 << static_cast<const void*>(RI
->getTopLevelRegion()->getBBNode(BB
))
107 O
.indent(2 * depth
) << "}\n";
110 static void addCustomGraphFeatures(const RegionInfo
* RI
,
111 GraphWriter
<RegionInfo
*> &GW
) {
112 raw_ostream
&O
= GW
.getOStream();
113 O
<< "\tcolorscheme = \"paired12\"\n";
114 printRegionCluster(RI
->getTopLevelRegion(), GW
, 4);
117 } //end namespace llvm
122 : public DOTGraphTraitsViewer
<RegionInfo
, false> {
124 RegionViewer() : DOTGraphTraitsViewer
<RegionInfo
, false>("reg", ID
){
125 initializeRegionViewerPass(*PassRegistry::getPassRegistry());
128 char RegionViewer::ID
= 0;
130 struct RegionOnlyViewer
131 : public DOTGraphTraitsViewer
<RegionInfo
, true> {
133 RegionOnlyViewer() : DOTGraphTraitsViewer
<RegionInfo
, true>("regonly", ID
) {
134 initializeRegionOnlyViewerPass(*PassRegistry::getPassRegistry());
137 char RegionOnlyViewer::ID
= 0;
140 : public DOTGraphTraitsPrinter
<RegionInfo
, false> {
143 DOTGraphTraitsPrinter
<RegionInfo
, false>("reg", ID
) {
144 initializeRegionPrinterPass(*PassRegistry::getPassRegistry());
147 char RegionPrinter::ID
= 0;
148 } //end anonymous namespace
150 INITIALIZE_PASS(RegionPrinter
, "dot-regions",
151 "Print regions of function to 'dot' file", true, true)
153 INITIALIZE_PASS(RegionViewer
, "view-regions", "View regions of function",
156 INITIALIZE_PASS(RegionOnlyViewer
, "view-regions-only",
157 "View regions of function (with no function bodies)",
162 struct RegionOnlyPrinter
163 : public DOTGraphTraitsPrinter
<RegionInfo
, true> {
165 RegionOnlyPrinter() :
166 DOTGraphTraitsPrinter
<RegionInfo
, true>("reg", ID
) {
167 initializeRegionOnlyPrinterPass(*PassRegistry::getPassRegistry());
173 char RegionOnlyPrinter::ID
= 0;
174 INITIALIZE_PASS(RegionOnlyPrinter
, "dot-regions-only",
175 "Print regions of function to 'dot' file "
176 "(with no function bodies)",
179 FunctionPass
* llvm::createRegionViewerPass() {
180 return new RegionViewer();
183 FunctionPass
* llvm::createRegionOnlyViewerPass() {
184 return new RegionOnlyViewer();
187 FunctionPass
* llvm::createRegionPrinterPass() {
188 return new RegionPrinter();
191 FunctionPass
* llvm::createRegionOnlyPrinterPass() {
192 return new RegionOnlyPrinter();