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 INITIALIZE_PASS(DomViewer, "view-dom", 115 "View dominance tree of function", false, false); 116 117 char DomOnlyViewer::ID = 0; 118 INITIALIZE_PASS(DomOnlyViewer, "view-dom-only", 119 "View dominance tree of function (with no function bodies)", 120 false, false); 121 122 char PostDomViewer::ID = 0; 123 INITIALIZE_PASS(PostDomViewer, "view-postdom", 124 "View postdominance tree of function", false, false); 125 126 char PostDomOnlyViewer::ID = 0; 127 INITIALIZE_PASS(PostDomOnlyViewer, "view-postdom-only", 128 "View postdominance tree of function " 129 "(with no function bodies)", 130 false, false); 131 132 namespace { 133 struct DomPrinter 134 : public DOTGraphTraitsPrinter<DominatorTree, false> { 135 static char ID; 136 DomPrinter() : DOTGraphTraitsPrinter<DominatorTree, false>("dom", &ID) {} 137 }; 138 139 struct DomOnlyPrinter 140 : public DOTGraphTraitsPrinter<DominatorTree, true> { 141 static char ID; 142 DomOnlyPrinter() : DOTGraphTraitsPrinter<DominatorTree, true>("domonly", &ID) {} 143 }; 144 145 struct PostDomPrinter 146 : public DOTGraphTraitsPrinter<PostDominatorTree, false> { 147 static char ID; 148 PostDomPrinter() : 149 DOTGraphTraitsPrinter<PostDominatorTree, false>("postdom", &ID) {} 150 }; 151 152 struct PostDomOnlyPrinter 153 : public DOTGraphTraitsPrinter<PostDominatorTree, true> { 154 static char ID; 155 PostDomOnlyPrinter() : 156 DOTGraphTraitsPrinter<PostDominatorTree, true>("postdomonly", &ID) {} 157 }; 158 } // end anonymous namespace 159 160 161 162 char DomPrinter::ID = 0; 163 INITIALIZE_PASS(DomPrinter, "dot-dom", 164 "Print dominance tree of function to 'dot' file", 165 false, false); 166 167 char DomOnlyPrinter::ID = 0; 168 INITIALIZE_PASS(DomOnlyPrinter, "dot-dom-only", 169 "Print dominance tree of function to 'dot' file " 170 "(with no function bodies)", 171 false, false); 172 173 char PostDomPrinter::ID = 0; 174 INITIALIZE_PASS(PostDomPrinter, "dot-postdom", 175 "Print postdominance tree of function to 'dot' file", 176 false, false); 177 178 char PostDomOnlyPrinter::ID = 0; 179 INITIALIZE_PASS(PostDomOnlyPrinter, "dot-postdom-only", 180 "Print postdominance tree of function to 'dot' file " 181 "(with no function bodies)", 182 false, false); 183 184 // Create methods available outside of this file, to use them 185 // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by 186 // the link time optimization. 187 188 FunctionPass *llvm::createDomPrinterPass() { 189 return new DomPrinter(); 190 } 191 192 FunctionPass *llvm::createDomOnlyPrinterPass() { 193 return new DomOnlyPrinter(); 194 } 195 196 FunctionPass *llvm::createDomViewerPass() { 197 return new DomViewer(); 198 } 199 200 FunctionPass *llvm::createDomOnlyViewerPass() { 201 return new DomOnlyViewer(); 202 } 203 204 FunctionPass *llvm::createPostDomPrinterPass() { 205 return new PostDomPrinter(); 206 } 207 208 FunctionPass *llvm::createPostDomOnlyPrinterPass() { 209 return new PostDomOnlyPrinter(); 210 } 211 212 FunctionPass *llvm::createPostDomViewerPass() { 213 return new PostDomViewer(); 214 } 215 216 FunctionPass *llvm::createPostDomOnlyViewerPass() { 217 return new PostDomOnlyViewer(); 218 } 219