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