DomPrinter.cpp revision 218893
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 DomViewer
85  : public DOTGraphTraitsViewer<DominatorTree, false> {
86  static char ID;
87  DomViewer() : DOTGraphTraitsViewer<DominatorTree, false>("dom", ID){
88    initializeDomViewerPass(*PassRegistry::getPassRegistry());
89  }
90};
91
92struct DomOnlyViewer
93  : public DOTGraphTraitsViewer<DominatorTree, true> {
94  static char ID;
95  DomOnlyViewer() : DOTGraphTraitsViewer<DominatorTree, true>("domonly", ID){
96    initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry());
97  }
98};
99
100struct PostDomViewer
101  : public DOTGraphTraitsViewer<PostDominatorTree, false> {
102  static char ID;
103  PostDomViewer() :
104    DOTGraphTraitsViewer<PostDominatorTree, false>("postdom", ID){
105      initializePostDomViewerPass(*PassRegistry::getPassRegistry());
106    }
107};
108
109struct PostDomOnlyViewer
110  : public DOTGraphTraitsViewer<PostDominatorTree, true> {
111  static char ID;
112  PostDomOnlyViewer() :
113    DOTGraphTraitsViewer<PostDominatorTree, true>("postdomonly", ID){
114      initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry());
115    }
116};
117} // end anonymous namespace
118
119char DomViewer::ID = 0;
120INITIALIZE_PASS(DomViewer, "view-dom",
121                "View dominance tree of function", false, false)
122
123char DomOnlyViewer::ID = 0;
124INITIALIZE_PASS(DomOnlyViewer, "view-dom-only",
125                "View dominance tree of function (with no function bodies)",
126                false, false)
127
128char PostDomViewer::ID = 0;
129INITIALIZE_PASS(PostDomViewer, "view-postdom",
130                "View postdominance tree of function", false, false)
131
132char PostDomOnlyViewer::ID = 0;
133INITIALIZE_PASS(PostDomOnlyViewer, "view-postdom-only",
134                "View postdominance tree of function "
135                "(with no function bodies)",
136                false, false)
137
138namespace {
139struct DomPrinter
140  : public DOTGraphTraitsPrinter<DominatorTree, false> {
141  static char ID;
142  DomPrinter() : DOTGraphTraitsPrinter<DominatorTree, false>("dom", ID) {
143    initializeDomPrinterPass(*PassRegistry::getPassRegistry());
144  }
145};
146
147struct DomOnlyPrinter
148  : public DOTGraphTraitsPrinter<DominatorTree, true> {
149  static char ID;
150  DomOnlyPrinter() : DOTGraphTraitsPrinter<DominatorTree, true>("domonly", ID) {
151    initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
152  }
153};
154
155struct PostDomPrinter
156  : public DOTGraphTraitsPrinter<PostDominatorTree, false> {
157  static char ID;
158  PostDomPrinter() :
159    DOTGraphTraitsPrinter<PostDominatorTree, false>("postdom", ID) {
160      initializePostDomPrinterPass(*PassRegistry::getPassRegistry());
161    }
162};
163
164struct PostDomOnlyPrinter
165  : public DOTGraphTraitsPrinter<PostDominatorTree, true> {
166  static char ID;
167  PostDomOnlyPrinter() :
168    DOTGraphTraitsPrinter<PostDominatorTree, true>("postdomonly", ID) {
169      initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
170    }
171};
172} // end anonymous namespace
173
174
175
176char DomPrinter::ID = 0;
177INITIALIZE_PASS(DomPrinter, "dot-dom",
178                "Print dominance tree of function to 'dot' file",
179                false, false)
180
181char DomOnlyPrinter::ID = 0;
182INITIALIZE_PASS(DomOnlyPrinter, "dot-dom-only",
183                "Print dominance tree of function to 'dot' file "
184                "(with no function bodies)",
185                false, false)
186
187char PostDomPrinter::ID = 0;
188INITIALIZE_PASS(PostDomPrinter, "dot-postdom",
189                "Print postdominance tree of function to 'dot' file",
190                false, false)
191
192char PostDomOnlyPrinter::ID = 0;
193INITIALIZE_PASS(PostDomOnlyPrinter, "dot-postdom-only",
194                "Print postdominance tree of function to 'dot' file "
195                "(with no function bodies)",
196                false, false)
197
198// Create methods available outside of this file, to use them
199// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
200// the link time optimization.
201
202FunctionPass *llvm::createDomPrinterPass() {
203  return new DomPrinter();
204}
205
206FunctionPass *llvm::createDomOnlyPrinterPass() {
207  return new DomOnlyPrinter();
208}
209
210FunctionPass *llvm::createDomViewerPass() {
211  return new DomViewer();
212}
213
214FunctionPass *llvm::createDomOnlyViewerPass() {
215  return new DomOnlyViewer();
216}
217
218FunctionPass *llvm::createPostDomPrinterPass() {
219  return new PostDomPrinter();
220}
221
222FunctionPass *llvm::createPostDomOnlyPrinterPass() {
223  return new PostDomOnlyPrinter();
224}
225
226FunctionPass *llvm::createPostDomViewerPass() {
227  return new PostDomViewer();
228}
229
230FunctionPass *llvm::createPostDomOnlyViewerPass() {
231  return new PostDomOnlyViewer();
232}
233