LLVM API Documentation

SelectionDAGPrinter.cpp

Go to the documentation of this file.
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 }