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 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 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 { 46 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; 56 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; 69 DomOnlyViewerWrapperPass() 70 : DOTGraphTraitsViewerWrapperPass< 71 DominatorTreeWrapperPass, true, DominatorTree *, 72 LegacyDominatorTreeWrapperPassAnalysisGraphTraits>("domonly", ID) { 73 initializeDomOnlyViewerWrapperPassPass(*PassRegistry::getPassRegistry()); 74 } 75 }; 76 77 struct LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits { 78 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; 88 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; 102 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; 138 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; 151 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; 164 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; 178 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 214 FunctionPass *llvm::createDomPrinterWrapperPassPass() { 215 return new DomPrinterWrapperPass(); 216 } 217 218 FunctionPass *llvm::createDomOnlyPrinterWrapperPassPass() { 219 return new DomOnlyPrinterWrapperPass(); 220 } 221 222 FunctionPass *llvm::createDomViewerWrapperPassPass() { 223 return new DomViewerWrapperPass(); 224 } 225 226 FunctionPass *llvm::createDomOnlyViewerWrapperPassPass() { 227 return new DomOnlyViewerWrapperPass(); 228 } 229 230 FunctionPass *llvm::createPostDomPrinterWrapperPassPass() { 231 return new PostDomPrinterWrapperPass(); 232 } 233 234 FunctionPass *llvm::createPostDomOnlyPrinterWrapperPassPass() { 235 return new PostDomOnlyPrinterWrapperPass(); 236 } 237 238 FunctionPass *llvm::createPostDomViewerWrapperPassPass() { 239 return new PostDomViewerWrapperPass(); 240 } 241 242 FunctionPass *llvm::createPostDomOnlyViewerWrapperPassPass() { 243 return new PostDomOnlyViewerWrapperPass(); 244 } 245