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 #include "llvm/InitializePasses.h"
24
25 using namespace llvm;
26
27
viewGraph(const Twine & Name,const Twine & Title)28 void DominatorTree::viewGraph(const Twine &Name, const Twine &Title) {
29 #ifndef NDEBUG
30 ViewGraph(this, Name, false, Title);
31 #else
32 errs() << "DomTree dump not available, build with DEBUG\n";
33 #endif // NDEBUG
34 }
35
viewGraph()36 void DominatorTree::viewGraph() {
37 #ifndef NDEBUG
38 this->viewGraph("domtree", "Dominator Tree for function");
39 #else
40 errs() << "DomTree dump not available, build with DEBUG\n";
41 #endif // NDEBUG
42 }
43
44 namespace {
45 struct LegacyDominatorTreeWrapperPassAnalysisGraphTraits {
getGraph__anon89845f870111::LegacyDominatorTreeWrapperPassAnalysisGraphTraits46 static DominatorTree *getGraph(DominatorTreeWrapperPass *DTWP) {
47 return &DTWP->getDomTree();
48 }
49 };
50
51 struct DomViewerWrapperPass
52 : public DOTGraphTraitsViewerWrapperPass<
53 DominatorTreeWrapperPass, false, DominatorTree *,
54 LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {
55 static char ID;
DomViewerWrapperPass__anon89845f870111::DomViewerWrapperPass56 DomViewerWrapperPass()
57 : DOTGraphTraitsViewerWrapperPass<
58 DominatorTreeWrapperPass, false, DominatorTree *,
59 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("dom", ID) {
60 initializeDomViewerWrapperPassPass(*PassRegistry::getPassRegistry());
61 }
62 };
63
64 struct DomOnlyViewerWrapperPass
65 : public DOTGraphTraitsViewerWrapperPass<
66 DominatorTreeWrapperPass, true, DominatorTree *,
67 LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {
68 static char ID;
DomOnlyViewerWrapperPass__anon89845f870111::DomOnlyViewerWrapperPass69 DomOnlyViewerWrapperPass()
70 : DOTGraphTraitsViewerWrapperPass<
71 DominatorTreeWrapperPass, true, DominatorTree *,
72 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) {
73 initializeDomOnlyViewerWrapperPassPass(*PassRegistry::getPassRegistry());
74 }
75 };
76
77 struct LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits {
getGraph__anon89845f870111::LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits78 static PostDominatorTree *getGraph(PostDominatorTreeWrapperPass *PDTWP) {
79 return &PDTWP->getPostDomTree();
80 }
81 };
82
83 struct PostDomViewerWrapperPass
84 : public DOTGraphTraitsViewerWrapperPass<
85 PostDominatorTreeWrapperPass, false, PostDominatorTree *,
86 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
87 static char ID;
PostDomViewerWrapperPass__anon89845f870111::PostDomViewerWrapperPass88 PostDomViewerWrapperPass()
89 : DOTGraphTraitsViewerWrapperPass<
90 PostDominatorTreeWrapperPass, false, PostDominatorTree *,
91 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom",
92 ID) {
93 initializePostDomViewerWrapperPassPass(*PassRegistry::getPassRegistry());
94 }
95 };
96
97 struct PostDomOnlyViewerWrapperPass
98 : public DOTGraphTraitsViewerWrapperPass<
99 PostDominatorTreeWrapperPass, true, PostDominatorTree *,
100 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
101 static char ID;
PostDomOnlyViewerWrapperPass__anon89845f870111::PostDomOnlyViewerWrapperPass102 PostDomOnlyViewerWrapperPass()
103 : DOTGraphTraitsViewerWrapperPass<
104 PostDominatorTreeWrapperPass, true, PostDominatorTree *,
105 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>(
106 "postdomonly", ID) {
107 initializePostDomOnlyViewerWrapperPassPass(
108 *PassRegistry::getPassRegistry());
109 }
110 };
111 } // end anonymous namespace
112
113 char DomViewerWrapperPass::ID = 0;
114 INITIALIZE_PASS(DomViewerWrapperPass, "view-dom",
115 "View dominance tree of function", false, false)
116
117 char DomOnlyViewerWrapperPass::ID = 0;
118 INITIALIZE_PASS(DomOnlyViewerWrapperPass, "view-dom-only",
119 "View dominance tree of function (with no function bodies)",
120 false, false)
121
122 char PostDomViewerWrapperPass::ID = 0;
123 INITIALIZE_PASS(PostDomViewerWrapperPass, "view-postdom",
124 "View postdominance tree of function", false, false)
125
126 char PostDomOnlyViewerWrapperPass::ID = 0;
127 INITIALIZE_PASS(PostDomOnlyViewerWrapperPass, "view-postdom-only",
128 "View postdominance tree of function "
129 "(with no function bodies)",
130 false, false)
131
132 namespace {
133 struct DomPrinterWrapperPass
134 : public DOTGraphTraitsPrinterWrapperPass<
135 DominatorTreeWrapperPass, false, DominatorTree *,
136 LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {
137 static char ID;
DomPrinterWrapperPass__anon89845f870211::DomPrinterWrapperPass138 DomPrinterWrapperPass()
139 : DOTGraphTraitsPrinterWrapperPass<
140 DominatorTreeWrapperPass, false, DominatorTree *,
141 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("dom", ID) {
142 initializeDomPrinterWrapperPassPass(*PassRegistry::getPassRegistry());
143 }
144 };
145
146 struct DomOnlyPrinterWrapperPass
147 : public DOTGraphTraitsPrinterWrapperPass<
148 DominatorTreeWrapperPass, true, DominatorTree *,
149 LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {
150 static char ID;
DomOnlyPrinterWrapperPass__anon89845f870211::DomOnlyPrinterWrapperPass151 DomOnlyPrinterWrapperPass()
152 : DOTGraphTraitsPrinterWrapperPass<
153 DominatorTreeWrapperPass, true, DominatorTree *,
154 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) {
155 initializeDomOnlyPrinterWrapperPassPass(*PassRegistry::getPassRegistry());
156 }
157 };
158
159 struct PostDomPrinterWrapperPass
160 : public DOTGraphTraitsPrinterWrapperPass<
161 PostDominatorTreeWrapperPass, false, PostDominatorTree *,
162 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
163 static char ID;
PostDomPrinterWrapperPass__anon89845f870211::PostDomPrinterWrapperPass164 PostDomPrinterWrapperPass()
165 : DOTGraphTraitsPrinterWrapperPass<
166 PostDominatorTreeWrapperPass, false, PostDominatorTree *,
167 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom",
168 ID) {
169 initializePostDomPrinterWrapperPassPass(*PassRegistry::getPassRegistry());
170 }
171 };
172
173 struct PostDomOnlyPrinterWrapperPass
174 : public DOTGraphTraitsPrinterWrapperPass<
175 PostDominatorTreeWrapperPass, true, PostDominatorTree *,
176 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
177 static char ID;
PostDomOnlyPrinterWrapperPass__anon89845f870211::PostDomOnlyPrinterWrapperPass178 PostDomOnlyPrinterWrapperPass()
179 : DOTGraphTraitsPrinterWrapperPass<
180 PostDominatorTreeWrapperPass, true, PostDominatorTree *,
181 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>(
182 "postdomonly", ID) {
183 initializePostDomOnlyPrinterWrapperPassPass(
184 *PassRegistry::getPassRegistry());
185 }
186 };
187 } // end anonymous namespace
188
189 char DomPrinterWrapperPass::ID = 0;
190 INITIALIZE_PASS(DomPrinterWrapperPass, "dot-dom",
191 "Print dominance tree of function to 'dot' file", false, false)
192
193 char DomOnlyPrinterWrapperPass::ID = 0;
194 INITIALIZE_PASS(DomOnlyPrinterWrapperPass, "dot-dom-only",
195 "Print dominance tree of function to 'dot' file "
196 "(with no function bodies)",
197 false, false)
198
199 char PostDomPrinterWrapperPass::ID = 0;
200 INITIALIZE_PASS(PostDomPrinterWrapperPass, "dot-postdom",
201 "Print postdominance tree of function to 'dot' file", false,
202 false)
203
204 char PostDomOnlyPrinterWrapperPass::ID = 0;
205 INITIALIZE_PASS(PostDomOnlyPrinterWrapperPass, "dot-postdom-only",
206 "Print postdominance tree of function to 'dot' file "
207 "(with no function bodies)",
208 false, false)
209
210 // Create methods available outside of this file, to use them
211 // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
212 // the link time optimization.
213
createDomPrinterWrapperPassPass()214 FunctionPass *llvm::createDomPrinterWrapperPassPass() {
215 return new DomPrinterWrapperPass();
216 }
217
createDomOnlyPrinterWrapperPassPass()218 FunctionPass *llvm::createDomOnlyPrinterWrapperPassPass() {
219 return new DomOnlyPrinterWrapperPass();
220 }
221
createDomViewerWrapperPassPass()222 FunctionPass *llvm::createDomViewerWrapperPassPass() {
223 return new DomViewerWrapperPass();
224 }
225
createDomOnlyViewerWrapperPassPass()226 FunctionPass *llvm::createDomOnlyViewerWrapperPassPass() {
227 return new DomOnlyViewerWrapperPass();
228 }
229
createPostDomPrinterWrapperPassPass()230 FunctionPass *llvm::createPostDomPrinterWrapperPassPass() {
231 return new PostDomPrinterWrapperPass();
232 }
233
createPostDomOnlyPrinterWrapperPassPass()234 FunctionPass *llvm::createPostDomOnlyPrinterWrapperPassPass() {
235 return new PostDomOnlyPrinterWrapperPass();
236 }
237
createPostDomViewerWrapperPassPass()238 FunctionPass *llvm::createPostDomViewerWrapperPassPass() {
239 return new PostDomViewerWrapperPass();
240 }
241
createPostDomOnlyViewerWrapperPassPass()242 FunctionPass *llvm::createPostDomOnlyViewerWrapperPassPass() {
243 return new PostDomOnlyViewerWrapperPass();
244 }
245