diff options
author | Chris Lattner <sabre@nondot.org> | 2002-10-07 18:38:01 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2002-10-07 18:38:01 +0000 |
commit | ac859db3e4dcfe0626dd7ed4b7a3c54a34986381 (patch) | |
tree | c41adec904db45006c1f44137b3f7477389015cb /tools/opt/GraphPrinters.cpp | |
parent | 95b923d548ed2e0f0993bb613868c871646f120c (diff) | |
download | external_llvm-ac859db3e4dcfe0626dd7ed4b7a3c54a34986381.zip external_llvm-ac859db3e4dcfe0626dd7ed4b7a3c54a34986381.tar.gz external_llvm-ac859db3e4dcfe0626dd7ed4b7a3c54a34986381.tar.bz2 |
- Implement a new -print-cfg option for analyze, that causes it to print the
CFG of each function in the module to 'dot' files.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4062 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/opt/GraphPrinters.cpp')
-rw-r--r-- | tools/opt/GraphPrinters.cpp | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/tools/opt/GraphPrinters.cpp b/tools/opt/GraphPrinters.cpp new file mode 100644 index 0000000..35bff56 --- /dev/null +++ b/tools/opt/GraphPrinters.cpp @@ -0,0 +1,88 @@ +//===- GraphPrinters.cpp - DOT printers for various graph types -----------===// +// +// 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 "Support/GraphWriter.h" +#include "llvm/Pass.h" +#include "llvm/iTerminators.h" +#include "llvm/Support/CFG.h" +#include <sstream> +#include <fstream> + +template<> +struct DOTGraphTraits<Function*> : public DefaultDOTGraphTraits { + static std::string getGraphName(Function *F) { + return "CFG for '" + F->getName() + "' function"; + } + + static std::string getNodeLabel(BasicBlock *Node, Function *Graph) { + std::ostringstream Out; + Out << Node; + std::string OutStr = Out.str(); + if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); + + // Process string output to make it nicer... + for (unsigned i = 0; i != OutStr.length(); ++i) + if (OutStr[i] == '\n') { // Left justify + OutStr[i] = '\\'; + OutStr.insert(OutStr.begin()+i+1, 'l'); + } else if (OutStr[i] == ';') { // Delete comments! + unsigned Idx = OutStr.find('\n', i+1); // Find end of line + OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx); + --i; + } + + return OutStr; + } + + static std::string getNodeAttributes(BasicBlock *N) { + return "fontname=Courier"; + } + + static std::string getEdgeSourceLabel(BasicBlock *Node, succ_iterator I) { + // Label source of conditional branches with "T" or "F" + if (BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator())) + if (BI->isConditional()) + return (I == succ_begin(Node)) ? "T" : "F"; + return ""; + } +}; + +template<typename GraphType> +static void WriteGraphToFile(std::ostream &O, const std::string &GraphName, + const GraphType >) { + std::string Filename = GraphName + ".dot"; + O << "Writing '" << Filename << "'..."; + std::ofstream F(Filename.c_str()); + + if (F.good()) + WriteGraph(F, GT); + else + O << " error opening file for writing!"; + O << "\n"; +} + + +namespace { + struct CFGPrinter : public FunctionPass { + Function *F; + virtual bool runOnFunction(Function &Func) { + WriteGraphToFile(std::cerr, "cfg."+Func.getName(), &Func); + return false; + } + + void print(std::ostream &OS) const {} + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } + }; + + RegisterAnalysis<CFGPrinter> P1("print-cfg", + "Print CFG of function to 'dot' file"); +}; |