Line data Source code
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 :
25 : using namespace llvm;
26 :
27 : namespace llvm {
28 : template<>
29 : struct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits {
30 :
31 : DOTGraphTraits (bool isSimple=false)
32 : : DefaultDOTGraphTraits(isSimple) {}
33 :
34 0 : std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) {
35 :
36 0 : BasicBlock *BB = Node->getBlock();
37 :
38 0 : if (!BB)
39 0 : return "Post dominance root node";
40 :
41 :
42 0 : if (isSimple())
43 : return DOTGraphTraits<const Function*>
44 0 : ::getSimpleNodeLabel(BB, BB->getParent());
45 : else
46 : return DOTGraphTraits<const Function*>
47 0 : ::getCompleteNodeLabel(BB, BB->getParent());
48 : }
49 : };
50 :
51 : template<>
52 : struct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> {
53 :
54 : DOTGraphTraits (bool isSimple=false)
55 : : DOTGraphTraits<DomTreeNode*>(isSimple) {}
56 :
57 0 : static std::string getGraphName(DominatorTree *DT) {
58 0 : return "Dominator tree";
59 : }
60 :
61 0 : std::string getNodeLabel(DomTreeNode *Node, DominatorTree *G) {
62 0 : return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
63 : }
64 : };
65 :
66 : template<>
67 : struct DOTGraphTraits<PostDominatorTree*>
68 : : public DOTGraphTraits<DomTreeNode*> {
69 :
70 : DOTGraphTraits (bool isSimple=false)
71 : : DOTGraphTraits<DomTreeNode*>(isSimple) {}
72 :
73 0 : static std::string getGraphName(PostDominatorTree *DT) {
74 0 : return "Post dominator tree";
75 : }
76 :
77 0 : std::string getNodeLabel(DomTreeNode *Node, PostDominatorTree *G ) {
78 0 : return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
79 : }
80 : };
81 : }
82 :
83 0 : void DominatorTree::viewGraph(const Twine &Name, const Twine &Title) {
84 : #ifndef NDEBUG
85 : ViewGraph(this, Name, false, Title);
86 : #else
87 0 : errs() << "DomTree dump not available, build with DEBUG\n";
88 : #endif // NDEBUG
89 0 : }
90 :
91 0 : void DominatorTree::viewGraph() {
92 : #ifndef NDEBUG
93 : this->viewGraph("domtree", "Dominator Tree for function");
94 : #else
95 0 : errs() << "DomTree dump not available, build with DEBUG\n";
96 : #endif // NDEBUG
97 0 : }
98 :
99 : namespace {
100 : struct DominatorTreeWrapperPassAnalysisGraphTraits {
101 : static DominatorTree *getGraph(DominatorTreeWrapperPass *DTWP) {
102 : return &DTWP->getDomTree();
103 : }
104 : };
105 :
106 : struct DomViewer : public DOTGraphTraitsViewer<
107 : DominatorTreeWrapperPass, false, DominatorTree *,
108 : DominatorTreeWrapperPassAnalysisGraphTraits> {
109 : static char ID;
110 0 : DomViewer()
111 0 : : DOTGraphTraitsViewer<DominatorTreeWrapperPass, false, DominatorTree *,
112 : DominatorTreeWrapperPassAnalysisGraphTraits>(
113 0 : "dom", ID) {
114 0 : initializeDomViewerPass(*PassRegistry::getPassRegistry());
115 0 : }
116 : };
117 :
118 : struct DomOnlyViewer : public DOTGraphTraitsViewer<
119 : DominatorTreeWrapperPass, true, DominatorTree *,
120 : DominatorTreeWrapperPassAnalysisGraphTraits> {
121 : static char ID;
122 0 : DomOnlyViewer()
123 0 : : DOTGraphTraitsViewer<DominatorTreeWrapperPass, true, DominatorTree *,
124 : DominatorTreeWrapperPassAnalysisGraphTraits>(
125 0 : "domonly", ID) {
126 0 : initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry());
127 0 : }
128 : };
129 :
130 : struct PostDominatorTreeWrapperPassAnalysisGraphTraits {
131 : static PostDominatorTree *getGraph(PostDominatorTreeWrapperPass *PDTWP) {
132 : return &PDTWP->getPostDomTree();
133 : }
134 : };
135 :
136 : struct PostDomViewer : public DOTGraphTraitsViewer<
137 : PostDominatorTreeWrapperPass, false,
138 : PostDominatorTree *,
139 : PostDominatorTreeWrapperPassAnalysisGraphTraits> {
140 : static char ID;
141 0 : PostDomViewer() :
142 : DOTGraphTraitsViewer<PostDominatorTreeWrapperPass, false,
143 : PostDominatorTree *,
144 : PostDominatorTreeWrapperPassAnalysisGraphTraits>(
145 0 : "postdom", ID){
146 0 : initializePostDomViewerPass(*PassRegistry::getPassRegistry());
147 0 : }
148 : };
149 :
150 : struct PostDomOnlyViewer : public DOTGraphTraitsViewer<
151 : PostDominatorTreeWrapperPass, true,
152 : PostDominatorTree *,
153 : PostDominatorTreeWrapperPassAnalysisGraphTraits> {
154 : static char ID;
155 0 : PostDomOnlyViewer() :
156 : DOTGraphTraitsViewer<PostDominatorTreeWrapperPass, true,
157 : PostDominatorTree *,
158 : PostDominatorTreeWrapperPassAnalysisGraphTraits>(
159 0 : "postdomonly", ID){
160 0 : initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry());
161 0 : }
162 : };
163 : } // end anonymous namespace
164 :
165 : char DomViewer::ID = 0;
166 21512 : INITIALIZE_PASS(DomViewer, "view-dom",
167 : "View dominance tree of function", false, false)
168 :
169 : char DomOnlyViewer::ID = 0;
170 21512 : INITIALIZE_PASS(DomOnlyViewer, "view-dom-only",
171 : "View dominance tree of function (with no function bodies)",
172 : false, false)
173 :
174 : char PostDomViewer::ID = 0;
175 21512 : INITIALIZE_PASS(PostDomViewer, "view-postdom",
176 : "View postdominance tree of function", false, false)
177 :
178 : char PostDomOnlyViewer::ID = 0;
179 21512 : INITIALIZE_PASS(PostDomOnlyViewer, "view-postdom-only",
180 : "View postdominance tree of function "
181 : "(with no function bodies)",
182 : false, false)
183 :
184 : namespace {
185 : struct DomPrinter : public DOTGraphTraitsPrinter<
186 : DominatorTreeWrapperPass, false, DominatorTree *,
187 : DominatorTreeWrapperPassAnalysisGraphTraits> {
188 : static char ID;
189 0 : DomPrinter()
190 0 : : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, false, DominatorTree *,
191 : DominatorTreeWrapperPassAnalysisGraphTraits>(
192 0 : "dom", ID) {
193 0 : initializeDomPrinterPass(*PassRegistry::getPassRegistry());
194 0 : }
195 : };
196 :
197 : struct DomOnlyPrinter : public DOTGraphTraitsPrinter<
198 : DominatorTreeWrapperPass, true, DominatorTree *,
199 : DominatorTreeWrapperPassAnalysisGraphTraits> {
200 : static char ID;
201 0 : DomOnlyPrinter()
202 0 : : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, true, DominatorTree *,
203 : DominatorTreeWrapperPassAnalysisGraphTraits>(
204 0 : "domonly", ID) {
205 0 : initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
206 0 : }
207 : };
208 :
209 : struct PostDomPrinter
210 : : public DOTGraphTraitsPrinter<
211 : PostDominatorTreeWrapperPass, false,
212 : PostDominatorTree *,
213 : PostDominatorTreeWrapperPassAnalysisGraphTraits> {
214 : static char ID;
215 0 : PostDomPrinter() :
216 : DOTGraphTraitsPrinter<PostDominatorTreeWrapperPass, false,
217 : PostDominatorTree *,
218 : PostDominatorTreeWrapperPassAnalysisGraphTraits>(
219 0 : "postdom", ID) {
220 0 : initializePostDomPrinterPass(*PassRegistry::getPassRegistry());
221 0 : }
222 : };
223 :
224 : struct PostDomOnlyPrinter
225 : : public DOTGraphTraitsPrinter<
226 : PostDominatorTreeWrapperPass, true,
227 : PostDominatorTree *,
228 : PostDominatorTreeWrapperPassAnalysisGraphTraits> {
229 : static char ID;
230 0 : PostDomOnlyPrinter() :
231 : DOTGraphTraitsPrinter<PostDominatorTreeWrapperPass, true,
232 : PostDominatorTree *,
233 : PostDominatorTreeWrapperPassAnalysisGraphTraits>(
234 0 : "postdomonly", ID) {
235 0 : initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
236 0 : }
237 : };
238 : } // end anonymous namespace
239 :
240 :
241 :
242 : char DomPrinter::ID = 0;
243 21512 : INITIALIZE_PASS(DomPrinter, "dot-dom",
244 : "Print dominance tree of function to 'dot' file",
245 : false, false)
246 :
247 : char DomOnlyPrinter::ID = 0;
248 21512 : INITIALIZE_PASS(DomOnlyPrinter, "dot-dom-only",
249 : "Print dominance tree of function to 'dot' file "
250 : "(with no function bodies)",
251 : false, false)
252 :
253 : char PostDomPrinter::ID = 0;
254 21512 : INITIALIZE_PASS(PostDomPrinter, "dot-postdom",
255 : "Print postdominance tree of function to 'dot' file",
256 : false, false)
257 :
258 : char PostDomOnlyPrinter::ID = 0;
259 21512 : INITIALIZE_PASS(PostDomOnlyPrinter, "dot-postdom-only",
260 : "Print postdominance tree of function to 'dot' file "
261 : "(with no function bodies)",
262 : false, false)
263 :
264 : // Create methods available outside of this file, to use them
265 : // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
266 : // the link time optimization.
267 :
268 0 : FunctionPass *llvm::createDomPrinterPass() {
269 0 : return new DomPrinter();
270 : }
271 :
272 0 : FunctionPass *llvm::createDomOnlyPrinterPass() {
273 0 : return new DomOnlyPrinter();
274 : }
275 :
276 0 : FunctionPass *llvm::createDomViewerPass() {
277 0 : return new DomViewer();
278 : }
279 :
280 0 : FunctionPass *llvm::createDomOnlyViewerPass() {
281 0 : return new DomOnlyViewer();
282 : }
283 :
284 0 : FunctionPass *llvm::createPostDomPrinterPass() {
285 0 : return new PostDomPrinter();
286 : }
287 :
288 0 : FunctionPass *llvm::createPostDomOnlyPrinterPass() {
289 0 : return new PostDomOnlyPrinter();
290 : }
291 :
292 0 : FunctionPass *llvm::createPostDomViewerPass() {
293 0 : return new PostDomViewer();
294 : }
295 :
296 0 : FunctionPass *llvm::createPostDomOnlyViewerPass() {
297 0 : return new PostDomOnlyViewer();
298 : }
|