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 }; 61 62 struct 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 73 struct LegacyPostDominatorTreeWrapperPassAnalysisGraphTraits { 74 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; 84 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; 96 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; 129 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; 140 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; 151 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; 163 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 196 FunctionPass *llvm::createDomPrinterWrapperPassPass() { 197 return new DomPrinterWrapperPass(); 198 } 199 200 FunctionPass *llvm::createDomOnlyPrinterWrapperPassPass() { 201 return new DomOnlyPrinterWrapperPass(); 202 } 203 204 FunctionPass *llvm::createDomViewerWrapperPassPass() { 205 return new DomViewerWrapperPass(); 206 } 207 208 FunctionPass *llvm::createDomOnlyViewerWrapperPassPass() { 209 return new DomOnlyViewerWrapperPass(); 210 } 211 212 FunctionPass *llvm::createPostDomPrinterWrapperPassPass() { 213 return new PostDomPrinterWrapperPass(); 214 } 215 216 FunctionPass *llvm::createPostDomOnlyPrinterWrapperPassPass() { 217 return new PostDomOnlyPrinterWrapperPass(); 218 } 219 220 FunctionPass *llvm::createPostDomViewerWrapperPassPass() { 221 return new PostDomViewerWrapperPass(); 222 } 223 224 FunctionPass *llvm::createPostDomOnlyViewerWrapperPassPass() { 225 return new PostDomOnlyViewerWrapperPass(); 226 } 227