DomPrinter.cpp revision 309124
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 PostDominatorTreeWrapperPassAnalysisGraphTraits {
115  static PostDominatorTree *getGraph(PostDominatorTreeWrapperPass *PDTWP) {
116    return &PDTWP->getPostDomTree();
117  }
118};
119
120struct PostDomViewer : public DOTGraphTraitsViewer<
121                          PostDominatorTreeWrapperPass, false,
122                          PostDominatorTree *,
123                          PostDominatorTreeWrapperPassAnalysisGraphTraits> {
124  static char ID;
125  PostDomViewer() :
126    DOTGraphTraitsViewer<PostDominatorTreeWrapperPass, false,
127                         PostDominatorTree *,
128                         PostDominatorTreeWrapperPassAnalysisGraphTraits>(
129        "postdom", ID){
130      initializePostDomViewerPass(*PassRegistry::getPassRegistry());
131    }
132};
133
134struct PostDomOnlyViewer : public DOTGraphTraitsViewer<
135                            PostDominatorTreeWrapperPass, true,
136                            PostDominatorTree *,
137                            PostDominatorTreeWrapperPassAnalysisGraphTraits> {
138  static char ID;
139  PostDomOnlyViewer() :
140    DOTGraphTraitsViewer<PostDominatorTreeWrapperPass, true,
141                         PostDominatorTree *,
142                         PostDominatorTreeWrapperPassAnalysisGraphTraits>(
143        "postdomonly", ID){
144      initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry());
145    }
146};
147} // end anonymous namespace
148
149char DomViewer::ID = 0;
150INITIALIZE_PASS(DomViewer, "view-dom",
151                "View dominance tree of function", false, false)
152
153char DomOnlyViewer::ID = 0;
154INITIALIZE_PASS(DomOnlyViewer, "view-dom-only",
155                "View dominance tree of function (with no function bodies)",
156                false, false)
157
158char PostDomViewer::ID = 0;
159INITIALIZE_PASS(PostDomViewer, "view-postdom",
160                "View postdominance tree of function", false, false)
161
162char PostDomOnlyViewer::ID = 0;
163INITIALIZE_PASS(PostDomOnlyViewer, "view-postdom-only",
164                "View postdominance tree of function "
165                "(with no function bodies)",
166                false, false)
167
168namespace {
169struct DomPrinter : public DOTGraphTraitsPrinter<
170                        DominatorTreeWrapperPass, false, DominatorTree *,
171                        DominatorTreeWrapperPassAnalysisGraphTraits> {
172  static char ID;
173  DomPrinter()
174      : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, false, DominatorTree *,
175                              DominatorTreeWrapperPassAnalysisGraphTraits>(
176            "dom", ID) {
177    initializeDomPrinterPass(*PassRegistry::getPassRegistry());
178  }
179};
180
181struct DomOnlyPrinter : public DOTGraphTraitsPrinter<
182                            DominatorTreeWrapperPass, true, DominatorTree *,
183                            DominatorTreeWrapperPassAnalysisGraphTraits> {
184  static char ID;
185  DomOnlyPrinter()
186      : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, true, DominatorTree *,
187                              DominatorTreeWrapperPassAnalysisGraphTraits>(
188            "domonly", ID) {
189    initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
190  }
191};
192
193struct PostDomPrinter
194  : public DOTGraphTraitsPrinter<
195                            PostDominatorTreeWrapperPass, false,
196                            PostDominatorTree *,
197                            PostDominatorTreeWrapperPassAnalysisGraphTraits> {
198  static char ID;
199  PostDomPrinter() :
200    DOTGraphTraitsPrinter<PostDominatorTreeWrapperPass, false,
201                          PostDominatorTree *,
202                          PostDominatorTreeWrapperPassAnalysisGraphTraits>(
203        "postdom", ID) {
204      initializePostDomPrinterPass(*PassRegistry::getPassRegistry());
205    }
206};
207
208struct PostDomOnlyPrinter
209  : public DOTGraphTraitsPrinter<
210                            PostDominatorTreeWrapperPass, true,
211                            PostDominatorTree *,
212                            PostDominatorTreeWrapperPassAnalysisGraphTraits> {
213  static char ID;
214  PostDomOnlyPrinter() :
215    DOTGraphTraitsPrinter<PostDominatorTreeWrapperPass, true,
216                          PostDominatorTree *,
217                          PostDominatorTreeWrapperPassAnalysisGraphTraits>(
218        "postdomonly", ID) {
219      initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
220    }
221};
222} // end anonymous namespace
223
224
225
226char DomPrinter::ID = 0;
227INITIALIZE_PASS(DomPrinter, "dot-dom",
228                "Print dominance tree of function to 'dot' file",
229                false, false)
230
231char DomOnlyPrinter::ID = 0;
232INITIALIZE_PASS(DomOnlyPrinter, "dot-dom-only",
233                "Print dominance tree of function to 'dot' file "
234                "(with no function bodies)",
235                false, false)
236
237char PostDomPrinter::ID = 0;
238INITIALIZE_PASS(PostDomPrinter, "dot-postdom",
239                "Print postdominance tree of function to 'dot' file",
240                false, false)
241
242char PostDomOnlyPrinter::ID = 0;
243INITIALIZE_PASS(PostDomOnlyPrinter, "dot-postdom-only",
244                "Print postdominance tree of function to 'dot' file "
245                "(with no function bodies)",
246                false, false)
247
248// Create methods available outside of this file, to use them
249// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
250// the link time optimization.
251
252FunctionPass *llvm::createDomPrinterPass() {
253  return new DomPrinter();
254}
255
256FunctionPass *llvm::createDomOnlyPrinterPass() {
257  return new DomOnlyPrinter();
258}
259
260FunctionPass *llvm::createDomViewerPass() {
261  return new DomViewer();
262}
263
264FunctionPass *llvm::createDomOnlyViewerPass() {
265  return new DomOnlyViewer();
266}
267
268FunctionPass *llvm::createPostDomPrinterPass() {
269  return new PostDomPrinter();
270}
271
272FunctionPass *llvm::createPostDomOnlyPrinterPass() {
273  return new PostDomOnlyPrinter();
274}
275
276FunctionPass *llvm::createPostDomViewerPass() {
277  return new PostDomViewer();
278}
279
280FunctionPass *llvm::createPostDomOnlyViewerPass() {
281  return new PostDomOnlyViewer();
282}
283