1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- CFGPrinter.h - CFG printer external interface -----------*- C++ -*-===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file defines external functions that can be called to explicitly 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// instantiate the CFG printer. 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef LLVM_ANALYSIS_CFGPRINTER_H 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define LLVM_ANALYSIS_CFGPRINTER_H 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Constants.h" 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Function.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Instructions.h" 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Assembly/Writer.h" 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/CFG.h" 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/GraphWriter.h" 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace llvm { 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<> 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstruct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits { 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static std::string getGraphName(const Function *F) { 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return "CFG for '" + F->getNameStr() + "' function"; 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static std::string getSimpleNodeLabel(const BasicBlock *Node, 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const Function *Graph) { 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!Node->getName().empty()) 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Node->getNameStr(); 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::string Str; 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman raw_string_ostream OS(Str); 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman WriteAsOperand(OS, Node, false); 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return OS.str(); 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static std::string getCompleteNodeLabel(const BasicBlock *Node, 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const Function *Graph) { 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::string Str; 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman raw_string_ostream OS(Str); 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Node->getName().empty()) { 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman WriteAsOperand(OS, Node, false); 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OS << ":"; 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OS << *Node; 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::string OutStr = OS.str(); 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Process string output to make it nicer... 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i != OutStr.length(); ++i) 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OutStr[i] == '\n') { // Left justify 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OutStr[i] = '\\'; 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OutStr.insert(OutStr.begin()+i+1, 'l'); 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (OutStr[i] == ';') { // Delete comments! 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Idx = OutStr.find('\n', i+1); // Find end of line 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx); 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --i; 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return OutStr; 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::string getNodeLabel(const BasicBlock *Node, 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const Function *Graph) { 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isSimple()) 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return getSimpleNodeLabel(Node, Graph); 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return getCompleteNodeLabel(Node, Graph); 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static std::string getEdgeSourceLabel(const BasicBlock *Node, 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman succ_const_iterator I) { 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Label source of conditional branches with "T" or "F" 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator())) 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BI->isConditional()) 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return (I == succ_begin(Node)) ? "T" : "F"; 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Label source of switch edges with the associated value. 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) { 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned SuccNo = I.getSuccessorIndex(); 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SuccNo == 0) return "def"; 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::string Str; 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman raw_string_ostream OS(Str); 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OS << SI->getCaseValue(SuccNo)->getValue(); 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return OS.str(); 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ""; 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} // End llvm namespace 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace llvm { 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman class FunctionPass; 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FunctionPass *createCFGPrinterPass (); 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FunctionPass *createCFGOnlyPrinterPass (); 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} // End llvm namespace 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 113