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 21namespace 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. 26template <typename AnalysisT, typename GraphT = AnalysisT *> 27struct DefaultAnalysisGraphTraits { 28 static GraphT getGraph(AnalysisT *A) { return A; } 29}; 30 31template < 32 typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 33 typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 34class DOTGraphTraitsViewer : public FunctionPass { 35public: 36 DOTGraphTraitsViewer(StringRef GraphName, char &ID) 37 : FunctionPass(ID), Name(GraphName) {} 38 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 49 void getAnalysisUsage(AnalysisUsage &AU) const override { 50 AU.setPreservesAll(); 51 AU.addRequired<AnalysisT>(); 52 } 53 54private: 55 std::string Name; 56}; 57 58template < 59 typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 60 typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 61class DOTGraphTraitsPrinter : public FunctionPass { 62public: 63 DOTGraphTraitsPrinter(StringRef GraphName, char &ID) 64 : FunctionPass(ID), Name(GraphName) {} 65 66 bool runOnFunction(Function &F) override { 67 GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); 68 std::string Filename = Name + "." + F.getName().str() + ".dot"; 69 std::string ErrorInfo; 70 71 errs() << "Writing '" << Filename << "'..."; 72 73 raw_fd_ostream File(Filename.c_str(), ErrorInfo, 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 (ErrorInfo.empty()) 78 WriteGraph(File, Graph, IsSimple, Title); 79 else 80 errs() << " error opening file for writing!"; 81 errs() << "\n"; 82 83 return false; 84 } 85 86 void getAnalysisUsage(AnalysisUsage &AU) const override { 87 AU.setPreservesAll(); 88 AU.addRequired<AnalysisT>(); 89 } 90 91private: 92 std::string Name; 93}; 94 95template < 96 typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 97 typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 98class DOTGraphTraitsModuleViewer : public ModulePass { 99public: 100 DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID) 101 : ModulePass(ID), Name(GraphName) {} 102 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 112 void getAnalysisUsage(AnalysisUsage &AU) const override { 113 AU.setPreservesAll(); 114 AU.addRequired<AnalysisT>(); 115 } 116 117private: 118 std::string Name; 119}; 120 121template < 122 typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *, 123 typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> > 124class DOTGraphTraitsModulePrinter : public ModulePass { 125public: 126 DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID) 127 : ModulePass(ID), Name(GraphName) {} 128 129 bool runOnModule(Module &M) override { 130 GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); 131 std::string Filename = Name + ".dot"; 132 std::string ErrorInfo; 133 134 errs() << "Writing '" << Filename << "'..."; 135 136 raw_fd_ostream File(Filename.c_str(), ErrorInfo, sys::fs::F_Text); 137 std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph); 138 139 if (ErrorInfo.empty()) 140 WriteGraph(File, Graph, IsSimple, Title); 141 else 142 errs() << " error opening file for writing!"; 143 errs() << "\n"; 144 145 return false; 146 } 147 148 void getAnalysisUsage(AnalysisUsage &AU) const override { 149 AU.setPreservesAll(); 150 AU.addRequired<AnalysisT>(); 151 } 152 153private: 154 std::string Name; 155}; 156 157} // end namespace llvm 158 159#endif 160