1 //===- GraphPrinters.cpp - DOT printers for various graph types -----------===// 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 several printers for various different types of graphs used 11 // by the LLVM infrastructure. It uses the generic graph interface to convert 12 // the graph into a .dot graph. These graphs can then be processed with the 13 // "dot" tool to convert them to postscript or some other suitable format. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #include "llvm/Support/GraphWriter.h" 18 #include "llvm/Pass.h" 19 #include "llvm/Value.h" 20 #include "llvm/Analysis/CallGraph.h" 21 #include "llvm/Analysis/Dominators.h" 22 #include "llvm/Support/raw_ostream.h" 23 using namespace llvm; 24 25 template<typename GraphType> 26 static void WriteGraphToFile(raw_ostream &O, const std::string &GraphName, 27 const GraphType >) { 28 std::string Filename = GraphName + ".dot"; 29 O << "Writing '" << Filename << "'..."; 30 std::string ErrInfo; 31 raw_fd_ostream F(Filename.c_str(), ErrInfo); 32 33 if (ErrInfo.empty()) 34 WriteGraph(F, GT); 35 else 36 O << " error opening file for writing!"; 37 O << "\n"; 38 } 39 40 41 //===----------------------------------------------------------------------===// 42 // Call Graph Printer 43 //===----------------------------------------------------------------------===// 44 45 namespace llvm { 46 template<> 47 struct DOTGraphTraits<CallGraph*> : public DefaultDOTGraphTraits { 48 49 DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} 50 51 static std::string getGraphName(CallGraph *F) { 52 return "Call Graph"; 53 } 54 55 static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) { 56 if (Node->getFunction()) 57 return ((Value*)Node->getFunction())->getName(); 58 else 59 return "external node"; 60 } 61 }; 62 } 63 64 65 namespace { 66 struct CallGraphPrinter : public ModulePass { 67 static char ID; // Pass ID, replacement for typeid 68 CallGraphPrinter() : ModulePass(&ID) {} 69 70 virtual bool runOnModule(Module &M) { 71 WriteGraphToFile(llvm::errs(), "callgraph", &getAnalysis<CallGraph>()); 72 return false; 73 } 74 75 void print(raw_ostream &OS, const llvm::Module*) const {} 76 77 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 78 AU.addRequired<CallGraph>(); 79 AU.setPreservesAll(); 80 } 81 }; 82 83 char CallGraphPrinter::ID = 0; 84 RegisterPass<CallGraphPrinter> P2("dot-callgraph", 85 "Print Call Graph to 'dot' file"); 86 } 87 88 //===----------------------------------------------------------------------===// 89 // DomInfoPrinter Pass 90 //===----------------------------------------------------------------------===// 91 92 namespace { 93 class DomInfoPrinter : public FunctionPass { 94 public: 95 static char ID; // Pass identification, replacement for typeid 96 DomInfoPrinter() : FunctionPass(&ID) {} 97 98 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 99 AU.setPreservesAll(); 100 AU.addRequired<DominatorTree>(); 101 AU.addRequired<DominanceFrontier>(); 102 103 } 104 105 virtual bool runOnFunction(Function &F) { 106 DominatorTree &DT = getAnalysis<DominatorTree>(); 107 DT.dump(); 108 DominanceFrontier &DF = getAnalysis<DominanceFrontier>(); 109 DF.dump(); 110 return false; 111 } 112 }; 113 114 char DomInfoPrinter::ID = 0; 115 static RegisterPass<DomInfoPrinter> 116 DIP("print-dom-info", "Dominator Info Printer", true, true); 117 } 118