diff options
author | Alkis Evlogimenos <alkis@evlogimenos.com> | 2004-07-08 00:47:58 +0000 |
---|---|---|
committer | Alkis Evlogimenos <alkis@evlogimenos.com> | 2004-07-08 00:47:58 +0000 |
commit | 71bf404e9b69122c276ad7ce66f38bf1e57cafeb (patch) | |
tree | ad9849da8f3a8a2196678dd51636f471e38ae7b1 /lib/CodeGen/MachineFunction.cpp | |
parent | cf617ddd9836ee6a4176337c7553015c2aa5b068 (diff) |
Add viewCFG() and viewCFGOnly() APIs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14679 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineFunction.cpp')
-rw-r--r-- | lib/CodeGen/MachineFunction.cpp | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index 520f1da960..63785a301b 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -26,7 +26,10 @@ #include "llvm/iOther.h" #include "llvm/Type.h" #include "Support/LeakDetector.h" +#include "Support/GraphWriter.h" +#include <fstream> #include <iostream> +#include <sstream> using namespace llvm; @@ -140,6 +143,80 @@ void MachineFunction::print(std::ostream &OS) const { OS << "\n# End machine code for " << Fn->getName () << "().\n\n"; } +/// CFGOnly flag - This is used to control whether or not the CFG graph printer +/// prints out the contents of basic blocks or not. This is acceptable because +/// this code is only really used for debugging purposes. +/// +static bool CFGOnly = false; + +namespace llvm { +template<> +struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits { + static std::string getGraphName(const MachineFunction *F) { + return "CFG for '" + F->getFunction()->getName() + "' function"; + } + + static std::string getNodeLabel(const MachineBasicBlock *Node, + const MachineFunction *Graph) { + if (CFGOnly && Node->getBasicBlock() && + !Node->getBasicBlock()->getName().empty()) + return Node->getBasicBlock()->getName() + ":"; + + std::ostringstream Out; + if (CFGOnly) { + Out << Node->getNumber() << ':'; + return Out.str(); + } + + Node->print(Out); + + 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'); + } + return OutStr; + } +}; +} + +void MachineFunction::viewCFG() const +{ + std::string Filename = "/tmp/cfg." + getFunction()->getName() + ".dot"; + std::cerr << "Writing '" << Filename << "'... "; + std::ofstream F(Filename.c_str()); + + if (!F) { + std::cerr << " error opening file for writing!\n"; + return; + } + + WriteGraph(F, this); + F.close(); + std::cerr << "\n"; + + std::cerr << "Running 'dot' program... " << std::flush; + if (system(("dot -Tps -Nfontname=Courier -Gsize=7.5,10 " + Filename + + " > /tmp/cfg.tempgraph.ps").c_str())) { + std::cerr << "Error running dot: 'dot' not in path?\n"; + } else { + std::cerr << "\n"; + system("gv /tmp/cfg.tempgraph.ps"); + } + system(("rm " + Filename + " /tmp/cfg.tempgraph.ps").c_str()); +} + +void MachineFunction::viewCFGOnly() const +{ + CFGOnly = true; + viewCFG(); + CFGOnly = false; +} + // The next two methods are used to construct and to retrieve // the MachineCodeForFunction object for the given function. // construct() -- Allocates and initializes for a given function and target @@ -405,4 +482,3 @@ MachineFunctionInfo::pushTempValue(unsigned size) void MachineFunctionInfo::popAllTempValues() { resetTmpAreaSize(); // clear tmp area to reuse } - |