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
25using namespace llvm;
26
27
28void 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
36void 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
44namespace {
45struct LegacyDominatorTreeWrapperPassAnalysisGraphTraits {
46 static DominatorTree *getGraph(DominatorTreeWrapperPass *DTWP) {
47 return &DTWP->getDomTree();
48 }
49};
50
51struct DomViewerWrapperPass
52 : public DOTGraphTraitsViewerWrapperPass<
53 DominatorTreeWrapperPass, false, DominatorTree *,
54 LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {
55 static char ID;
56 DomViewerWrapperPass()
57 : DOTGraphTraitsViewerWrapperPass<
58 DominatorTreeWrapperPass, false, DominatorTree *,
59 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("dom", ID) {}
60};
61
62struct DomOnlyViewerWrapperPass
63 : public DOTGraphTraitsViewerWrapperPass<
64 DominatorTreeWrapperPass, true, DominatorTree *,
65 LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {
66 static char ID;
67 DomOnlyViewerWrapperPass()
68 : DOTGraphTraitsViewerWrapperPass<
69 DominatorTreeWrapperPass, true, DominatorTree *,
70 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) {}
71};
72
73struct LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits {
74 static PostDominatorTree *getGraph(PostDominatorTreeWrapperPass *PDTWP) {
75 return &PDTWP->getPostDomTree();
76 }
77};
78
79struct PostDomViewerWrapperPass
80 : public DOTGraphTraitsViewerWrapperPass<
81 PostDominatorTreeWrapperPass, false, PostDominatorTree *,
82 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
83 static char ID;
84 PostDomViewerWrapperPass()
85 : DOTGraphTraitsViewerWrapperPass<
86 PostDominatorTreeWrapperPass, false, PostDominatorTree *,
87 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom",
88 ID) {}
89};
90
91struct PostDomOnlyViewerWrapperPass
92 : public DOTGraphTraitsViewerWrapperPass<
93 PostDominatorTreeWrapperPass, true, PostDominatorTree *,
94 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
95 static char ID;
96 PostDomOnlyViewerWrapperPass()
97 : DOTGraphTraitsViewerWrapperPass<
98 PostDominatorTreeWrapperPass, true, PostDominatorTree *,
99 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>(
100 "postdomonly", ID) {}
101};
102} // end anonymous namespace
103
104char DomViewerWrapperPass::ID = 0;
105INITIALIZE_PASS(DomViewerWrapperPass, "view-dom",
106 "View dominance tree of function", false, false)
107
108char DomOnlyViewerWrapperPass::ID = 0;
109INITIALIZE_PASS(DomOnlyViewerWrapperPass, "view-dom-only",
110 "View dominance tree of function (with no function bodies)",
111 false, false)
112
113char PostDomViewerWrapperPass::ID = 0;
114INITIALIZE_PASS(PostDomViewerWrapperPass, "view-postdom",
115 "View postdominance tree of function", false, false)
116
117char PostDomOnlyViewerWrapperPass::ID = 0;
118INITIALIZE_PASS(PostDomOnlyViewerWrapperPass, "view-postdom-only",
119 "View postdominance tree of function "
120 "(with no function bodies)",
121 false, false)
122
123namespace {
124struct DomPrinterWrapperPass
125 : public DOTGraphTraitsPrinterWrapperPass<
126 DominatorTreeWrapperPass, false, DominatorTree *,
127 LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {
128 static char ID;
129 DomPrinterWrapperPass()
130 : DOTGraphTraitsPrinterWrapperPass<
131 DominatorTreeWrapperPass, false, DominatorTree *,
132 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("dom", ID) {}
133};
134
135struct DomOnlyPrinterWrapperPass
136 : public DOTGraphTraitsPrinterWrapperPass<
137 DominatorTreeWrapperPass, true, DominatorTree *,
138 LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {
139 static char ID;
140 DomOnlyPrinterWrapperPass()
141 : DOTGraphTraitsPrinterWrapperPass<
142 DominatorTreeWrapperPass, true, DominatorTree *,
143 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) {}
144};
145
146struct PostDomPrinterWrapperPass
147 : public DOTGraphTraitsPrinterWrapperPass<
148 PostDominatorTreeWrapperPass, false, PostDominatorTree *,
149 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
150 static char ID;
151 PostDomPrinterWrapperPass()
152 : DOTGraphTraitsPrinterWrapperPass<
153 PostDominatorTreeWrapperPass, false, PostDominatorTree *,
154 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom",
155 ID) {}
156};
157
158struct PostDomOnlyPrinterWrapperPass
159 : public DOTGraphTraitsPrinterWrapperPass<
160 PostDominatorTreeWrapperPass, true, PostDominatorTree *,
161 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
162 static char ID;
163 PostDomOnlyPrinterWrapperPass()
164 : DOTGraphTraitsPrinterWrapperPass<
165 PostDominatorTreeWrapperPass, true, PostDominatorTree *,
166 LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>(
167 "postdomonly", ID) {}
168};
169} // end anonymous namespace
170
171char DomPrinterWrapperPass::ID = 0;
172INITIALIZE_PASS(DomPrinterWrapperPass, "dot-dom",
173 "Print dominance tree of function to 'dot' file", false, false)
174
175char DomOnlyPrinterWrapperPass::ID = 0;
176INITIALIZE_PASS(DomOnlyPrinterWrapperPass, "dot-dom-only",
177 "Print dominance tree of function to 'dot' file "
178 "(with no function bodies)",
179 false, false)
180
181char PostDomPrinterWrapperPass::ID = 0;
182INITIALIZE_PASS(PostDomPrinterWrapperPass, "dot-postdom",
183 "Print postdominance tree of function to 'dot' file", false,
184 false)
185
186char PostDomOnlyPrinterWrapperPass::ID = 0;
187INITIALIZE_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
196FunctionPass *llvm::createDomPrinterWrapperPassPass() {
197 return new DomPrinterWrapperPass();
198}
199
200FunctionPass *llvm::createDomOnlyPrinterWrapperPassPass() {
201 return new DomOnlyPrinterWrapperPass();
202}
203
204FunctionPass *llvm::createDomViewerWrapperPassPass() {
205 return new DomViewerWrapperPass();
206}
207
208FunctionPass *llvm::createDomOnlyViewerWrapperPassPass() {
209 return new DomOnlyViewerWrapperPass();
210}
211
212FunctionPass *llvm::createPostDomPrinterWrapperPassPass() {
213 return new PostDomPrinterWrapperPass();
214}
215
216FunctionPass *llvm::createPostDomOnlyPrinterWrapperPassPass() {
217 return new PostDomOnlyPrinterWrapperPass();
218}
219
220FunctionPass *llvm::createPostDomViewerWrapperPassPass() {
221 return new PostDomViewerWrapperPass();
222}
223
224FunctionPass *llvm::createPostDomOnlyViewerWrapperPassPass() {
225 return new PostDomOnlyViewerWrapperPass();
226}
227