LLVM API Documentation
00001 //===-- DOTGraphTraitsPass.h - Print/View dotty graphs-----------*- C++ -*-===// 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 // Templates to create dotty viewer and printer passes for GraphTraits graphs. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H 00015 #define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H 00016 00017 #include "llvm/Analysis/CFGPrinter.h" 00018 #include "llvm/Pass.h" 00019 #include "llvm/Support/FileSystem.h" 00020 00021 namespace llvm { 00022 00023 /// \brief Default traits class for extracting a graph from an analysis pass. 00024 /// 00025 /// This assumes that 'GraphT' is 'AnalysisT *' and so just passes it through. 00026 template <typename AnalysisT, typename GraphT = AnalysisT *> 00027 struct DefaultAnalysisGraphTraits { 00028 static GraphT getGraph(AnalysisT *A) { return A; } 00029 }; 00030 00031 template < 00032 typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 00033 typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 00034 class DOTGraphTraitsViewer : public FunctionPass { 00035 public: 00036 DOTGraphTraitsViewer(StringRef GraphName, char &ID) 00037 : FunctionPass(ID), Name(GraphName) {} 00038 00039 bool runOnFunction(Function &F) override { 00040 GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); 00041 std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph); 00042 std::string Title = GraphName + " for '" + F.getName().str() + "' function"; 00043 00044 ViewGraph(Graph, Name, IsSimple, Title); 00045 00046 return false; 00047 } 00048 00049 void getAnalysisUsage(AnalysisUsage &AU) const override { 00050 AU.setPreservesAll(); 00051 AU.addRequired<AnalysisT>(); 00052 } 00053 00054 private: 00055 std::string Name; 00056 }; 00057 00058 template < 00059 typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 00060 typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 00061 class DOTGraphTraitsPrinter : public FunctionPass { 00062 public: 00063 DOTGraphTraitsPrinter(StringRef GraphName, char &ID) 00064 : FunctionPass(ID), Name(GraphName) {} 00065 00066 bool runOnFunction(Function &F) override { 00067 GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); 00068 std::string Filename = Name + "." + F.getName().str() + ".dot"; 00069 std::error_code EC; 00070 00071 errs() << "Writing '" << Filename << "'..."; 00072 00073 raw_fd_ostream File(Filename, EC, sys::fs::F_Text); 00074 std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph); 00075 std::string Title = GraphName + " for '" + F.getName().str() + "' function"; 00076 00077 if (!EC) 00078 WriteGraph(File, Graph, IsSimple, Title); 00079 else 00080 errs() << " error opening file for writing!"; 00081 errs() << "\n"; 00082 00083 return false; 00084 } 00085 00086 void getAnalysisUsage(AnalysisUsage &AU) const override { 00087 AU.setPreservesAll(); 00088 AU.addRequired<AnalysisT>(); 00089 } 00090 00091 private: 00092 std::string Name; 00093 }; 00094 00095 template < 00096 typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 00097 typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 00098 class DOTGraphTraitsModuleViewer : public ModulePass { 00099 public: 00100 DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID) 00101 : ModulePass(ID), Name(GraphName) {} 00102 00103 bool runOnModule(Module &M) override { 00104 GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); 00105 std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph); 00106 00107 ViewGraph(Graph, Name, IsSimple, Title); 00108 00109 return false; 00110 } 00111 00112 void getAnalysisUsage(AnalysisUsage &AU) const override { 00113 AU.setPreservesAll(); 00114 AU.addRequired<AnalysisT>(); 00115 } 00116 00117 private: 00118 std::string Name; 00119 }; 00120 00121 template < 00122 typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 00123 typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 00124 class DOTGraphTraitsModulePrinter : public ModulePass { 00125 public: 00126 DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID) 00127 : ModulePass(ID), Name(GraphName) {} 00128 00129 bool runOnModule(Module &M) override { 00130 GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); 00131 std::string Filename = Name + ".dot"; 00132 std::error_code EC; 00133 00134 errs() << "Writing '" << Filename << "'..."; 00135 00136 raw_fd_ostream File(Filename, EC, sys::fs::F_Text); 00137 std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph); 00138 00139 if (!EC) 00140 WriteGraph(File, Graph, IsSimple, Title); 00141 else 00142 errs() << " error opening file for writing!"; 00143 errs() << "\n"; 00144 00145 return false; 00146 } 00147 00148 void getAnalysisUsage(AnalysisUsage &AU) const override { 00149 AU.setPreservesAll(); 00150 AU.addRequired<AnalysisT>(); 00151 } 00152 00153 private: 00154 std::string Name; 00155 }; 00156 00157 } // end namespace llvm 00158 00159 #endif