CFGPrinter.h revision 6c507926532d609b1225c29878b37c562e4277f2
16c507926532d609b1225c29878b37c562e4277f2Eric Christopher//===-- CFGPrinter.h - CFG printer external interface -----------*- C++ -*-===//
29769ab22265b313171d201b5928688524a01bd87Misha Brukman//
321e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke//                     The LLVM Compiler Infrastructure
421e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
79769ab22265b313171d201b5928688524a01bd87Misha Brukman//
821e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke//===----------------------------------------------------------------------===//
921e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke//
1021e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke// This file defines external functions that can be called to explicitly
1121e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke// instantiate the CFG printer.
1221e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke//
1321e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke//===----------------------------------------------------------------------===//
1421e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke
1521e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke#ifndef LLVM_ANALYSIS_CFGPRINTER_H
1621e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke#define LLVM_ANALYSIS_CFGPRINTER_H
1721e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke
1888067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner#include "llvm/Function.h"
1988067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner#include "llvm/Instructions.h"
2088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner#include "llvm/Assembly/Writer.h"
2188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner#include "llvm/Support/CFG.h"
2288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner#include "llvm/Support/GraphWriter.h"
2388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
2488067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattnernamespace llvm {
2588067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattnertemplate<>
2688067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattnerstruct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
27a10d598602308549d87d2c5d9848f5a72fda2b43Tobias Grosser
28a10d598602308549d87d2c5d9848f5a72fda2b43Tobias Grosser  DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
29a10d598602308549d87d2c5d9848f5a72fda2b43Tobias Grosser
3088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner  static std::string getGraphName(const Function *F) {
3188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    return "CFG for '" + F->getNameStr() + "' function";
3288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner  }
3388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
3456f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser  static std::string getSimpleNodeLabel(const BasicBlock *Node,
3556f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser                                  const Function *Graph) {
3656f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser    if (!Node->getName().empty())
37e8a81da98d5b7373734f0702493fe22883c3e0e2Tobias Grosser      return Node->getNameStr();
3888067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
3988067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    std::string Str;
4088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    raw_string_ostream OS(Str);
4188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
4256f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser    WriteAsOperand(OS, Node, false);
4356f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser    return OS.str();
4456f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser  }
4556f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser
466c507926532d609b1225c29878b37c562e4277f2Eric Christopher  static std::string getCompleteNodeLabel(const BasicBlock *Node,
476c507926532d609b1225c29878b37c562e4277f2Eric Christopher                                          const Function *Graph) {
4856f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser    std::string Str;
4956f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser    raw_string_ostream OS(Str);
5088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
5188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    if (Node->getName().empty()) {
5288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner      WriteAsOperand(OS, Node, false);
5388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner      OS << ":";
5488067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    }
5588067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
5688067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    OS << *Node;
5788067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    std::string OutStr = OS.str();
5888067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
5988067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
6088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    // Process string output to make it nicer...
6188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    for (unsigned i = 0; i != OutStr.length(); ++i)
6288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner      if (OutStr[i] == '\n') {                            // Left justify
6388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner        OutStr[i] = '\\';
6488067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner        OutStr.insert(OutStr.begin()+i+1, 'l');
6588067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner      } else if (OutStr[i] == ';') {                      // Delete comments!
6688067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner        unsigned Idx = OutStr.find('\n', i+1);            // Find end of line
6788067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner        OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx);
6888067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner        --i;
6988067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner      }
7088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
7188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    return OutStr;
7288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner  }
7388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
7456f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser  std::string getNodeLabel(const BasicBlock *Node,
7556f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser                           const Function *Graph) {
7656f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser    if (isSimple())
7756f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser      return getSimpleNodeLabel(Node, Graph);
7856f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser    else
7956f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser      return getCompleteNodeLabel(Node, Graph);
8056f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser  }
8156f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser
8288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner  static std::string getEdgeSourceLabel(const BasicBlock *Node,
8388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner                                        succ_const_iterator I) {
8488067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    // Label source of conditional branches with "T" or "F"
8588067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
8688067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner      if (BI->isConditional())
8788067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner        return (I == succ_begin(Node)) ? "T" : "F";
880a26870d921c4f5507126f3068fc13148c426496Chris Lattner
89641c6f983eb4e40ab23732ab46ffa85bab7f0ba9Dan Gohman    // Label source of switch edges with the associated value.
900a26870d921c4f5507126f3068fc13148c426496Chris Lattner    if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
910a26870d921c4f5507126f3068fc13148c426496Chris Lattner      unsigned SuccNo = I.getSuccessorIndex();
920a26870d921c4f5507126f3068fc13148c426496Chris Lattner
930a26870d921c4f5507126f3068fc13148c426496Chris Lattner      if (SuccNo == 0) return "def";
940a26870d921c4f5507126f3068fc13148c426496Chris Lattner
950a26870d921c4f5507126f3068fc13148c426496Chris Lattner      std::string Str;
960a26870d921c4f5507126f3068fc13148c426496Chris Lattner      raw_string_ostream OS(Str);
970a26870d921c4f5507126f3068fc13148c426496Chris Lattner      OS << SI->getCaseValue(SuccNo)->getValue();
980a26870d921c4f5507126f3068fc13148c426496Chris Lattner      return OS.str();
990a26870d921c4f5507126f3068fc13148c426496Chris Lattner    }
10088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    return "";
10188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner  }
10288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner};
10388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner} // End llvm namespace
10488067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
10521e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaekenamespace llvm {
10621e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke  class FunctionPass;
10721e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke  FunctionPass *createCFGPrinterPass ();
10821e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke  FunctionPass *createCFGOnlyPrinterPass ();
10921e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke} // End llvm namespace
11021e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke
11121e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke#endif
112