LLVM API Documentation
00001 //===-- SelectionDAGPrinter.cpp - Implement SelectionDAG::viewGraph() -----===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This implements the SelectionDAG::viewGraph method. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/Constants.h" 00015 #include "llvm/Function.h" 00016 #include "llvm/Assembly/Writer.h" 00017 #include "llvm/CodeGen/SelectionDAG.h" 00018 #include "llvm/CodeGen/MachineFunction.h" 00019 #include "llvm/Target/MRegisterInfo.h" 00020 #include "llvm/Target/TargetMachine.h" 00021 #include "llvm/Support/GraphWriter.h" 00022 #include "llvm/ADT/StringExtras.h" 00023 #include "llvm/Config/config.h" 00024 #include <fstream> 00025 #include <sstream> 00026 using namespace llvm; 00027 00028 namespace llvm { 00029 template<> 00030 struct DOTGraphTraits<SelectionDAG*> : public DefaultDOTGraphTraits { 00031 static std::string getGraphName(const SelectionDAG *G) { 00032 return G->getMachineFunction().getFunction()->getName(); 00033 } 00034 00035 static bool renderGraphFromBottomUp() { 00036 return true; 00037 } 00038 00039 static bool hasNodeAddressLabel(const SDNode *Node, 00040 const SelectionDAG *Graph) { 00041 return true; 00042 } 00043 00044 static std::string getNodeLabel(const SDNode *Node, 00045 const SelectionDAG *Graph); 00046 static std::string getNodeAttributes(const SDNode *N) { 00047 return "shape=Mrecord"; 00048 } 00049 00050 static void addCustomGraphFeatures(SelectionDAG *G, 00051 GraphWriter<SelectionDAG*> &GW) { 00052 GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot"); 00053 GW.emitEdge(0, -1, G->getRoot().Val, -1, ""); 00054 } 00055 }; 00056 } 00057 00058 std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node, 00059 const SelectionDAG *G) { 00060 std::string Op = Node->getOperationName(G); 00061 00062 for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) 00063 if (Node->getValueType(i) == MVT::Other) 00064 Op += ":ch"; 00065 else 00066 Op = Op + ":" + MVT::getValueTypeString(Node->getValueType(i)); 00067 00068 if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(Node)) { 00069 Op += ": " + utostr(CSDN->getValue()); 00070 } else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(Node)) { 00071 Op += ": " + ftostr(CSDN->getValue()); 00072 } else if (const GlobalAddressSDNode *GADN = 00073 dyn_cast<GlobalAddressSDNode>(Node)) { 00074 int offset = GADN->getOffset(); 00075 Op += ": " + GADN->getGlobal()->getName(); 00076 if (offset > 0) 00077 Op += "+" + itostr(offset); 00078 else 00079 Op += itostr(offset); 00080 } else if (const FrameIndexSDNode *FIDN = dyn_cast<FrameIndexSDNode>(Node)) { 00081 Op += " " + itostr(FIDN->getIndex()); 00082 } else if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Node)){ 00083 if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->get())) 00084 Op += "<" + ftostr(CFP->getValue()) + ">"; 00085 else if (ConstantInt *CI = dyn_cast<ConstantInt>(CP->get())) 00086 Op += "<" + utostr(CI->getZExtValue()) + ">"; 00087 else { 00088 std::ostringstream SS; 00089 WriteAsOperand(SS, CP->get(), false); 00090 Op += "<" + SS.str() + ">"; 00091 } 00092 } else if (const BasicBlockSDNode *BBDN = dyn_cast<BasicBlockSDNode>(Node)) { 00093 Op = "BB: "; 00094 const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock(); 00095 if (LBB) 00096 Op += LBB->getName(); 00097 //Op += " " + (const void*)BBDN->getBasicBlock(); 00098 } else if (const RegisterSDNode *R = dyn_cast<RegisterSDNode>(Node)) { 00099 if (G && R->getReg() != 0 && MRegisterInfo::isPhysicalRegister(R->getReg())) { 00100 Op = Op + " " + G->getTarget().getRegisterInfo()->getName(R->getReg()); 00101 } else { 00102 Op += " #" + utostr(R->getReg()); 00103 } 00104 } else if (const ExternalSymbolSDNode *ES = 00105 dyn_cast<ExternalSymbolSDNode>(Node)) { 00106 Op += "'" + std::string(ES->getSymbol()) + "'"; 00107 } else if (const SrcValueSDNode *M = dyn_cast<SrcValueSDNode>(Node)) { 00108 if (M->getValue()) 00109 Op += "<" + M->getValue()->getName() + ":" + itostr(M->getOffset()) + ">"; 00110 else 00111 Op += "<null:" + itostr(M->getOffset()) + ">"; 00112 } else if (const VTSDNode *N = dyn_cast<VTSDNode>(Node)) { 00113 Op = Op + " VT=" + getValueTypeString(N->getVT()); 00114 } else if (const StringSDNode *N = dyn_cast<StringSDNode>(Node)) { 00115 Op = Op + "\"" + N->getValue() + "\""; 00116 } 00117 00118 return Op; 00119 } 00120 00121 00122 /// viewGraph - Pop up a ghostview window with the reachable parts of the DAG 00123 /// rendered using 'dot'. 00124 /// 00125 void SelectionDAG::viewGraph() { 00126 // This code is only for debugging! 00127 #ifndef NDEBUG 00128 ViewGraph(this, "dag." + getMachineFunction().getFunction()->getName()); 00129 #else 00130 std::cerr << "SelectionDAG::viewGraph is only available in debug builds on " 00131 << "systems with Graphviz or gv!\n"; 00132 #endif // NDEBUG 00133 }