1 //===- DomPrinter.cpp - DOT printer for the dominance trees ------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit 11 // a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the 12 // program, with a graph of the dominance/postdominance tree of that 13 // function. 14 // 15 // There are also passes available to directly call dotty ('-view-dom' or 16 // '-view-postdom'). By appending '-only' like '-dot-dom-only' only the 17 // names of the bbs are printed, but the content is hidden. 18 // 19 //===----------------------------------------------------------------------===// 20 21 #include "llvm/Analysis/DomPrinter.h" 22 23 #include "llvm/Analysis/Dominators.h" 24 #include "llvm/Analysis/DOTGraphTraitsPass.h" 25 #include "llvm/Analysis/PostDominators.h" 26 27 using namespace llvm; 28 29 namespace llvm { 30 template<> 31 struct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits { 32 33 DOTGraphTraits (bool isSimple=false) 34 : DefaultDOTGraphTraits(isSimple) {} 35 36 std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) { 37 38 BasicBlock *BB = Node->getBlock(); 39 40 if (!BB) 41 return "Post dominance root node"; 42 43 44 if (isSimple()) 45 return DOTGraphTraits<const Function*> 46 ::getSimpleNodeLabel(BB, BB->getParent()); 47 else 48 return DOTGraphTraits<const Function*> 49 ::getCompleteNodeLabel(BB, BB->getParent()); 50 } 51 }; 52 53 template<> 54 struct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> { 55 56 DOTGraphTraits (bool isSimple=false) 57 : DOTGraphTraits<DomTreeNode*>(isSimple) {} 58 59 static std::string getGraphName(DominatorTree *DT) { 60 return "Dominator tree"; 61 } 62 63 std::string getNodeLabel(DomTreeNode *Node, DominatorTree *G) { 64 return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode()); 65 } 66 }; 67 68 template<> 69 struct DOTGraphTraits<PostDominatorTree*> 70 : public DOTGraphTraits<DomTreeNode*> { 71 72 DOTGraphTraits (bool isSimple=false) 73 : DOTGraphTraits<DomTreeNode*>(isSimple) {} 74 75 static std::string getGraphName(PostDominatorTree *DT) { 76 return "Post dominator tree"; 77 } 78 79 std::string getNodeLabel(DomTreeNode *Node, PostDominatorTree *G ) { 80 return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode()); 81 } 82 }; 83 } 84 85 namespace { 86 struct DomViewer 87 : public DOTGraphTraitsViewer<DominatorTree, false> { 88 static char ID; 89 DomViewer() : DOTGraphTraitsViewer<DominatorTree, false>("dom", &ID){} 90 }; 91 92 struct DomOnlyViewer 93 : public DOTGraphTraitsViewer<DominatorTree, true> { 94 static char ID; 95 DomOnlyViewer() : DOTGraphTraitsViewer<DominatorTree, true>("domonly", &ID){} 96 }; 97 98 struct PostDomViewer 99 : public DOTGraphTraitsViewer<PostDominatorTree, false> { 100 static char ID; 101 PostDomViewer() : 102 DOTGraphTraitsViewer<PostDominatorTree, false>("postdom", &ID){} 103 }; 104 105 struct PostDomOnlyViewer 106 : public DOTGraphTraitsViewer<PostDominatorTree, true> { 107 static char ID; 108 PostDomOnlyViewer() : 109 DOTGraphTraitsViewer<PostDominatorTree, true>("postdomonly", &ID){} 110 }; 111 } // end anonymous namespace 112 113 char DomViewer::ID = 0; 114 RegisterPass<DomViewer> A("view-dom", 115 "View dominance tree of function"); 116 117 char DomOnlyViewer::ID = 0; 118 RegisterPass<DomOnlyViewer> B("view-dom-only", 119 "View dominance tree of function " 120 "(with no function bodies)"); 121 122 char PostDomViewer::ID = 0; 123 RegisterPass<PostDomViewer> C("view-postdom", 124 "View postdominance tree of function"); 125 126 char PostDomOnlyViewer::ID = 0; 127 RegisterPass<PostDomOnlyViewer> D("view-postdom-only", 128 "View postdominance tree of function " 129 "(with no function bodies)"); 130 131 namespace { 132 struct DomPrinter 133 : public DOTGraphTraitsPrinter<DominatorTree, false> { 134 static char ID; 135 DomPrinter() : DOTGraphTraitsPrinter<DominatorTree, false>("dom", &ID) {} 136 }; 137 138 struct DomOnlyPrinter 139 : public DOTGraphTraitsPrinter<DominatorTree, true> { 140 static char ID; 141 DomOnlyPrinter() : DOTGraphTraitsPrinter<DominatorTree, true>("domonly", &ID) {} 142 }; 143 144 struct PostDomPrinter 145 : public DOTGraphTraitsPrinter<PostDominatorTree, false> { 146 static char ID; 147 PostDomPrinter() : 148 DOTGraphTraitsPrinter<PostDominatorTree, false>("postdom", &ID) {} 149 }; 150 151 struct PostDomOnlyPrinter 152 : public DOTGraphTraitsPrinter<PostDominatorTree, true> { 153 static char ID; 154 PostDomOnlyPrinter() : 155 DOTGraphTraitsPrinter<PostDominatorTree, true>("postdomonly", &ID) {} 156 }; 157 } // end anonymous namespace 158 159 160 161 char DomPrinter::ID = 0; 162 RegisterPass<DomPrinter> E("dot-dom", 163 "Print dominance tree of function " 164 "to 'dot' file"); 165 166 char DomOnlyPrinter::ID = 0; 167 RegisterPass<DomOnlyPrinter> F("dot-dom-only", 168 "Print dominance tree of function " 169 "to 'dot' file " 170 "(with no function bodies)"); 171 172 char PostDomPrinter::ID = 0; 173 RegisterPass<PostDomPrinter> G("dot-postdom", 174 "Print postdominance tree of function " 175 "to 'dot' file"); 176 177 char PostDomOnlyPrinter::ID = 0; 178 RegisterPass<PostDomOnlyPrinter> H("dot-postdom-only", 179 "Print postdominance tree of function " 180 "to 'dot' file " 181 "(with no function bodies)"); 182 183 // Create methods available outside of this file, to use them 184 // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by 185 // the link time optimization. 186 187 FunctionPass *llvm::createDomPrinterPass() { 188 return new DomPrinter(); 189 } 190 191 FunctionPass *llvm::createDomOnlyPrinterPass() { 192 return new DomOnlyPrinter(); 193 } 194 195 FunctionPass *llvm::createDomViewerPass() { 196 return new DomViewer(); 197 } 198 199 FunctionPass *llvm::createDomOnlyViewerPass() { 200 return new DomOnlyViewer(); 201 } 202 203 FunctionPass *llvm::createPostDomPrinterPass() { 204 return new PostDomPrinter(); 205 } 206 207 FunctionPass *llvm::createPostDomOnlyPrinterPass() { 208 return new PostDomOnlyPrinter(); 209 } 210 211 FunctionPass *llvm::createPostDomViewerPass() { 212 return new PostDomViewer(); 213 } 214 215 FunctionPass *llvm::createPostDomOnlyViewerPass() { 216 return new PostDomOnlyViewer(); 217 } 218