DomPrinter.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  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. #include "llvm/Analysis/DomPrinter.h"
  21. #include "llvm/Analysis/DOTGraphTraitsPass.h"
  22. #include "llvm/Analysis/PostDominators.h"
  23. using namespace llvm;
  24. namespace llvm {
  25. template<>
  26. struct DOTGraphTraits<DomTreeNode*> : public DefaultDOTGraphTraits {
  27. DOTGraphTraits (bool isSimple=false)
  28. : DefaultDOTGraphTraits(isSimple) {}
  29. std::string getNodeLabel(DomTreeNode *Node, DomTreeNode *Graph) {
  30. BasicBlock *BB = Node->getBlock();
  31. if (!BB)
  32. return "Post dominance root node";
  33. if (isSimple())
  34. return DOTGraphTraits<const Function*>
  35. ::getSimpleNodeLabel(BB, BB->getParent());
  36. else
  37. return DOTGraphTraits<const Function*>
  38. ::getCompleteNodeLabel(BB, BB->getParent());
  39. }
  40. };
  41. template<>
  42. struct DOTGraphTraits<DominatorTree*> : public DOTGraphTraits<DomTreeNode*> {
  43. DOTGraphTraits (bool isSimple=false)
  44. : DOTGraphTraits<DomTreeNode*>(isSimple) {}
  45. static std::string getGraphName(DominatorTree *DT) {
  46. return "Dominator tree";
  47. }
  48. std::string getNodeLabel(DomTreeNode *Node, DominatorTree *G) {
  49. return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
  50. }
  51. };
  52. template<>
  53. struct DOTGraphTraits<PostDominatorTree*>
  54. : public DOTGraphTraits<DomTreeNode*> {
  55. DOTGraphTraits (bool isSimple=false)
  56. : DOTGraphTraits<DomTreeNode*>(isSimple) {}
  57. static std::string getGraphName(PostDominatorTree *DT) {
  58. return "Post dominator tree";
  59. }
  60. std::string getNodeLabel(DomTreeNode *Node, PostDominatorTree *G ) {
  61. return DOTGraphTraits<DomTreeNode*>::getNodeLabel(Node, G->getRootNode());
  62. }
  63. };
  64. }
  65. namespace {
  66. struct DominatorTreeWrapperPassAnalysisGraphTraits {
  67. static DominatorTree *getGraph(DominatorTreeWrapperPass *DTWP) {
  68. return &DTWP->getDomTree();
  69. }
  70. };
  71. struct DomViewer : public DOTGraphTraitsViewer<
  72. DominatorTreeWrapperPass, false, DominatorTree *,
  73. DominatorTreeWrapperPassAnalysisGraphTraits> {
  74. static char ID;
  75. DomViewer()
  76. : DOTGraphTraitsViewer<DominatorTreeWrapperPass, false, DominatorTree *,
  77. DominatorTreeWrapperPassAnalysisGraphTraits>(
  78. "dom", ID) {
  79. initializeDomViewerPass(*PassRegistry::getPassRegistry());
  80. }
  81. };
  82. struct DomOnlyViewer : public DOTGraphTraitsViewer<
  83. DominatorTreeWrapperPass, true, DominatorTree *,
  84. DominatorTreeWrapperPassAnalysisGraphTraits> {
  85. static char ID;
  86. DomOnlyViewer()
  87. : DOTGraphTraitsViewer<DominatorTreeWrapperPass, true, DominatorTree *,
  88. DominatorTreeWrapperPassAnalysisGraphTraits>(
  89. "domonly", ID) {
  90. initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry());
  91. }
  92. };
  93. struct PostDomViewer
  94. : public DOTGraphTraitsViewer<PostDominatorTree, false> {
  95. static char ID;
  96. PostDomViewer() :
  97. DOTGraphTraitsViewer<PostDominatorTree, false>("postdom", ID){
  98. initializePostDomViewerPass(*PassRegistry::getPassRegistry());
  99. }
  100. };
  101. struct PostDomOnlyViewer
  102. : public DOTGraphTraitsViewer<PostDominatorTree, true> {
  103. static char ID;
  104. PostDomOnlyViewer() :
  105. DOTGraphTraitsViewer<PostDominatorTree, true>("postdomonly", ID){
  106. initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry());
  107. }
  108. };
  109. } // end anonymous namespace
  110. char DomViewer::ID = 0;
  111. INITIALIZE_PASS(DomViewer, "view-dom",
  112. "View dominance tree of function", false, false)
  113. char DomOnlyViewer::ID = 0;
  114. INITIALIZE_PASS(DomOnlyViewer, "view-dom-only",
  115. "View dominance tree of function (with no function bodies)",
  116. false, false)
  117. char PostDomViewer::ID = 0;
  118. INITIALIZE_PASS(PostDomViewer, "view-postdom",
  119. "View postdominance tree of function", false, false)
  120. char PostDomOnlyViewer::ID = 0;
  121. INITIALIZE_PASS(PostDomOnlyViewer, "view-postdom-only",
  122. "View postdominance tree of function "
  123. "(with no function bodies)",
  124. false, false)
  125. namespace {
  126. struct DomPrinter : public DOTGraphTraitsPrinter<
  127. DominatorTreeWrapperPass, false, DominatorTree *,
  128. DominatorTreeWrapperPassAnalysisGraphTraits> {
  129. static char ID;
  130. DomPrinter()
  131. : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, false, DominatorTree *,
  132. DominatorTreeWrapperPassAnalysisGraphTraits>(
  133. "dom", ID) {
  134. initializeDomPrinterPass(*PassRegistry::getPassRegistry());
  135. }
  136. };
  137. struct DomOnlyPrinter : public DOTGraphTraitsPrinter<
  138. DominatorTreeWrapperPass, true, DominatorTree *,
  139. DominatorTreeWrapperPassAnalysisGraphTraits> {
  140. static char ID;
  141. DomOnlyPrinter()
  142. : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, true, DominatorTree *,
  143. DominatorTreeWrapperPassAnalysisGraphTraits>(
  144. "domonly", ID) {
  145. initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
  146. }
  147. };
  148. struct PostDomPrinter
  149. : public DOTGraphTraitsPrinter<PostDominatorTree, false> {
  150. static char ID;
  151. PostDomPrinter() :
  152. DOTGraphTraitsPrinter<PostDominatorTree, false>("postdom", ID) {
  153. initializePostDomPrinterPass(*PassRegistry::getPassRegistry());
  154. }
  155. };
  156. struct PostDomOnlyPrinter
  157. : public DOTGraphTraitsPrinter<PostDominatorTree, true> {
  158. static char ID;
  159. PostDomOnlyPrinter() :
  160. DOTGraphTraitsPrinter<PostDominatorTree, true>("postdomonly", ID) {
  161. initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
  162. }
  163. };
  164. } // end anonymous namespace
  165. char DomPrinter::ID = 0;
  166. INITIALIZE_PASS(DomPrinter, "dot-dom",
  167. "Print dominance tree of function to 'dot' file",
  168. false, false)
  169. char DomOnlyPrinter::ID = 0;
  170. INITIALIZE_PASS(DomOnlyPrinter, "dot-dom-only",
  171. "Print dominance tree of function to 'dot' file "
  172. "(with no function bodies)",
  173. false, false)
  174. char PostDomPrinter::ID = 0;
  175. INITIALIZE_PASS(PostDomPrinter, "dot-postdom",
  176. "Print postdominance tree of function to 'dot' file",
  177. false, false)
  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. // 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. FunctionPass *llvm::createDomPrinterPass() {
  187. return new DomPrinter();
  188. }
  189. FunctionPass *llvm::createDomOnlyPrinterPass() {
  190. return new DomOnlyPrinter();
  191. }
  192. FunctionPass *llvm::createDomViewerPass() {
  193. return new DomViewer();
  194. }
  195. FunctionPass *llvm::createDomOnlyViewerPass() {
  196. return new DomOnlyViewer();
  197. }
  198. FunctionPass *llvm::createPostDomPrinterPass() {
  199. return new PostDomPrinter();
  200. }
  201. FunctionPass *llvm::createPostDomOnlyPrinterPass() {
  202. return new PostDomOnlyPrinter();
  203. }
  204. FunctionPass *llvm::createPostDomViewerPass() {
  205. return new PostDomViewer();
  206. }
  207. FunctionPass *llvm::createPostDomOnlyViewerPass() {
  208. return new PostDomOnlyViewer();
  209. }