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 <iostream> 23 #include <fstream> 24 using namespace llvm; 25 26 template<typename GraphType> 27 static void WriteGraphToFile(std::ostream &O, const std::string &GraphName, 28 const GraphType >) { 29 std::string Filename = GraphName + ".dot"; 30 O << "Writing '" << Filename << "'..."; 31 std::string ErrInfo; 32 raw_fd_ostream F(Filename.c_str(), ErrInfo); 33 34 if (ErrInfo.empty()) 35 WriteGraph(F, GT); 36 else 37 O << " error opening file for writing!"; 38 O << "\n"; 39 } 40 41 42 //===----------------------------------------------------------------------===// 43 // Call Graph Printer 44 //===----------------------------------------------------------------------===// 45 46 namespace llvm { 47 template<> 48 struct DOTGraphTraits<CallGraph*> : public DefaultDOTGraphTraits { 49 50 DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} 51 52 static std::string getGraphName(CallGraph *F) { 53 return "Call Graph"; 54 } 55 56 static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) { 57 if (Node->getFunction()) 58 return ((Value*)Node->getFunction())->getName(); 59 else 60 return "Indirect call node"; 61 } 62 }; 63 } 64 65 66 namespace { 67 struct CallGraphPrinter : public ModulePass { 68 static char ID; // Pass ID, replacement for typeid 69 CallGraphPrinter() : ModulePass(&ID) {} 70 71 virtual bool runOnModule(Module &M) { 72 WriteGraphToFile(std::cerr, "callgraph", &getAnalysis<CallGraph>()); 73 return false; 74 } 75 76 void print(raw_ostream &OS, const llvm::Module*) const {} 77 78 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 79 AU.addRequired<CallGraph>(); 80 AU.setPreservesAll(); 81 } 82 }; 83 84 char CallGraphPrinter::ID = 0; 85 RegisterPass<CallGraphPrinter> P2("dot-callgraph", 86 "Print Call Graph to 'dot' file"); 87 } 88 89 //===----------------------------------------------------------------------===// 90 // DomInfoPrinter Pass 91 //===----------------------------------------------------------------------===// 92 93 namespace { 94 class DomInfoPrinter : public FunctionPass { 95 public: 96 static char ID; // Pass identification, replacement for typeid 97 DomInfoPrinter() : FunctionPass(&ID) {} 98 99 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 100 AU.setPreservesAll(); 101 AU.addRequired<DominatorTree>(); 102 AU.addRequired<DominanceFrontier>(); 103 104 } 105 106 virtual bool runOnFunction(Function &F) { 107 DominatorTree &DT = getAnalysis<DominatorTree>(); 108 DT.dump(); 109 DominanceFrontier &DF = getAnalysis<DominanceFrontier>(); 110 DF.dump(); 111 return false; 112 } 113 }; 114 115 char DomInfoPrinter::ID = 0; 116 static RegisterPass<DomInfoPrinter> 117 DIP("print-dom-info", "Dominator Info Printer", true, true); 118 } 119