1 //===-- DOTGraphTraitsPass.h - Print/View dotty graphs-----------*- C++ -*-===// 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 // Templates to create dotty viewer and printer passes for GraphTraits graphs. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H 15 #define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H 16 17 #include "llvm/Analysis/CFGPrinter.h" 18 #include "llvm/Pass.h" 19 #include "llvm/Support/FileSystem.h" 20 21 namespace llvm { 22 23 /// \brief Default traits class for extracting a graph from an analysis pass. 24 /// 25 /// This assumes that 'GraphT' is 'AnalysisT *' and so just passes it through. 26 template <typename AnalysisT, typename GraphT = AnalysisT *> 27 struct DefaultAnalysisGraphTraits { getGraphDefaultAnalysisGraphTraits28 static GraphT getGraph(AnalysisT *A) { return A; } 29 }; 30 31 template < 32 typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 33 typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 34 class DOTGraphTraitsViewer : public FunctionPass { 35 public: DOTGraphTraitsViewer(StringRef GraphName,char & ID)36 DOTGraphTraitsViewer(StringRef GraphName, char &ID) 37 : FunctionPass(ID), Name(GraphName) {} 38 runOnFunction(Function & F)39 bool runOnFunction(Function &F) override { 40 GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); 41 std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph); 42 std::string Title = GraphName + " for '" + F.getName().str() + "' function"; 43 44 ViewGraph(Graph, Name, IsSimple, Title); 45 46 return false; 47 } 48 getAnalysisUsage(AnalysisUsage & AU)49 void getAnalysisUsage(AnalysisUsage &AU) const override { 50 AU.setPreservesAll(); 51 AU.addRequired<AnalysisT>(); 52 } 53 54 private: 55 std::string Name; 56 }; 57 58 template < 59 typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 60 typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 61 class DOTGraphTraitsPrinter : public FunctionPass { 62 public: DOTGraphTraitsPrinter(StringRef GraphName,char & ID)63 DOTGraphTraitsPrinter(StringRef GraphName, char &ID) 64 : FunctionPass(ID), Name(GraphName) {} 65 runOnFunction(Function & F)66 bool runOnFunction(Function &F) override { 67 GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); 68 std::string Filename = Name + "." + F.getName().str() + ".dot"; 69 std::error_code EC; 70 71 errs() << "Writing '" << Filename << "'..."; 72 73 raw_fd_ostream File(Filename, EC, sys::fs::F_Text); 74 std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph); 75 std::string Title = GraphName + " for '" + F.getName().str() + "' function"; 76 77 if (!EC) 78 WriteGraph(File, Graph, IsSimple, Title); 79 else 80 errs() << " error opening file for writing!"; 81 errs() << "\n"; 82 83 return false; 84 } 85 getAnalysisUsage(AnalysisUsage & AU)86 void getAnalysisUsage(AnalysisUsage &AU) const override { 87 AU.setPreservesAll(); 88 AU.addRequired<AnalysisT>(); 89 } 90 91 private: 92 std::string Name; 93 }; 94 95 template < 96 typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 97 typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 98 class DOTGraphTraitsModuleViewer : public ModulePass { 99 public: DOTGraphTraitsModuleViewer(StringRef GraphName,char & ID)100 DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID) 101 : ModulePass(ID), Name(GraphName) {} 102 runOnModule(Module & M)103 bool runOnModule(Module &M) override { 104 GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); 105 std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph); 106 107 ViewGraph(Graph, Name, IsSimple, Title); 108 109 return false; 110 } 111 getAnalysisUsage(AnalysisUsage & AU)112 void getAnalysisUsage(AnalysisUsage &AU) const override { 113 AU.setPreservesAll(); 114 AU.addRequired<AnalysisT>(); 115 } 116 117 private: 118 std::string Name; 119 }; 120 121 template < 122 typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 123 typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 124 class DOTGraphTraitsModulePrinter : public ModulePass { 125 public: DOTGraphTraitsModulePrinter(StringRef GraphName,char & ID)126 DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID) 127 : ModulePass(ID), Name(GraphName) {} 128 runOnModule(Module & M)129 bool runOnModule(Module &M) override { 130 GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); 131 std::string Filename = Name + ".dot"; 132 std::error_code EC; 133 134 errs() << "Writing '" << Filename << "'..."; 135 136 raw_fd_ostream File(Filename, EC, sys::fs::F_Text); 137 std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph); 138 139 if (!EC) 140 WriteGraph(File, Graph, IsSimple, Title); 141 else 142 errs() << " error opening file for writing!"; 143 errs() << "\n"; 144 145 return false; 146 } 147 getAnalysisUsage(AnalysisUsage & AU)148 void getAnalysisUsage(AnalysisUsage &AU) const override { 149 AU.setPreservesAll(); 150 AU.addRequired<AnalysisT>(); 151 } 152 153 private: 154 std::string Name; 155 }; 156 157 } // end namespace llvm 158 159 #endif 160