]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Analysis/DomPrinter.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Analysis / DomPrinter.cpp
1 //===- DomPrinter.cpp - DOT printer for the dominance trees    ------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit
10 // a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the
11 // program, with a graph of the dominance/postdominance tree of that
12 // function.
13 //
14 // There are also passes available to directly call dotty ('-view-dom' or
15 // '-view-postdom'). By appending '-only' like '-dot-dom-only' only the
16 // names of the bbs are printed, but the content is hidden.
17 //
18 //===----------------------------------------------------------------------===//
19
20 #include "llvm/Analysis/DomPrinter.h"
21 #include "llvm/Analysis/DOTGraphTraitsPass.h"
22 #include "llvm/Analysis/PostDominators.h"
23
24 using namespace llvm;
25
26 namespace llvm {
27 template<>
28 struct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits {
29
30   DOTGraphTraits (bool isSimple=false)
31     : DefaultDOTGraphTraits(isSimple) {}
32
33   std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) {
34
35     BasicBlock *BB = Node->getBlock();
36
37     if (!BB)
38       return "Post dominance root node";
39
40
41     if (isSimple())
42       return DOTGraphTraits<const Function*>
43         ::getSimpleNodeLabel(BB, BB->getParent());
44     else
45       return DOTGraphTraits<const Function*>
46         ::getCompleteNodeLabel(BB, BB->getParent());
47   }
48 };
49
50 template<>
51 struct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> {
52
53   DOTGraphTraits (bool isSimple=false)
54     : DOTGraphTraits<DomTreeNode*>(isSimple) {}
55
56   static std::string getGraphName(DominatorTree *DT) {
57     return "Dominator tree";
58   }
59
60   std::string getNodeLabel(DomTreeNode *Node, DominatorTree *G) {
61     return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
62   }
63 };
64
65 template<>
66 struct DOTGraphTraits<PostDominatorTree*>
67   : public DOTGraphTraits<DomTreeNode*> {
68
69   DOTGraphTraits (bool isSimple=false)
70     : DOTGraphTraits<DomTreeNode*>(isSimple) {}
71
72   static std::string getGraphName(PostDominatorTree *DT) {
73     return "Post dominator tree";
74   }
75
76   std::string getNodeLabel(DomTreeNode *Node, PostDominatorTree *G ) {
77     return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
78   }
79 };
80 }
81
82 void DominatorTree::viewGraph(const Twine &Name, const Twine &Title) {
83 #ifndef NDEBUG
84   ViewGraph(this, Name, false, Title);
85 #else
86   errs() << "DomTree dump not available, build with DEBUG\n";
87 #endif  // NDEBUG
88 }
89
90 void DominatorTree::viewGraph() {
91 #ifndef NDEBUG
92   this->viewGraph("domtree", "Dominator Tree for function");
93 #else
94   errs() << "DomTree dump not available, build with DEBUG\n";
95 #endif  // NDEBUG
96 }
97
98 namespace {
99 struct DominatorTreeWrapperPassAnalysisGraphTraits {
100   static DominatorTree *getGraph(DominatorTreeWrapperPass *DTWP) {
101     return &DTWP->getDomTree();
102   }
103 };
104
105 struct DomViewer : public DOTGraphTraitsViewer<
106                        DominatorTreeWrapperPass, false, DominatorTree *,
107                        DominatorTreeWrapperPassAnalysisGraphTraits> {
108   static char ID;
109   DomViewer()
110       : DOTGraphTraitsViewer<DominatorTreeWrapperPass, false, DominatorTree *,
111                              DominatorTreeWrapperPassAnalysisGraphTraits>(
112             "dom", ID) {
113     initializeDomViewerPass(*PassRegistry::getPassRegistry());
114   }
115 };
116
117 struct DomOnlyViewer : public DOTGraphTraitsViewer<
118                            DominatorTreeWrapperPass, true, DominatorTree *,
119                            DominatorTreeWrapperPassAnalysisGraphTraits> {
120   static char ID;
121   DomOnlyViewer()
122       : DOTGraphTraitsViewer<DominatorTreeWrapperPass, true, DominatorTree *,
123                              DominatorTreeWrapperPassAnalysisGraphTraits>(
124             "domonly", ID) {
125     initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry());
126   }
127 };
128
129 struct PostDominatorTreeWrapperPassAnalysisGraphTraits {
130   static PostDominatorTree *getGraph(PostDominatorTreeWrapperPass *PDTWP) {
131     return &PDTWP->getPostDomTree();
132   }
133 };
134
135 struct PostDomViewer : public DOTGraphTraitsViewer<
136                           PostDominatorTreeWrapperPass, false,
137                           PostDominatorTree *,
138                           PostDominatorTreeWrapperPassAnalysisGraphTraits> {
139   static char ID;
140   PostDomViewer() :
141     DOTGraphTraitsViewer<PostDominatorTreeWrapperPass, false,
142                          PostDominatorTree *,
143                          PostDominatorTreeWrapperPassAnalysisGraphTraits>(
144         "postdom", ID){
145       initializePostDomViewerPass(*PassRegistry::getPassRegistry());
146     }
147 };
148
149 struct PostDomOnlyViewer : public DOTGraphTraitsViewer<
150                             PostDominatorTreeWrapperPass, true,
151                             PostDominatorTree *,
152                             PostDominatorTreeWrapperPassAnalysisGraphTraits> {
153   static char ID;
154   PostDomOnlyViewer() :
155     DOTGraphTraitsViewer<PostDominatorTreeWrapperPass, true,
156                          PostDominatorTree *,
157                          PostDominatorTreeWrapperPassAnalysisGraphTraits>(
158         "postdomonly", ID){
159       initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry());
160     }
161 };
162 } // end anonymous namespace
163
164 char DomViewer::ID = 0;
165 INITIALIZE_PASS(DomViewer, "view-dom",
166                 "View dominance tree of function", false, false)
167
168 char DomOnlyViewer::ID = 0;
169 INITIALIZE_PASS(DomOnlyViewer, "view-dom-only",
170                 "View dominance tree of function (with no function bodies)",
171                 false, false)
172
173 char PostDomViewer::ID = 0;
174 INITIALIZE_PASS(PostDomViewer, "view-postdom",
175                 "View postdominance tree of function", false, false)
176
177 char PostDomOnlyViewer::ID = 0;
178 INITIALIZE_PASS(PostDomOnlyViewer, "view-postdom-only",
179                 "View postdominance tree of function "
180                 "(with no function bodies)",
181                 false, false)
182
183 namespace {
184 struct DomPrinter : public DOTGraphTraitsPrinter<
185                         DominatorTreeWrapperPass, false, DominatorTree *,
186                         DominatorTreeWrapperPassAnalysisGraphTraits> {
187   static char ID;
188   DomPrinter()
189       : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, false, DominatorTree *,
190                               DominatorTreeWrapperPassAnalysisGraphTraits>(
191             "dom", ID) {
192     initializeDomPrinterPass(*PassRegistry::getPassRegistry());
193   }
194 };
195
196 struct DomOnlyPrinter : public DOTGraphTraitsPrinter<
197                             DominatorTreeWrapperPass, true, DominatorTree *,
198                             DominatorTreeWrapperPassAnalysisGraphTraits> {
199   static char ID;
200   DomOnlyPrinter()
201       : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, true, DominatorTree *,
202                               DominatorTreeWrapperPassAnalysisGraphTraits>(
203             "domonly", ID) {
204     initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
205   }
206 };
207
208 struct PostDomPrinter
209   : public DOTGraphTraitsPrinter<
210                             PostDominatorTreeWrapperPass, false,
211                             PostDominatorTree *,
212                             PostDominatorTreeWrapperPassAnalysisGraphTraits> {
213   static char ID;
214   PostDomPrinter() :
215     DOTGraphTraitsPrinter<PostDominatorTreeWrapperPass, false,
216                           PostDominatorTree *,
217                           PostDominatorTreeWrapperPassAnalysisGraphTraits>(
218         "postdom", ID) {
219       initializePostDomPrinterPass(*PassRegistry::getPassRegistry());
220     }
221 };
222
223 struct PostDomOnlyPrinter
224   : public DOTGraphTraitsPrinter<
225                             PostDominatorTreeWrapperPass, true,
226                             PostDominatorTree *,
227                             PostDominatorTreeWrapperPassAnalysisGraphTraits> {
228   static char ID;
229   PostDomOnlyPrinter() :
230     DOTGraphTraitsPrinter<PostDominatorTreeWrapperPass, true,
231                           PostDominatorTree *,
232                           PostDominatorTreeWrapperPassAnalysisGraphTraits>(
233         "postdomonly", ID) {
234       initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
235     }
236 };
237 } // end anonymous namespace
238
239
240
241 char DomPrinter::ID = 0;
242 INITIALIZE_PASS(DomPrinter, "dot-dom",
243                 "Print dominance tree of function to 'dot' file",
244                 false, false)
245
246 char DomOnlyPrinter::ID = 0;
247 INITIALIZE_PASS(DomOnlyPrinter, "dot-dom-only",
248                 "Print dominance tree of function to 'dot' file "
249                 "(with no function bodies)",
250                 false, false)
251
252 char PostDomPrinter::ID = 0;
253 INITIALIZE_PASS(PostDomPrinter, "dot-postdom",
254                 "Print postdominance tree of function to 'dot' file",
255                 false, false)
256
257 char PostDomOnlyPrinter::ID = 0;
258 INITIALIZE_PASS(PostDomOnlyPrinter, "dot-postdom-only",
259                 "Print postdominance tree of function to 'dot' file "
260                 "(with no function bodies)",
261                 false, false)
262
263 // Create methods available outside of this file, to use them
264 // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
265 // the link time optimization.
266
267 FunctionPass *llvm::createDomPrinterPass() {
268   return new DomPrinter();
269 }
270
271 FunctionPass *llvm::createDomOnlyPrinterPass() {
272   return new DomOnlyPrinter();
273 }
274
275 FunctionPass *llvm::createDomViewerPass() {
276   return new DomViewer();
277 }
278
279 FunctionPass *llvm::createDomOnlyViewerPass() {
280   return new DomOnlyViewer();
281 }
282
283 FunctionPass *llvm::createPostDomPrinterPass() {
284   return new PostDomPrinter();
285 }
286
287 FunctionPass *llvm::createPostDomOnlyPrinterPass() {
288   return new PostDomOnlyPrinter();
289 }
290
291 FunctionPass *llvm::createPostDomViewerPass() {
292   return new PostDomViewer();
293 }
294
295 FunctionPass *llvm::createPostDomOnlyViewerPass() {
296   return new PostDomOnlyViewer();
297 }