LLVM API Documentation
00001 //===- DomPrinter.cpp - DOT printer for the dominance trees ------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines '-dot-dom' and '-dot-postdom' analysis passes, which emit 00011 // a dom.<fnname>.dot or postdom.<fnname>.dot file for each function in the 00012 // program, with a graph of the dominance/postdominance tree of that 00013 // function. 00014 // 00015 // There are also passes available to directly call dotty ('-view-dom' or 00016 // '-view-postdom'). By appending '-only' like '-dot-dom-only' only the 00017 // names of the bbs are printed, but the content is hidden. 00018 // 00019 //===----------------------------------------------------------------------===// 00020 00021 #include "llvm/Analysis/DomPrinter.h" 00022 #include "llvm/Analysis/DOTGraphTraitsPass.h" 00023 #include "llvm/Analysis/PostDominators.h" 00024 00025 using namespace llvm; 00026 00027 namespace llvm { 00028 template<> 00029 struct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits { 00030 00031 DOTGraphTraits (bool isSimple=false) 00032 : DefaultDOTGraphTraits(isSimple) {} 00033 00034 std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) { 00035 00036 BasicBlock *BB = Node->getBlock(); 00037 00038 if (!BB) 00039 return "Post dominance root node"; 00040 00041 00042 if (isSimple()) 00043 return DOTGraphTraits<const Function*> 00044 ::getSimpleNodeLabel(BB, BB->getParent()); 00045 else 00046 return DOTGraphTraits<const Function*> 00047 ::getCompleteNodeLabel(BB, BB->getParent()); 00048 } 00049 }; 00050 00051 template<> 00052 struct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> { 00053 00054 DOTGraphTraits (bool isSimple=false) 00055 : DOTGraphTraits<DomTreeNode*>(isSimple) {} 00056 00057 static std::string getGraphName(DominatorTree *DT) { 00058 return "Dominator tree"; 00059 } 00060 00061 std::string getNodeLabel(DomTreeNode *Node, DominatorTree *G) { 00062 return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode()); 00063 } 00064 }; 00065 00066 template<> 00067 struct DOTGraphTraits<PostDominatorTree*> 00068 : public DOTGraphTraits<DomTreeNode*> { 00069 00070 DOTGraphTraits (bool isSimple=false) 00071 : DOTGraphTraits<DomTreeNode*>(isSimple) {} 00072 00073 static std::string getGraphName(PostDominatorTree *DT) { 00074 return "Post dominator tree"; 00075 } 00076 00077 std::string getNodeLabel(DomTreeNode *Node, PostDominatorTree *G ) { 00078 return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode()); 00079 } 00080 }; 00081 } 00082 00083 namespace { 00084 struct DominatorTreeWrapperPassAnalysisGraphTraits { 00085 static DominatorTree *getGraph(DominatorTreeWrapperPass *DTWP) { 00086 return &DTWP->getDomTree(); 00087 } 00088 }; 00089 00090 struct DomViewer : public DOTGraphTraitsViewer< 00091 DominatorTreeWrapperPass, false, DominatorTree *, 00092 DominatorTreeWrapperPassAnalysisGraphTraits> { 00093 static char ID; 00094 DomViewer() 00095 : DOTGraphTraitsViewer<DominatorTreeWrapperPass, false, DominatorTree *, 00096 DominatorTreeWrapperPassAnalysisGraphTraits>( 00097 "dom", ID) { 00098 initializeDomViewerPass(*PassRegistry::getPassRegistry()); 00099 } 00100 }; 00101 00102 struct DomOnlyViewer : public DOTGraphTraitsViewer< 00103 DominatorTreeWrapperPass, true, DominatorTree *, 00104 DominatorTreeWrapperPassAnalysisGraphTraits> { 00105 static char ID; 00106 DomOnlyViewer() 00107 : DOTGraphTraitsViewer<DominatorTreeWrapperPass, true, DominatorTree *, 00108 DominatorTreeWrapperPassAnalysisGraphTraits>( 00109 "domonly", ID) { 00110 initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry()); 00111 } 00112 }; 00113 00114 struct PostDomViewer 00115 : public DOTGraphTraitsViewer<PostDominatorTree, false> { 00116 static char ID; 00117 PostDomViewer() : 00118 DOTGraphTraitsViewer<PostDominatorTree, false>("postdom", ID){ 00119 initializePostDomViewerPass(*PassRegistry::getPassRegistry()); 00120 } 00121 }; 00122 00123 struct PostDomOnlyViewer 00124 : public DOTGraphTraitsViewer<PostDominatorTree, true> { 00125 static char ID; 00126 PostDomOnlyViewer() : 00127 DOTGraphTraitsViewer<PostDominatorTree, true>("postdomonly", ID){ 00128 initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry()); 00129 } 00130 }; 00131 } // end anonymous namespace 00132 00133 char DomViewer::ID = 0; 00134 INITIALIZE_PASS(DomViewer, "view-dom", 00135 "View dominance tree of function", false, false) 00136 00137 char DomOnlyViewer::ID = 0; 00138 INITIALIZE_PASS(DomOnlyViewer, "view-dom-only", 00139 "View dominance tree of function (with no function bodies)", 00140 false, false) 00141 00142 char PostDomViewer::ID = 0; 00143 INITIALIZE_PASS(PostDomViewer, "view-postdom", 00144 "View postdominance tree of function", false, false) 00145 00146 char PostDomOnlyViewer::ID = 0; 00147 INITIALIZE_PASS(PostDomOnlyViewer, "view-postdom-only", 00148 "View postdominance tree of function " 00149 "(with no function bodies)", 00150 false, false) 00151 00152 namespace { 00153 struct DomPrinter : public DOTGraphTraitsPrinter< 00154 DominatorTreeWrapperPass, false, DominatorTree *, 00155 DominatorTreeWrapperPassAnalysisGraphTraits> { 00156 static char ID; 00157 DomPrinter() 00158 : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, false, DominatorTree *, 00159 DominatorTreeWrapperPassAnalysisGraphTraits>( 00160 "dom", ID) { 00161 initializeDomPrinterPass(*PassRegistry::getPassRegistry()); 00162 } 00163 }; 00164 00165 struct DomOnlyPrinter : public DOTGraphTraitsPrinter< 00166 DominatorTreeWrapperPass, true, DominatorTree *, 00167 DominatorTreeWrapperPassAnalysisGraphTraits> { 00168 static char ID; 00169 DomOnlyPrinter() 00170 : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, true, DominatorTree *, 00171 DominatorTreeWrapperPassAnalysisGraphTraits>( 00172 "domonly", ID) { 00173 initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry()); 00174 } 00175 }; 00176 00177 struct PostDomPrinter 00178 : public DOTGraphTraitsPrinter<PostDominatorTree, false> { 00179 static char ID; 00180 PostDomPrinter() : 00181 DOTGraphTraitsPrinter<PostDominatorTree, false>("postdom", ID) { 00182 initializePostDomPrinterPass(*PassRegistry::getPassRegistry()); 00183 } 00184 }; 00185 00186 struct PostDomOnlyPrinter 00187 : public DOTGraphTraitsPrinter<PostDominatorTree, true> { 00188 static char ID; 00189 PostDomOnlyPrinter() : 00190 DOTGraphTraitsPrinter<PostDominatorTree, true>("postdomonly", ID) { 00191 initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry()); 00192 } 00193 }; 00194 } // end anonymous namespace 00195 00196 00197 00198 char DomPrinter::ID = 0; 00199 INITIALIZE_PASS(DomPrinter, "dot-dom", 00200 "Print dominance tree of function to 'dot' file", 00201 false, false) 00202 00203 char DomOnlyPrinter::ID = 0; 00204 INITIALIZE_PASS(DomOnlyPrinter, "dot-dom-only", 00205 "Print dominance tree of function to 'dot' file " 00206 "(with no function bodies)", 00207 false, false) 00208 00209 char PostDomPrinter::ID = 0; 00210 INITIALIZE_PASS(PostDomPrinter, "dot-postdom", 00211 "Print postdominance tree of function to 'dot' file", 00212 false, false) 00213 00214 char PostDomOnlyPrinter::ID = 0; 00215 INITIALIZE_PASS(PostDomOnlyPrinter, "dot-postdom-only", 00216 "Print postdominance tree of function to 'dot' file " 00217 "(with no function bodies)", 00218 false, false) 00219 00220 // Create methods available outside of this file, to use them 00221 // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by 00222 // the link time optimization. 00223 00224 FunctionPass *llvm::createDomPrinterPass() { 00225 return new DomPrinter(); 00226 } 00227 00228 FunctionPass *llvm::createDomOnlyPrinterPass() { 00229 return new DomOnlyPrinter(); 00230 } 00231 00232 FunctionPass *llvm::createDomViewerPass() { 00233 return new DomViewer(); 00234 } 00235 00236 FunctionPass *llvm::createDomOnlyViewerPass() { 00237 return new DomOnlyViewer(); 00238 } 00239 00240 FunctionPass *llvm::createPostDomPrinterPass() { 00241 return new PostDomPrinter(); 00242 } 00243 00244 FunctionPass *llvm::createPostDomOnlyPrinterPass() { 00245 return new PostDomOnlyPrinter(); 00246 } 00247 00248 FunctionPass *llvm::createPostDomViewerPass() { 00249 return new PostDomViewer(); 00250 } 00251 00252 FunctionPass *llvm::createPostDomOnlyViewerPass() { 00253 return new PostDomOnlyViewer(); 00254 }