diff --git a/tools/analyze/GraphPrinters.cpp b/tools/analyze/GraphPrinters.cpp index 35bff565a1f..28b18d1480e 100644 --- a/tools/analyze/GraphPrinters.cpp +++ b/tools/analyze/GraphPrinters.cpp @@ -10,10 +10,15 @@ #include "Support/GraphWriter.h" #include "llvm/Pass.h" #include "llvm/iTerminators.h" +#include "llvm/Analysis/CallGraph.h" #include "llvm/Support/CFG.h" #include #include +//===----------------------------------------------------------------------===// +// Control Flow Graph Printer +//===----------------------------------------------------------------------===// + template<> struct DOTGraphTraits : public DefaultDOTGraphTraits { static std::string getGraphName(Function *F) { @@ -70,7 +75,6 @@ static void WriteGraphToFile(std::ostream &O, const std::string &GraphName, namespace { struct CFGPrinter : public FunctionPass { - Function *F; virtual bool runOnFunction(Function &Func) { WriteGraphToFile(std::cerr, "cfg."+Func.getName(), &Func); return false; @@ -86,3 +90,43 @@ namespace { RegisterAnalysis P1("print-cfg", "Print CFG of function to 'dot' file"); }; + + + +//===----------------------------------------------------------------------===// +// Call Graph Printer +//===----------------------------------------------------------------------===// + +template<> +struct DOTGraphTraits : public DefaultDOTGraphTraits { + static std::string getGraphName(CallGraph *F) { + return "Call Graph"; + } + + static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) { + if (Node->getFunction()) + return Node->getFunction()->getName(); + else + return "Indirect call node"; + } +}; + + +namespace { + struct CallGraphPrinter : public Pass { + virtual bool run(Module &M) { + WriteGraphToFile(std::cerr, "callgraph", &getAnalysis()); + return false; + } + + void print(std::ostream &OS) const {} + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.setPreservesAll(); + } + }; + + RegisterAnalysis P2("print-callgraph", + "Print Call Graph to 'dot' file"); +}; diff --git a/tools/opt/GraphPrinters.cpp b/tools/opt/GraphPrinters.cpp index 35bff565a1f..28b18d1480e 100644 --- a/tools/opt/GraphPrinters.cpp +++ b/tools/opt/GraphPrinters.cpp @@ -10,10 +10,15 @@ #include "Support/GraphWriter.h" #include "llvm/Pass.h" #include "llvm/iTerminators.h" +#include "llvm/Analysis/CallGraph.h" #include "llvm/Support/CFG.h" #include #include +//===----------------------------------------------------------------------===// +// Control Flow Graph Printer +//===----------------------------------------------------------------------===// + template<> struct DOTGraphTraits : public DefaultDOTGraphTraits { static std::string getGraphName(Function *F) { @@ -70,7 +75,6 @@ static void WriteGraphToFile(std::ostream &O, const std::string &GraphName, namespace { struct CFGPrinter : public FunctionPass { - Function *F; virtual bool runOnFunction(Function &Func) { WriteGraphToFile(std::cerr, "cfg."+Func.getName(), &Func); return false; @@ -86,3 +90,43 @@ namespace { RegisterAnalysis P1("print-cfg", "Print CFG of function to 'dot' file"); }; + + + +//===----------------------------------------------------------------------===// +// Call Graph Printer +//===----------------------------------------------------------------------===// + +template<> +struct DOTGraphTraits : public DefaultDOTGraphTraits { + static std::string getGraphName(CallGraph *F) { + return "Call Graph"; + } + + static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) { + if (Node->getFunction()) + return Node->getFunction()->getName(); + else + return "Indirect call node"; + } +}; + + +namespace { + struct CallGraphPrinter : public Pass { + virtual bool run(Module &M) { + WriteGraphToFile(std::cerr, "callgraph", &getAnalysis()); + return false; + } + + void print(std::ostream &OS) const {} + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.setPreservesAll(); + } + }; + + RegisterAnalysis P2("print-callgraph", + "Print Call Graph to 'dot' file"); +};