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 1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/CFG.h" 190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h" 200b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.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) { 31a7b0cb759433c715065440ee2a963a04db7f2b0bBenjamin Kramer return "CFG for '" + F->getName().str() + "' function"; 3288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner } 3388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner 3456f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser static std::string getSimpleNodeLabel(const BasicBlock *Node, 35b39e25ef2c8d8c840ec4155e57c737ac7bd4f167Eli Friedman const Function *) { 3656f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser if (!Node->getName().empty()) 37a7b0cb759433c715065440ee2a963a04db7f2b0bBenjamin Kramer return Node->getName().str(); 3888067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner 3988067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner std::string Str; 4088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner raw_string_ostream OS(Str); 4188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner 4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Node->printAsOperand(OS, false); 4356f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser return OS.str(); 4456f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser } 4556f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser 464be0c592c42739b1927aaf2a20b3fabbf6adf335Andrew Trick static std::string getCompleteNodeLabel(const BasicBlock *Node, 47b39e25ef2c8d8c840ec4155e57c737ac7bd4f167Eli Friedman const Function *) { 482f08e75a45b9fa698a49277f6cc11e041bf5fa51Andrew Trick enum { MaxColumns = 80 }; 4956f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser std::string Str; 5056f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser raw_string_ostream OS(Str); 5188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner 5288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner if (Node->getName().empty()) { 5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Node->printAsOperand(OS, false); 5488067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner OS << ":"; 5588067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner } 5688067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner 5788067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner OS << *Node; 5888067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner std::string OutStr = OS.str(); 5988067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); 6088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner 6188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner // Process string output to make it nicer... 622f08e75a45b9fa698a49277f6cc11e041bf5fa51Andrew Trick unsigned ColNum = 0; 632f08e75a45b9fa698a49277f6cc11e041bf5fa51Andrew Trick unsigned LastSpace = 0; 642f08e75a45b9fa698a49277f6cc11e041bf5fa51Andrew Trick for (unsigned i = 0; i != OutStr.length(); ++i) { 6588067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner if (OutStr[i] == '\n') { // Left justify 6688067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner OutStr[i] = '\\'; 6788067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner OutStr.insert(OutStr.begin()+i+1, 'l'); 682f08e75a45b9fa698a49277f6cc11e041bf5fa51Andrew Trick ColNum = 0; 692f08e75a45b9fa698a49277f6cc11e041bf5fa51Andrew Trick LastSpace = 0; 7088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner } else if (OutStr[i] == ';') { // Delete comments! 7188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner unsigned Idx = OutStr.find('\n', i+1); // Find end of line 7288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx); 7388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner --i; 742f08e75a45b9fa698a49277f6cc11e041bf5fa51Andrew Trick } else if (ColNum == MaxColumns) { // Wrap lines. 7537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Wrap very long names even though we can't find a space. 7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!LastSpace) 7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LastSpace = i; 7837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines OutStr.insert(LastSpace, "\\l..."); 7937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ColNum = i - LastSpace; 8037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LastSpace = 0; 8137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines i += 3; // The loop will advance 'i' again. 8288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner } 832f08e75a45b9fa698a49277f6cc11e041bf5fa51Andrew Trick else 842f08e75a45b9fa698a49277f6cc11e041bf5fa51Andrew Trick ++ColNum; 852f08e75a45b9fa698a49277f6cc11e041bf5fa51Andrew Trick if (OutStr[i] == ' ') 862f08e75a45b9fa698a49277f6cc11e041bf5fa51Andrew Trick LastSpace = i; 872f08e75a45b9fa698a49277f6cc11e041bf5fa51Andrew Trick } 8888067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner return OutStr; 8988067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner } 9088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner 9156f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser std::string getNodeLabel(const BasicBlock *Node, 9256f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser const Function *Graph) { 9356f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser if (isSimple()) 9456f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser return getSimpleNodeLabel(Node, Graph); 9556f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser else 9656f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser return getCompleteNodeLabel(Node, Graph); 9756f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser } 9856f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser 9988067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner static std::string getEdgeSourceLabel(const BasicBlock *Node, 10088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner succ_const_iterator I) { 10188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner // Label source of conditional branches with "T" or "F" 10288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator())) 10388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner if (BI->isConditional()) 10488067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner return (I == succ_begin(Node)) ? "T" : "F"; 1054be0c592c42739b1927aaf2a20b3fabbf6adf335Andrew Trick 106641c6f983eb4e40ab23732ab46ffa85bab7f0ba9Dan Gohman // Label source of switch edges with the associated value. 1070a26870d921c4f5507126f3068fc13148c426496Chris Lattner if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) { 1080a26870d921c4f5507126f3068fc13148c426496Chris Lattner unsigned SuccNo = I.getSuccessorIndex(); 1090a26870d921c4f5507126f3068fc13148c426496Chris Lattner 1100a26870d921c4f5507126f3068fc13148c426496Chris Lattner if (SuccNo == 0) return "def"; 1114be0c592c42739b1927aaf2a20b3fabbf6adf335Andrew Trick 1120a26870d921c4f5507126f3068fc13148c426496Chris Lattner std::string Str; 1130a26870d921c4f5507126f3068fc13148c426496Chris Lattner raw_string_ostream OS(Str); 114c10fa6c801e48771b5eade50afc2fe6abaf08227Stepan Dyatkovskiy SwitchInst::ConstCaseIt Case = 1154be0c592c42739b1927aaf2a20b3fabbf6adf335Andrew Trick SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo); 116c10fa6c801e48771b5eade50afc2fe6abaf08227Stepan Dyatkovskiy OS << Case.getCaseValue()->getValue(); 1170a26870d921c4f5507126f3068fc13148c426496Chris Lattner return OS.str(); 1184be0c592c42739b1927aaf2a20b3fabbf6adf335Andrew Trick } 11988067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner return ""; 12088067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner } 12188067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner}; 12288067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner} // End llvm namespace 12388067b9133103de3bfadd4f5166f4fb082ba2496Chris Lattner 12421e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaekenamespace llvm { 12521e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke class FunctionPass; 12621e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke FunctionPass *createCFGPrinterPass (); 12721e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke FunctionPass *createCFGOnlyPrinterPass (); 12821e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke} // End llvm namespace 12921e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke 13021e232501a9d5ace29187b20a211ca73b09a1c75Brian Gaeke#endif 131