10b57cec5SDimitry Andric //===- DomPrinter.cpp - DOT printer for the dominance trees ------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit
100b57cec5SDimitry Andric // a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the
110b57cec5SDimitry Andric // program, with a graph of the dominance/postdominance tree of that
120b57cec5SDimitry Andric // function.
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric // There are also passes available to directly call dotty ('-view-dom' or
150b57cec5SDimitry Andric // '-view-postdom'). By appending '-only' like '-dot-dom-only' only the
160b57cec5SDimitry Andric // names of the bbs are printed, but the content is hidden.
170b57cec5SDimitry Andric //
180b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
190b57cec5SDimitry Andric
200b57cec5SDimitry Andric #include "llvm/Analysis/DomPrinter.h"
210b57cec5SDimitry Andric #include "llvm/Analysis/DOTGraphTraitsPass.h"
220b57cec5SDimitry Andric #include "llvm/Analysis/PostDominators.h"
23480093f4SDimitry Andric #include "llvm/InitializePasses.h"
240b57cec5SDimitry Andric
250b57cec5SDimitry Andric using namespace llvm;
260b57cec5SDimitry Andric
2704eeddc0SDimitry Andric
viewGraph(const Twine & Name,const Twine & Title)280b57cec5SDimitry Andric void DominatorTree::viewGraph(const Twine &Name, const Twine &Title) {
290b57cec5SDimitry Andric #ifndef NDEBUG
300b57cec5SDimitry Andric ViewGraph(this, Name, false, Title);
310b57cec5SDimitry Andric #else
320b57cec5SDimitry Andric errs() << "DomTree dump not available, build with DEBUG\n";
330b57cec5SDimitry Andric #endif // NDEBUG
340b57cec5SDimitry Andric }
350b57cec5SDimitry Andric
viewGraph()360b57cec5SDimitry Andric void DominatorTree::viewGraph() {
370b57cec5SDimitry Andric #ifndef NDEBUG
380b57cec5SDimitry Andric this->viewGraph("domtree", "Dominator Tree for function");
390b57cec5SDimitry Andric #else
400b57cec5SDimitry Andric errs() << "DomTree dump not available, build with DEBUG\n";
410b57cec5SDimitry Andric #endif // NDEBUG
420b57cec5SDimitry Andric }
430b57cec5SDimitry Andric
440b57cec5SDimitry Andric namespace {
45*81ad6265SDimitry Andric struct LegacyDominatorTreeWrapperPassAnalysisGraphTraits {
getGraph__anon89845f870111::LegacyDominatorTreeWrapperPassAnalysisGraphTraits460b57cec5SDimitry Andric static DominatorTree *getGraph(DominatorTreeWrapperPass *DTWP) {
470b57cec5SDimitry Andric return &DTWP->getDomTree();
480b57cec5SDimitry Andric }
490b57cec5SDimitry Andric };
500b57cec5SDimitry Andric
51*81ad6265SDimitry Andric struct DomViewerWrapperPass
52*81ad6265SDimitry Andric : public DOTGraphTraitsViewerWrapperPass<
530b57cec5SDimitry Andric DominatorTreeWrapperPass, false, DominatorTree *,
54*81ad6265SDimitry Andric LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {
550b57cec5SDimitry Andric static char ID;
DomViewerWrapperPass__anon89845f870111::DomViewerWrapperPass56*81ad6265SDimitry Andric DomViewerWrapperPass()
57*81ad6265SDimitry Andric : DOTGraphTraitsViewerWrapperPass<
58*81ad6265SDimitry Andric DominatorTreeWrapperPass, false, DominatorTree *,
59*81ad6265SDimitry Andric LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("dom", ID) {
60*81ad6265SDimitry Andric initializeDomViewerWrapperPassPass(*PassRegistry::getPassRegistry());
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric };
630b57cec5SDimitry Andric
64*81ad6265SDimitry Andric struct DomOnlyViewerWrapperPass
65*81ad6265SDimitry Andric : public DOTGraphTraitsViewerWrapperPass<
660b57cec5SDimitry Andric DominatorTreeWrapperPass, true, DominatorTree *,
67*81ad6265SDimitry Andric LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {
680b57cec5SDimitry Andric static char ID;
DomOnlyViewerWrapperPass__anon89845f870111::DomOnlyViewerWrapperPass69*81ad6265SDimitry Andric DomOnlyViewerWrapperPass()
70*81ad6265SDimitry Andric : DOTGraphTraitsViewerWrapperPass<
71*81ad6265SDimitry Andric DominatorTreeWrapperPass, true, DominatorTree *,
72*81ad6265SDimitry Andric LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) {
73*81ad6265SDimitry Andric initializeDomOnlyViewerWrapperPassPass(*PassRegistry::getPassRegistry());
740b57cec5SDimitry Andric }
750b57cec5SDimitry Andric };
760b57cec5SDimitry Andric
77*81ad6265SDimitry Andric struct LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits {
getGraph__anon89845f870111::LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits780b57cec5SDimitry Andric static PostDominatorTree *getGraph(PostDominatorTreeWrapperPass *PDTWP) {
790b57cec5SDimitry Andric return &PDTWP->getPostDomTree();
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric };
820b57cec5SDimitry Andric
83*81ad6265SDimitry Andric struct PostDomViewerWrapperPass
84*81ad6265SDimitry Andric : public DOTGraphTraitsViewerWrapperPass<
85*81ad6265SDimitry Andric PostDominatorTreeWrapperPass, false, PostDominatorTree *,
86*81ad6265SDimitry Andric LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
870b57cec5SDimitry Andric static char ID;
PostDomViewerWrapperPass__anon89845f870111::PostDomViewerWrapperPass88*81ad6265SDimitry Andric PostDomViewerWrapperPass()
89*81ad6265SDimitry Andric : DOTGraphTraitsViewerWrapperPass<
90*81ad6265SDimitry Andric PostDominatorTreeWrapperPass, false, PostDominatorTree *,
91*81ad6265SDimitry Andric LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom",
92*81ad6265SDimitry Andric ID) {
93*81ad6265SDimitry Andric initializePostDomViewerWrapperPassPass(*PassRegistry::getPassRegistry());
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric };
960b57cec5SDimitry Andric
97*81ad6265SDimitry Andric struct PostDomOnlyViewerWrapperPass
98*81ad6265SDimitry Andric : public DOTGraphTraitsViewerWrapperPass<
99*81ad6265SDimitry Andric PostDominatorTreeWrapperPass, true, PostDominatorTree *,
100*81ad6265SDimitry Andric LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
1010b57cec5SDimitry Andric static char ID;
PostDomOnlyViewerWrapperPass__anon89845f870111::PostDomOnlyViewerWrapperPass102*81ad6265SDimitry Andric PostDomOnlyViewerWrapperPass()
103*81ad6265SDimitry Andric : DOTGraphTraitsViewerWrapperPass<
104*81ad6265SDimitry Andric PostDominatorTreeWrapperPass, true, PostDominatorTree *,
105*81ad6265SDimitry Andric LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>(
1060b57cec5SDimitry Andric "postdomonly", ID) {
107*81ad6265SDimitry Andric initializePostDomOnlyViewerWrapperPassPass(
108*81ad6265SDimitry Andric *PassRegistry::getPassRegistry());
1090b57cec5SDimitry Andric }
1100b57cec5SDimitry Andric };
1110b57cec5SDimitry Andric } // end anonymous namespace
1120b57cec5SDimitry Andric
113*81ad6265SDimitry Andric char DomViewerWrapperPass::ID = 0;
114*81ad6265SDimitry Andric INITIALIZE_PASS(DomViewerWrapperPass, "view-dom",
1150b57cec5SDimitry Andric "View dominance tree of function", false, false)
1160b57cec5SDimitry Andric
117*81ad6265SDimitry Andric char DomOnlyViewerWrapperPass::ID = 0;
118*81ad6265SDimitry Andric INITIALIZE_PASS(DomOnlyViewerWrapperPass, "view-dom-only",
1190b57cec5SDimitry Andric "View dominance tree of function (with no function bodies)",
1200b57cec5SDimitry Andric false, false)
1210b57cec5SDimitry Andric
122*81ad6265SDimitry Andric char PostDomViewerWrapperPass::ID = 0;
123*81ad6265SDimitry Andric INITIALIZE_PASS(PostDomViewerWrapperPass, "view-postdom",
1240b57cec5SDimitry Andric "View postdominance tree of function", false, false)
1250b57cec5SDimitry Andric
126*81ad6265SDimitry Andric char PostDomOnlyViewerWrapperPass::ID = 0;
127*81ad6265SDimitry Andric INITIALIZE_PASS(PostDomOnlyViewerWrapperPass, "view-postdom-only",
1280b57cec5SDimitry Andric "View postdominance tree of function "
1290b57cec5SDimitry Andric "(with no function bodies)",
1300b57cec5SDimitry Andric false, false)
1310b57cec5SDimitry Andric
1320b57cec5SDimitry Andric namespace {
133*81ad6265SDimitry Andric struct DomPrinterWrapperPass
134*81ad6265SDimitry Andric : public DOTGraphTraitsPrinterWrapperPass<
1350b57cec5SDimitry Andric DominatorTreeWrapperPass, false, DominatorTree *,
136*81ad6265SDimitry Andric LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {
1370b57cec5SDimitry Andric static char ID;
DomPrinterWrapperPass__anon89845f870211::DomPrinterWrapperPass138*81ad6265SDimitry Andric DomPrinterWrapperPass()
139*81ad6265SDimitry Andric : DOTGraphTraitsPrinterWrapperPass<
140*81ad6265SDimitry Andric DominatorTreeWrapperPass, false, DominatorTree *,
141*81ad6265SDimitry Andric LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("dom", ID) {
142*81ad6265SDimitry Andric initializeDomPrinterWrapperPassPass(*PassRegistry::getPassRegistry());
1430b57cec5SDimitry Andric }
1440b57cec5SDimitry Andric };
1450b57cec5SDimitry Andric
146*81ad6265SDimitry Andric struct DomOnlyPrinterWrapperPass
147*81ad6265SDimitry Andric : public DOTGraphTraitsPrinterWrapperPass<
1480b57cec5SDimitry Andric DominatorTreeWrapperPass, true, DominatorTree *,
149*81ad6265SDimitry Andric LegacyDominatorTreeWrapperPassAnalysisGraphTraits> {
1500b57cec5SDimitry Andric static char ID;
DomOnlyPrinterWrapperPass__anon89845f870211::DomOnlyPrinterWrapperPass151*81ad6265SDimitry Andric DomOnlyPrinterWrapperPass()
152*81ad6265SDimitry Andric : DOTGraphTraitsPrinterWrapperPass<
153*81ad6265SDimitry Andric DominatorTreeWrapperPass, true, DominatorTree *,
154*81ad6265SDimitry Andric LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) {
155*81ad6265SDimitry Andric initializeDomOnlyPrinterWrapperPassPass(*PassRegistry::getPassRegistry());
1560b57cec5SDimitry Andric }
1570b57cec5SDimitry Andric };
1580b57cec5SDimitry Andric
159*81ad6265SDimitry Andric struct PostDomPrinterWrapperPass
160*81ad6265SDimitry Andric : public DOTGraphTraitsPrinterWrapperPass<
161*81ad6265SDimitry Andric PostDominatorTreeWrapperPass, false, PostDominatorTree *,
162*81ad6265SDimitry Andric LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
1630b57cec5SDimitry Andric static char ID;
PostDomPrinterWrapperPass__anon89845f870211::PostDomPrinterWrapperPass164*81ad6265SDimitry Andric PostDomPrinterWrapperPass()
165*81ad6265SDimitry Andric : DOTGraphTraitsPrinterWrapperPass<
166*81ad6265SDimitry Andric PostDominatorTreeWrapperPass, false, PostDominatorTree *,
167*81ad6265SDimitry Andric LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>("postdom",
168*81ad6265SDimitry Andric ID) {
169*81ad6265SDimitry Andric initializePostDomPrinterWrapperPassPass(*PassRegistry::getPassRegistry());
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric };
1720b57cec5SDimitry Andric
173*81ad6265SDimitry Andric struct PostDomOnlyPrinterWrapperPass
174*81ad6265SDimitry Andric : public DOTGraphTraitsPrinterWrapperPass<
175*81ad6265SDimitry Andric PostDominatorTreeWrapperPass, true, PostDominatorTree *,
176*81ad6265SDimitry Andric LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits> {
1770b57cec5SDimitry Andric static char ID;
PostDomOnlyPrinterWrapperPass__anon89845f870211::PostDomOnlyPrinterWrapperPass178*81ad6265SDimitry Andric PostDomOnlyPrinterWrapperPass()
179*81ad6265SDimitry Andric : DOTGraphTraitsPrinterWrapperPass<
180*81ad6265SDimitry Andric PostDominatorTreeWrapperPass, true, PostDominatorTree *,
181*81ad6265SDimitry Andric LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits>(
1820b57cec5SDimitry Andric "postdomonly", ID) {
183*81ad6265SDimitry Andric initializePostDomOnlyPrinterWrapperPassPass(
184*81ad6265SDimitry Andric *PassRegistry::getPassRegistry());
1850b57cec5SDimitry Andric }
1860b57cec5SDimitry Andric };
1870b57cec5SDimitry Andric } // end anonymous namespace
1880b57cec5SDimitry Andric
189*81ad6265SDimitry Andric char DomPrinterWrapperPass::ID = 0;
190*81ad6265SDimitry Andric INITIALIZE_PASS(DomPrinterWrapperPass, "dot-dom",
191*81ad6265SDimitry Andric "Print dominance tree of function to 'dot' file", false, false)
1920b57cec5SDimitry Andric
193*81ad6265SDimitry Andric char DomOnlyPrinterWrapperPass::ID = 0;
194*81ad6265SDimitry Andric INITIALIZE_PASS(DomOnlyPrinterWrapperPass, "dot-dom-only",
1950b57cec5SDimitry Andric "Print dominance tree of function to 'dot' file "
1960b57cec5SDimitry Andric "(with no function bodies)",
1970b57cec5SDimitry Andric false, false)
1980b57cec5SDimitry Andric
199*81ad6265SDimitry Andric char PostDomPrinterWrapperPass::ID = 0;
200*81ad6265SDimitry Andric INITIALIZE_PASS(PostDomPrinterWrapperPass, "dot-postdom",
201*81ad6265SDimitry Andric "Print postdominance tree of function to 'dot' file", false,
202*81ad6265SDimitry Andric false)
2030b57cec5SDimitry Andric
204*81ad6265SDimitry Andric char PostDomOnlyPrinterWrapperPass::ID = 0;
205*81ad6265SDimitry Andric INITIALIZE_PASS(PostDomOnlyPrinterWrapperPass, "dot-postdom-only",
2060b57cec5SDimitry Andric "Print postdominance tree of function to 'dot' file "
2070b57cec5SDimitry Andric "(with no function bodies)",
2080b57cec5SDimitry Andric false, false)
2090b57cec5SDimitry Andric
2100b57cec5SDimitry Andric // Create methods available outside of this file, to use them
2110b57cec5SDimitry Andric // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
2120b57cec5SDimitry Andric // the link time optimization.
2130b57cec5SDimitry Andric
createDomPrinterWrapperPassPass()214*81ad6265SDimitry Andric FunctionPass *llvm::createDomPrinterWrapperPassPass() {
215*81ad6265SDimitry Andric return new DomPrinterWrapperPass();
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric
createDomOnlyPrinterWrapperPassPass()218*81ad6265SDimitry Andric FunctionPass *llvm::createDomOnlyPrinterWrapperPassPass() {
219*81ad6265SDimitry Andric return new DomOnlyPrinterWrapperPass();
2200b57cec5SDimitry Andric }
2210b57cec5SDimitry Andric
createDomViewerWrapperPassPass()222*81ad6265SDimitry Andric FunctionPass *llvm::createDomViewerWrapperPassPass() {
223*81ad6265SDimitry Andric return new DomViewerWrapperPass();
2240b57cec5SDimitry Andric }
2250b57cec5SDimitry Andric
createDomOnlyViewerWrapperPassPass()226*81ad6265SDimitry Andric FunctionPass *llvm::createDomOnlyViewerWrapperPassPass() {
227*81ad6265SDimitry Andric return new DomOnlyViewerWrapperPass();
2280b57cec5SDimitry Andric }
2290b57cec5SDimitry Andric
createPostDomPrinterWrapperPassPass()230*81ad6265SDimitry Andric FunctionPass *llvm::createPostDomPrinterWrapperPassPass() {
231*81ad6265SDimitry Andric return new PostDomPrinterWrapperPass();
2320b57cec5SDimitry Andric }
2330b57cec5SDimitry Andric
createPostDomOnlyPrinterWrapperPassPass()234*81ad6265SDimitry Andric FunctionPass *llvm::createPostDomOnlyPrinterWrapperPassPass() {
235*81ad6265SDimitry Andric return new PostDomOnlyPrinterWrapperPass();
2360b57cec5SDimitry Andric }
2370b57cec5SDimitry Andric
createPostDomViewerWrapperPassPass()238*81ad6265SDimitry Andric FunctionPass *llvm::createPostDomViewerWrapperPassPass() {
239*81ad6265SDimitry Andric return new PostDomViewerWrapperPass();
2400b57cec5SDimitry Andric }
2410b57cec5SDimitry Andric
createPostDomOnlyViewerWrapperPassPass()242*81ad6265SDimitry Andric FunctionPass *llvm::createPostDomOnlyViewerWrapperPassPass() {
243*81ad6265SDimitry Andric return new PostDomOnlyViewerWrapperPass();
2440b57cec5SDimitry Andric }
245