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 };
61
62 struct DomOnlyViewerWrapperPass
63 : public DOTGraphTraitsViewerWrapperPass<
64 DominatorTreeWrapperPass, true, DominatorTree *,
65 LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {
66 static char ID;
DomOnlyViewerWrapperPass__anon89845f870111::DomOnlyViewerWrapperPass67 DomOnlyViewerWrapperPass()
68 : DOTGraphTraitsViewerWrapperPass<
69 DominatorTreeWrapperPass, true, DominatorTree *,
70 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) {}
71 };
72
73 struct LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits {
getGraph__anon89845f870111::LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits74 static PostDominatorTree *getGraph(PostDominatorTreeWrapperPass *PDTWP) {
75 return &PDTWP->getPostDomTree();
76 }
77 };
78
79 struct PostDomViewerWrapperPass
80 : public DOTGraphTraitsViewerWrapperPass<
81 PostDominatorTreeWrapperPass, false, PostDominatorTree *,
82 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
83 static char ID;
PostDomViewerWrapperPass__anon89845f870111::PostDomViewerWrapperPass84 PostDomViewerWrapperPass()
85 : DOTGraphTraitsViewerWrapperPass<
86 PostDominatorTreeWrapperPass, false, PostDominatorTree *,
87 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom",
88 ID) {}
89 };
90
91 struct PostDomOnlyViewerWrapperPass
92 : public DOTGraphTraitsViewerWrapperPass<
93 PostDominatorTreeWrapperPass, true, PostDominatorTree *,
94 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
95 static char ID;
PostDomOnlyViewerWrapperPass__anon89845f870111::PostDomOnlyViewerWrapperPass96 PostDomOnlyViewerWrapperPass()
97 : DOTGraphTraitsViewerWrapperPass<
98 PostDominatorTreeWrapperPass, true, PostDominatorTree *,
99 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>(
100 "postdomonly", ID) {}
101 };
102 } // end anonymous namespace
103
104 char DomViewerWrapperPass::ID = 0;
105 INITIALIZE_PASS(DomViewerWrapperPass, "view-dom",
106 "View dominance tree of function", false, false)
107
108 char DomOnlyViewerWrapperPass::ID = 0;
109 INITIALIZE_PASS(DomOnlyViewerWrapperPass, "view-dom-only",
110 "View dominance tree of function (with no function bodies)",
111 false, false)
112
113 char PostDomViewerWrapperPass::ID = 0;
114 INITIALIZE_PASS(PostDomViewerWrapperPass, "view-postdom",
115 "View postdominance tree of function", false, false)
116
117 char PostDomOnlyViewerWrapperPass::ID = 0;
118 INITIALIZE_PASS(PostDomOnlyViewerWrapperPass, "view-postdom-only",
119 "View postdominance tree of function "
120 "(with no function bodies)",
121 false, false)
122
123 namespace {
124 struct DomPrinterWrapperPass
125 : public DOTGraphTraitsPrinterWrapperPass<
126 DominatorTreeWrapperPass, false, DominatorTree *,
127 LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {
128 static char ID;
DomPrinterWrapperPass__anon89845f870211::DomPrinterWrapperPass129 DomPrinterWrapperPass()
130 : DOTGraphTraitsPrinterWrapperPass<
131 DominatorTreeWrapperPass, false, DominatorTree *,
132 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("dom", ID) {}
133 };
134
135 struct DomOnlyPrinterWrapperPass
136 : public DOTGraphTraitsPrinterWrapperPass<
137 DominatorTreeWrapperPass, true, DominatorTree *,
138 LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {
139 static char ID;
DomOnlyPrinterWrapperPass__anon89845f870211::DomOnlyPrinterWrapperPass140 DomOnlyPrinterWrapperPass()
141 : DOTGraphTraitsPrinterWrapperPass<
142 DominatorTreeWrapperPass, true, DominatorTree *,
143 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) {}
144 };
145
146 struct PostDomPrinterWrapperPass
147 : public DOTGraphTraitsPrinterWrapperPass<
148 PostDominatorTreeWrapperPass, false, PostDominatorTree *,
149 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
150 static char ID;
PostDomPrinterWrapperPass__anon89845f870211::PostDomPrinterWrapperPass151 PostDomPrinterWrapperPass()
152 : DOTGraphTraitsPrinterWrapperPass<
153 PostDominatorTreeWrapperPass, false, PostDominatorTree *,
154 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom",
155 ID) {}
156 };
157
158 struct PostDomOnlyPrinterWrapperPass
159 : public DOTGraphTraitsPrinterWrapperPass<
160 PostDominatorTreeWrapperPass, true, PostDominatorTree *,
161 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
162 static char ID;
PostDomOnlyPrinterWrapperPass__anon89845f870211::PostDomOnlyPrinterWrapperPass163 PostDomOnlyPrinterWrapperPass()
164 : DOTGraphTraitsPrinterWrapperPass<
165 PostDominatorTreeWrapperPass, true, PostDominatorTree *,
166 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>(
167 "postdomonly", ID) {}
168 };
169 } // end anonymous namespace
170
171 char DomPrinterWrapperPass::ID = 0;
172 INITIALIZE_PASS(DomPrinterWrapperPass, "dot-dom",
173 "Print dominance tree of function to 'dot' file", false, false)
174
175 char DomOnlyPrinterWrapperPass::ID = 0;
176 INITIALIZE_PASS(DomOnlyPrinterWrapperPass, "dot-dom-only",
177 "Print dominance tree of function to 'dot' file "
178 "(with no function bodies)",
179 false, false)
180
181 char PostDomPrinterWrapperPass::ID = 0;
182 INITIALIZE_PASS(PostDomPrinterWrapperPass, "dot-postdom",
183 "Print postdominance tree of function to 'dot' file", false,
184 false)
185
186 char PostDomOnlyPrinterWrapperPass::ID = 0;
187 INITIALIZE_PASS(PostDomOnlyPrinterWrapperPass, "dot-postdom-only",
188 "Print postdominance tree of function to 'dot' file "
189 "(with no function bodies)",
190 false, false)
191
192 // Create methods available outside of this file, to use them
193 // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
194 // the link time optimization.
195
createDomPrinterWrapperPassPass()196 FunctionPass *llvm::createDomPrinterWrapperPassPass() {
197 return new DomPrinterWrapperPass();
198 }
199
createDomOnlyPrinterWrapperPassPass()200 FunctionPass *llvm::createDomOnlyPrinterWrapperPassPass() {
201 return new DomOnlyPrinterWrapperPass();
202 }
203
createDomViewerWrapperPassPass()204 FunctionPass *llvm::createDomViewerWrapperPassPass() {
205 return new DomViewerWrapperPass();
206 }
207
createDomOnlyViewerWrapperPassPass()208 FunctionPass *llvm::createDomOnlyViewerWrapperPassPass() {
209 return new DomOnlyViewerWrapperPass();
210 }
211
createPostDomPrinterWrapperPassPass()212 FunctionPass *llvm::createPostDomPrinterWrapperPassPass() {
213 return new PostDomPrinterWrapperPass();
214 }
215
createPostDomOnlyPrinterWrapperPassPass()216 FunctionPass *llvm::createPostDomOnlyPrinterWrapperPassPass() {
217 return new PostDomOnlyPrinterWrapperPass();
218 }
219
createPostDomViewerWrapperPassPass()220 FunctionPass *llvm::createPostDomViewerWrapperPassPass() {
221 return new PostDomViewerWrapperPass();
222 }
223
createPostDomOnlyViewerWrapperPassPass()224 FunctionPass *llvm::createPostDomOnlyViewerWrapperPassPass() {
225 return new PostDomOnlyViewerWrapperPass();
226 }
227