| //===- GraphPrinters.cpp - DOT printers for various graph types -----------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file defines several printers for various different types of graphs used |
| // by the LLVM infrastructure. It uses the generic graph interface to convert |
| // the graph into a .dot graph. These graphs can then be processed with the |
| // "dot" tool to convert them to postscript or some other suitable format. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/Support/GraphWriter.h" |
| #include "llvm/Pass.h" |
| #include "llvm/Value.h" |
| #include "llvm/Analysis/CallGraph.h" |
| #include "llvm/Analysis/Dominators.h" |
| #include "llvm/Support/ToolOutputFile.h" |
| using namespace llvm; |
| |
| template<typename GraphType> |
| static void WriteGraphToFile(raw_ostream &O, const std::string &GraphName, |
| const GraphType >) { |
| std::string Filename = GraphName + ".dot"; |
| O << "Writing '" << Filename << "'..."; |
| std::string ErrInfo; |
| tool_output_file F(Filename.c_str(), ErrInfo); |
| |
| if (ErrInfo.empty()) { |
| WriteGraph(F.os(), GT); |
| F.os().close(); |
| if (!F.os().has_error()) { |
| O << "\n"; |
| F.keep(); |
| return; |
| } |
| } |
| O << " error opening file for writing!\n"; |
| F.os().clear_error(); |
| } |
| |
| |
| //===----------------------------------------------------------------------===// |
| // Call Graph Printer |
| //===----------------------------------------------------------------------===// |
| |
| namespace llvm { |
| template<> |
| struct DOTGraphTraits<CallGraph*> : public DefaultDOTGraphTraits { |
| |
| DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} |
| |
| static std::string getGraphName(CallGraph *F) { |
| return "Call Graph"; |
| } |
| |
| static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) { |
| if (Node->getFunction()) |
| return ((Value*)Node->getFunction())->getName(); |
| return "external node"; |
| } |
| }; |
| } |
| |
| |
| namespace { |
| struct CallGraphPrinter : public ModulePass { |
| static char ID; // Pass ID, replacement for typeid |
| CallGraphPrinter() : ModulePass(ID) {} |
| |
| virtual bool runOnModule(Module &M) { |
| WriteGraphToFile(llvm::errs(), "callgraph", &getAnalysis<CallGraph>()); |
| return false; |
| } |
| |
| void print(raw_ostream &OS, const llvm::Module*) const {} |
| |
| virtual void getAnalysisUsage(AnalysisUsage &AU) const { |
| AU.addRequired<CallGraph>(); |
| AU.setPreservesAll(); |
| } |
| }; |
| } |
| |
| char CallGraphPrinter::ID = 0; |
| static RegisterPass<CallGraphPrinter> P2("dot-callgraph", |
| "Print Call Graph to 'dot' file"); |
| |
| //===----------------------------------------------------------------------===// |
| // DomInfoPrinter Pass |
| //===----------------------------------------------------------------------===// |
| |
| namespace { |
| class DomInfoPrinter : public FunctionPass { |
| public: |
| static char ID; // Pass identification, replacement for typeid |
| DomInfoPrinter() : FunctionPass(ID) {} |
| |
| virtual void getAnalysisUsage(AnalysisUsage &AU) const { |
| AU.setPreservesAll(); |
| AU.addRequired<DominatorTree>(); |
| |
| } |
| |
| virtual bool runOnFunction(Function &F) { |
| getAnalysis<DominatorTree>().dump(); |
| return false; |
| } |
| }; |
| } |
| |
| char DomInfoPrinter::ID = 0; |
| static RegisterPass<DomInfoPrinter> |
| DIP("print-dom-info", "Dominator Info Printer", true, true); |