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