DomPrinter.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  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. #include "llvm/Analysis/DomPrinter.h"
  20. #include "llvm/Analysis/DOTGraphTraitsPass.h"
  21. #include "llvm/Analysis/PostDominators.h"
  22. #include "llvm/InitializePasses.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<DOTFuncInfo *>
  35. ::getSimpleNodeLabel(BB, nullptr);
  36. else
  37. return DOTGraphTraits<DOTFuncInfo *>
  38. ::getCompleteNodeLabel(BB, nullptr);
  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. PreservedAnalyses DomTreePrinterPass::run(Function &F,
  66. FunctionAnalysisManager &AM) {
  67. WriteDOTGraphToFile(F, &AM.getResult<DominatorTreeAnalysis>(F), "dom", false);
  68. return PreservedAnalyses::all();
  69. }
  70. PreservedAnalyses DomTreeOnlyPrinterPass::run(Function &F,
  71. FunctionAnalysisManager &AM) {
  72. WriteDOTGraphToFile(F, &AM.getResult<DominatorTreeAnalysis>(F), "domonly",
  73. true);
  74. return PreservedAnalyses::all();
  75. }
  76. void DominatorTree::viewGraph(const Twine &Name, const Twine &Title) {
  77. #ifndef NDEBUG
  78. ViewGraph(this, Name, false, Title);
  79. #else
  80. errs() << "DomTree dump not available, build with DEBUG\n";
  81. #endif // NDEBUG
  82. }
  83. void DominatorTree::viewGraph() {
  84. #ifndef NDEBUG
  85. this->viewGraph("domtree", "Dominator Tree for function");
  86. #else
  87. errs() << "DomTree dump not available, build with DEBUG\n";
  88. #endif // NDEBUG
  89. }
  90. namespace {
  91. struct DominatorTreeWrapperPassAnalysisGraphTraits {
  92. static DominatorTree *getGraph(DominatorTreeWrapperPass *DTWP) {
  93. return &DTWP->getDomTree();
  94. }
  95. };
  96. struct DomViewer : public DOTGraphTraitsViewer<
  97. DominatorTreeWrapperPass, false, DominatorTree *,
  98. DominatorTreeWrapperPassAnalysisGraphTraits> {
  99. static char ID;
  100. DomViewer()
  101. : DOTGraphTraitsViewer<DominatorTreeWrapperPass, false, DominatorTree *,
  102. DominatorTreeWrapperPassAnalysisGraphTraits>(
  103. "dom", ID) {
  104. initializeDomViewerPass(*PassRegistry::getPassRegistry());
  105. }
  106. };
  107. struct DomOnlyViewer : public DOTGraphTraitsViewer<
  108. DominatorTreeWrapperPass, true, DominatorTree *,
  109. DominatorTreeWrapperPassAnalysisGraphTraits> {
  110. static char ID;
  111. DomOnlyViewer()
  112. : DOTGraphTraitsViewer<DominatorTreeWrapperPass, true, DominatorTree *,
  113. DominatorTreeWrapperPassAnalysisGraphTraits>(
  114. "domonly", ID) {
  115. initializeDomOnlyViewerPass(*PassRegistry::getPassRegistry());
  116. }
  117. };
  118. struct PostDominatorTreeWrapperPassAnalysisGraphTraits {
  119. static PostDominatorTree *getGraph(PostDominatorTreeWrapperPass *PDTWP) {
  120. return &PDTWP->getPostDomTree();
  121. }
  122. };
  123. struct PostDomViewer : public DOTGraphTraitsViewer<
  124. PostDominatorTreeWrapperPass, false,
  125. PostDominatorTree *,
  126. PostDominatorTreeWrapperPassAnalysisGraphTraits> {
  127. static char ID;
  128. PostDomViewer() :
  129. DOTGraphTraitsViewer<PostDominatorTreeWrapperPass, false,
  130. PostDominatorTree *,
  131. PostDominatorTreeWrapperPassAnalysisGraphTraits>(
  132. "postdom", ID){
  133. initializePostDomViewerPass(*PassRegistry::getPassRegistry());
  134. }
  135. };
  136. struct PostDomOnlyViewer : public DOTGraphTraitsViewer<
  137. PostDominatorTreeWrapperPass, true,
  138. PostDominatorTree *,
  139. PostDominatorTreeWrapperPassAnalysisGraphTraits> {
  140. static char ID;
  141. PostDomOnlyViewer() :
  142. DOTGraphTraitsViewer<PostDominatorTreeWrapperPass, true,
  143. PostDominatorTree *,
  144. PostDominatorTreeWrapperPassAnalysisGraphTraits>(
  145. "postdomonly", ID){
  146. initializePostDomOnlyViewerPass(*PassRegistry::getPassRegistry());
  147. }
  148. };
  149. } // end anonymous namespace
  150. char DomViewer::ID = 0;
  151. INITIALIZE_PASS(DomViewer, "view-dom",
  152. "View dominance tree of function", false, false)
  153. char DomOnlyViewer::ID = 0;
  154. INITIALIZE_PASS(DomOnlyViewer, "view-dom-only",
  155. "View dominance tree of function (with no function bodies)",
  156. false, false)
  157. char PostDomViewer::ID = 0;
  158. INITIALIZE_PASS(PostDomViewer, "view-postdom",
  159. "View postdominance tree of function", false, false)
  160. char PostDomOnlyViewer::ID = 0;
  161. INITIALIZE_PASS(PostDomOnlyViewer, "view-postdom-only",
  162. "View postdominance tree of function "
  163. "(with no function bodies)",
  164. false, false)
  165. namespace {
  166. struct DomPrinter : public DOTGraphTraitsPrinter<
  167. DominatorTreeWrapperPass, false, DominatorTree *,
  168. DominatorTreeWrapperPassAnalysisGraphTraits> {
  169. static char ID;
  170. DomPrinter()
  171. : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, false, DominatorTree *,
  172. DominatorTreeWrapperPassAnalysisGraphTraits>(
  173. "dom", ID) {
  174. initializeDomPrinterPass(*PassRegistry::getPassRegistry());
  175. }
  176. };
  177. struct DomOnlyPrinter : public DOTGraphTraitsPrinter<
  178. DominatorTreeWrapperPass, true, DominatorTree *,
  179. DominatorTreeWrapperPassAnalysisGraphTraits> {
  180. static char ID;
  181. DomOnlyPrinter()
  182. : DOTGraphTraitsPrinter<DominatorTreeWrapperPass, true, DominatorTree *,
  183. DominatorTreeWrapperPassAnalysisGraphTraits>(
  184. "domonly", ID) {
  185. initializeDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
  186. }
  187. };
  188. struct PostDomPrinter
  189. : public DOTGraphTraitsPrinter<
  190. PostDominatorTreeWrapperPass, false,
  191. PostDominatorTree *,
  192. PostDominatorTreeWrapperPassAnalysisGraphTraits> {
  193. static char ID;
  194. PostDomPrinter() :
  195. DOTGraphTraitsPrinter<PostDominatorTreeWrapperPass, false,
  196. PostDominatorTree *,
  197. PostDominatorTreeWrapperPassAnalysisGraphTraits>(
  198. "postdom", ID) {
  199. initializePostDomPrinterPass(*PassRegistry::getPassRegistry());
  200. }
  201. };
  202. struct PostDomOnlyPrinter
  203. : public DOTGraphTraitsPrinter<
  204. PostDominatorTreeWrapperPass, true,
  205. PostDominatorTree *,
  206. PostDominatorTreeWrapperPassAnalysisGraphTraits> {
  207. static char ID;
  208. PostDomOnlyPrinter() :
  209. DOTGraphTraitsPrinter<PostDominatorTreeWrapperPass, true,
  210. PostDominatorTree *,
  211. PostDominatorTreeWrapperPassAnalysisGraphTraits>(
  212. "postdomonly", ID) {
  213. initializePostDomOnlyPrinterPass(*PassRegistry::getPassRegistry());
  214. }
  215. };
  216. } // end anonymous namespace
  217. char DomPrinter::ID = 0;
  218. INITIALIZE_PASS(DomPrinter, "dot-dom",
  219. "Print dominance tree of function to 'dot' file",
  220. false, false)
  221. char DomOnlyPrinter::ID = 0;
  222. INITIALIZE_PASS(DomOnlyPrinter, "dot-dom-only",
  223. "Print dominance tree of function to 'dot' file "
  224. "(with no function bodies)",
  225. false, false)
  226. char PostDomPrinter::ID = 0;
  227. INITIALIZE_PASS(PostDomPrinter, "dot-postdom",
  228. "Print postdominance tree of function to 'dot' file",
  229. false, false)
  230. char PostDomOnlyPrinter::ID = 0;
  231. INITIALIZE_PASS(PostDomOnlyPrinter, "dot-postdom-only",
  232. "Print postdominance tree of function to 'dot' file "
  233. "(with no function bodies)",
  234. false, false)
  235. // Create methods available outside of this file, to use them
  236. // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
  237. // the link time optimization.
  238. FunctionPass *llvm::createDomPrinterPass() {
  239. return new DomPrinter();
  240. }
  241. FunctionPass *llvm::createDomOnlyPrinterPass() {
  242. return new DomOnlyPrinter();
  243. }
  244. FunctionPass *llvm::createDomViewerPass() {
  245. return new DomViewer();
  246. }
  247. FunctionPass *llvm::createDomOnlyViewerPass() {
  248. return new DomOnlyViewer();
  249. }
  250. FunctionPass *llvm::createPostDomPrinterPass() {
  251. return new PostDomPrinter();
  252. }
  253. FunctionPass *llvm::createPostDomOnlyPrinterPass() {
  254. return new PostDomOnlyPrinter();
  255. }
  256. FunctionPass *llvm::createPostDomViewerPass() {
  257. return new PostDomViewer();
  258. }
  259. FunctionPass *llvm::createPostDomOnlyViewerPass() {
  260. return new PostDomOnlyViewer();
  261. }