DomPrinter.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
1//===- DomPrinter.cpp - DOT printer for the dominance trees    ------------===//
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//
10// This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit
11// a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the
12// program, with a graph of the dominance/postdominance tree of that
13// function.
14//
15// There are also passes available to directly call dotty ('-view-dom' or
16// '-view-postdom'). By appending '-only' like '-dot-dom-only' only the
17// names of the bbs are printed, but the content is hidden.
18//
19//===----------------------------------------------------------------------===//
20
21#include "llvm/Analysis/DomPrinter.h"
22#include "llvm/Analysis/DOTGraphTraitsPass.h"
23#include "llvm/Analysis/PostDominators.h"
24
25using namespace llvm;
26
27namespace llvm {
28template<>
29struct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits {
30
31  DOTGraphTraits (bool isSimple=false)
32    : DefaultDOTGraphTraits(isSimple) {}
33
34  std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) {
35
36    BasicBlock *BB = Node->getBlock();
37
38    if (!BB)
39      return "Post dominance root node";
40
41
42    if (isSimple())
43      return DOTGraphTraits<const Function*>
44        ::getSimpleNodeLabel(BB, BB->getParent());
45    else
46      return DOTGraphTraits<const Function*>
47        ::getCompleteNodeLabel(BB, BB->getParent());
48  }
49};
50
51template<>
52struct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> {
53
54  DOTGraphTraits (bool isSimple=false)
55    : DOTGraphTraits<DomTreeNode*>(isSimple) {}
56
57  static std::string getGraphName(DominatorTree *DT) {
58    return "Dominator tree";
59  }
60
61  std::string getNodeLabel(DomTreeNode *Node, DominatorTree *G) {
62    return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
63  }
64};
65
66template<>
67struct DOTGraphTraits<PostDominatorTree*>
68  : public DOTGraphTraits<DomTreeNode*> {
69
70  DOTGraphTraits (bool isSimple=false)
71    : DOTGraphTraits<DomTreeNode*>(isSimple) {}
72
73  static std::string getGraphName(PostDominatorTree *DT) {
74    return "Post dominator tree";
75  }
76
77  std::string getNodeLabel(DomTreeNode *Node, PostDominatorTree *G ) {
78    return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
79  }
80};
81}
82
83namespace {
84struct DominatorTreeWrapperPassAnalysisGraphTraits {
85  static DominatorTree *getGraph(DominatorTreeWrapperPass *DTWP) {
86    return &DTWP->getDomTree();
87  }
88};
89
90struct DomViewer : public DOTGraphTraitsViewer<
91                       DominatorTreeWrapperPass, false, DominatorTree *,
92                       DominatorTreeWrapperPassAnalysisGraphTraits> {
93  static char ID;
94  DomViewer()
95      : DOTGraphTraitsViewer<DominatorTreeWrapperPass, false, DominatorTree *,
96                             DominatorTreeWrapperPassAnalysisGraphTraits>(
97            "dom", ID) {
98    initializeDomViewerPass(*PassRegistry::getPassRegistry());
99  }
100};
101
102struct DomOnlyViewer : public DOTGraphTraitsViewer<
103                           DominatorTreeWrapperPass, true, DominatorTree *,
104                           DominatorTreeWrapperPassAnalysisGraphTraits> {
105  static char ID;
106  DomOnlyViewer()
107      : DOTGraphTraitsViewer<DominatorTreeWrapperPass, true, DominatorTree *,
108                             DominatorTreeWrapperPassAnalysisGraphTraits>(
109            "domonly", ID) {
110    initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry());
111  }
112};
113
114struct PostDomViewer
115  : public DOTGraphTraitsViewer<PostDominatorTree, false> {
116  static char ID;
117  PostDomViewer() :
118    DOTGraphTraitsViewer<PostDominatorTree, false>("postdom", ID){
119      initializePostDomViewerPass(*PassRegistry::getPassRegistry());
120    }
121};
122
123struct PostDomOnlyViewer
124  : public DOTGraphTraitsViewer<PostDominatorTree, true> {
125  static char ID;
126  PostDomOnlyViewer() :
127    DOTGraphTraitsViewer<PostDominatorTree, true>("postdomonly", ID){
128      initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry());
129    }
130};
131} // end anonymous namespace
132
133char DomViewer::ID = 0;
134INITIALIZE_PASS(DomViewer, "view-dom",
135                "View dominance tree of function", false, false)
136
137char DomOnlyViewer::ID = 0;
138INITIALIZE_PASS(DomOnlyViewer, "view-dom-only",
139                "View dominance tree of function (with no function bodies)",
140                false, false)
141
142char PostDomViewer::ID = 0;
143INITIALIZE_PASS(PostDomViewer, "view-postdom",
144                "View postdominance tree of function", false, false)
145
146char PostDomOnlyViewer::ID = 0;
147INITIALIZE_PASS(PostDomOnlyViewer, "view-postdom-only",
148                "View postdominance tree of function "
149                "(with no function bodies)",
150                false, false)
151
152namespace {
153struct DomPrinter : public DOTGraphTraitsPrinter<
154                        DominatorTreeWrapperPass, false, DominatorTree *,
155                        DominatorTreeWrapperPassAnalysisGraphTraits> {
156  static char ID;
157  DomPrinter()
158      : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, false, DominatorTree *,
159                              DominatorTreeWrapperPassAnalysisGraphTraits>(
160            "dom", ID) {
161    initializeDomPrinterPass(*PassRegistry::getPassRegistry());
162  }
163};
164
165struct DomOnlyPrinter : public DOTGraphTraitsPrinter<
166                            DominatorTreeWrapperPass, true, DominatorTree *,
167                            DominatorTreeWrapperPassAnalysisGraphTraits> {
168  static char ID;
169  DomOnlyPrinter()
170      : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, true, DominatorTree *,
171                              DominatorTreeWrapperPassAnalysisGraphTraits>(
172            "domonly", ID) {
173    initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
174  }
175};
176
177struct PostDomPrinter
178  : public DOTGraphTraitsPrinter<PostDominatorTree, false> {
179  static char ID;
180  PostDomPrinter() :
181    DOTGraphTraitsPrinter<PostDominatorTree, false>("postdom", ID) {
182      initializePostDomPrinterPass(*PassRegistry::getPassRegistry());
183    }
184};
185
186struct PostDomOnlyPrinter
187  : public DOTGraphTraitsPrinter<PostDominatorTree, true> {
188  static char ID;
189  PostDomOnlyPrinter() :
190    DOTGraphTraitsPrinter<PostDominatorTree, true>("postdomonly", ID) {
191      initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
192    }
193};
194} // end anonymous namespace
195
196
197
198char DomPrinter::ID = 0;
199INITIALIZE_PASS(DomPrinter, "dot-dom",
200                "Print dominance tree of function to 'dot' file",
201                false, false)
202
203char DomOnlyPrinter::ID = 0;
204INITIALIZE_PASS(DomOnlyPrinter, "dot-dom-only",
205                "Print dominance tree of function to 'dot' file "
206                "(with no function bodies)",
207                false, false)
208
209char PostDomPrinter::ID = 0;
210INITIALIZE_PASS(PostDomPrinter, "dot-postdom",
211                "Print postdominance tree of function to 'dot' file",
212                false, false)
213
214char PostDomOnlyPrinter::ID = 0;
215INITIALIZE_PASS(PostDomOnlyPrinter, "dot-postdom-only",
216                "Print postdominance tree of function to 'dot' file "
217                "(with no function bodies)",
218                false, false)
219
220// Create methods available outside of this file, to use them
221// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
222// the link time optimization.
223
224FunctionPass *llvm::createDomPrinterPass() {
225  return new DomPrinter();
226}
227
228FunctionPass *llvm::createDomOnlyPrinterPass() {
229  return new DomOnlyPrinter();
230}
231
232FunctionPass *llvm::createDomViewerPass() {
233  return new DomViewer();
234}
235
236FunctionPass *llvm::createDomOnlyViewerPass() {
237  return new DomOnlyViewer();
238}
239
240FunctionPass *llvm::createPostDomPrinterPass() {
241  return new PostDomPrinter();
242}
243
244FunctionPass *llvm::createPostDomOnlyPrinterPass() {
245  return new PostDomOnlyPrinter();
246}
247
248FunctionPass *llvm::createPostDomViewerPass() {
249  return new PostDomViewer();
250}
251
252FunctionPass *llvm::createPostDomOnlyViewerPass() {
253  return new PostDomOnlyViewer();
254}
255