CFGPrinter.h revision 0a26870d921c4f5507126f3068fc13148c426496
121e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke//===-- 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 {
2788067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner  static std::string getGraphName(const Function *F) {
2888067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    return "CFG for '" + F->getNameStr() + "' function";
2988067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner  }
3088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
3188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner  static std::string getNodeLabel(const BasicBlock *Node,
3288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner                                  const Function *Graph,
3388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner                                  bool ShortNames) {
3488067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    if (ShortNames && !Node->getName().empty())
3588067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner      return Node->getNameStr() + ":";
3688067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
3788067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    std::string Str;
3888067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    raw_string_ostream OS(Str);
3988067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
4088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    if (ShortNames) {
4188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner      WriteAsOperand(OS, Node, false);
4288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner      return OS.str();
4388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    }
4488067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
4588067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    if (Node->getName().empty()) {
4688067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner      WriteAsOperand(OS, Node, false);
4788067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner      OS << ":";
4888067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    }
4988067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
5088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    OS << *Node;
5188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    std::string OutStr = OS.str();
5288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
5388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
5488067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    // Process string output to make it nicer...
5588067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    for (unsigned i = 0; i != OutStr.length(); ++i)
5688067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner      if (OutStr[i] == '\n') {                            // Left justify
5788067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner        OutStr[i] = '\\';
5888067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner        OutStr.insert(OutStr.begin()+i+1, 'l');
5988067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner      } else if (OutStr[i] == ';') {                      // Delete comments!
6088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner        unsigned Idx = OutStr.find('\n', i+1);            // Find end of line
6188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner        OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx);
6288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner        --i;
6388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner      }
6488067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
6588067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    return OutStr;
6688067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner  }
6788067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
6888067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner  static std::string getEdgeSourceLabel(const BasicBlock *Node,
6988067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner                                        succ_const_iterator I) {
7088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    // Label source of conditional branches with "T" or "F"
7188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
7288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner      if (BI->isConditional())
7388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner        return (I == succ_begin(Node)) ? "T" : "F";
740a26870d921c4f5507126f3068fc13148c426496Chris Lattner
750a26870d921c4f5507126f3068fc13148c426496Chris Lattner    // Label source of conditional branches with "T" or "F"
760a26870d921c4f5507126f3068fc13148c426496Chris Lattner    if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
770a26870d921c4f5507126f3068fc13148c426496Chris Lattner      unsigned SuccNo = I.getSuccessorIndex();
780a26870d921c4f5507126f3068fc13148c426496Chris Lattner
790a26870d921c4f5507126f3068fc13148c426496Chris Lattner      if (SuccNo == 0) return "def";
800a26870d921c4f5507126f3068fc13148c426496Chris Lattner
810a26870d921c4f5507126f3068fc13148c426496Chris Lattner      std::string Str;
820a26870d921c4f5507126f3068fc13148c426496Chris Lattner      raw_string_ostream OS(Str);
830a26870d921c4f5507126f3068fc13148c426496Chris Lattner      OS << SI->getCaseValue(SuccNo)->getValue();
840a26870d921c4f5507126f3068fc13148c426496Chris Lattner      return OS.str();
850a26870d921c4f5507126f3068fc13148c426496Chris Lattner    }
8688067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner    return "";
8788067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner  }
8888067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner};
8988067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner} // End llvm namespace
9088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner
9121e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaekenamespace llvm {
9221e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke  class FunctionPass;
9321e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke  FunctionPass *createCFGPrinterPass ();
9421e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke  FunctionPass *createCFGOnlyPrinterPass ();
9521e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke} // End llvm namespace
9621e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke
9721e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke#endif
98