SelectionDAGPrinter.cpp revision 26f7fa7bba94eb18bf0e43586dd2b596cb58ca80
1//===-- SelectionDAGPrinter.cpp - Implement SelectionDAG::viewGraph() -----===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This implements the SelectionDAG::viewGraph method.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Constants.h"
15#include "llvm/Function.h"
16#include "llvm/Assembly/Writer.h"
17#include "llvm/CodeGen/SelectionDAG.h"
18#include "llvm/CodeGen/MachineConstantPool.h"
19#include "llvm/CodeGen/MachineFunction.h"
20#include "llvm/Target/MRegisterInfo.h"
21#include "llvm/Target/TargetMachine.h"
22#include "llvm/Support/GraphWriter.h"
23#include "llvm/ADT/StringExtras.h"
24#include "llvm/Config/config.h"
25#include <fstream>
26#include <sstream>
27using namespace llvm;
28
29namespace llvm {
30  template<>
31  struct DOTGraphTraits<SelectionDAG*> : public DefaultDOTGraphTraits {
32    static std::string getGraphName(const SelectionDAG *G) {
33      return G->getMachineFunction().getFunction()->getName();
34    }
35
36    static bool renderGraphFromBottomUp() {
37      return true;
38    }
39
40    static bool hasNodeAddressLabel(const SDNode *Node,
41                                    const SelectionDAG *Graph) {
42      return true;
43    }
44
45    static std::string getNodeLabel(const SDNode *Node,
46                                    const SelectionDAG *Graph);
47    static std::string getNodeAttributes(const SDNode *N,
48                                         const SelectionDAG *Graph) {
49#ifndef NDEBUG
50      const std::string &Attrs = Graph->getGraphAttrs(N);
51      if (!Attrs.empty()) {
52        if (Attrs.find("shape=") == std::string::npos)
53          return std::string("shape=Mrecord,") + Attrs;
54        else
55          return Attrs;
56      }
57#endif
58      return "shape=Mrecord";
59    }
60
61    static void addCustomGraphFeatures(SelectionDAG *G,
62                                       GraphWriter<SelectionDAG*> &GW) {
63      GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot");
64      if (G->getRoot().Val)
65        GW.emitEdge(0, -1, G->getRoot().Val, -1, "");
66    }
67  };
68}
69
70std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
71                                                        const SelectionDAG *G) {
72  std::string Op = Node->getOperationName(G);
73
74  for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i)
75    if (Node->getValueType(i) == MVT::Other)
76      Op += ":ch";
77    else
78      Op = Op + ":" + MVT::getValueTypeString(Node->getValueType(i));
79
80  if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(Node)) {
81    Op += ": " + utostr(CSDN->getValue());
82  } else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(Node)) {
83    Op += ": " + ftostr(CSDN->getValue());
84  } else if (const GlobalAddressSDNode *GADN =
85             dyn_cast<GlobalAddressSDNode>(Node)) {
86    int offset = GADN->getOffset();
87    Op += ": " + GADN->getGlobal()->getName();
88    if (offset > 0)
89      Op += "+" + itostr(offset);
90    else
91      Op += itostr(offset);
92  } else if (const FrameIndexSDNode *FIDN = dyn_cast<FrameIndexSDNode>(Node)) {
93    Op += " " + itostr(FIDN->getIndex());
94  } else if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Node)){
95    if (CP->isMachineConstantPoolEntry()) {
96      std::ostringstream SS;
97      CP->getMachineCPVal()->print(SS);
98      Op += "<" + SS.str() + ">";
99    } else {
100      if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
101        Op += "<" + ftostr(CFP->getValue()) + ">";
102      else if (ConstantInt *CI = dyn_cast<ConstantInt>(CP->getConstVal()))
103        Op += "<" + utostr(CI->getZExtValue()) + ">";
104      else {
105        std::ostringstream SS;
106        WriteAsOperand(SS, CP->getConstVal(), false);
107        Op += "<" + SS.str() + ">";
108      }
109    }
110  } else if (const BasicBlockSDNode *BBDN = dyn_cast<BasicBlockSDNode>(Node)) {
111    Op = "BB: ";
112    const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock();
113    if (LBB)
114      Op += LBB->getName();
115    //Op += " " + (const void*)BBDN->getBasicBlock();
116  } else if (const RegisterSDNode *R = dyn_cast<RegisterSDNode>(Node)) {
117    if (G && R->getReg() != 0 && MRegisterInfo::isPhysicalRegister(R->getReg())) {
118      Op = Op + " " + G->getTarget().getRegisterInfo()->getName(R->getReg());
119    } else {
120      Op += " #" + utostr(R->getReg());
121    }
122  } else if (const ExternalSymbolSDNode *ES =
123             dyn_cast<ExternalSymbolSDNode>(Node)) {
124    Op += "'" + std::string(ES->getSymbol()) + "'";
125  } else if (const SrcValueSDNode *M = dyn_cast<SrcValueSDNode>(Node)) {
126    if (M->getValue())
127      Op += "<" + M->getValue()->getName() + ":" + itostr(M->getOffset()) + ">";
128    else
129      Op += "<null:" + itostr(M->getOffset()) + ">";
130  } else if (const VTSDNode *N = dyn_cast<VTSDNode>(Node)) {
131    Op = Op + " VT=" + getValueTypeString(N->getVT());
132  } else if (const StringSDNode *N = dyn_cast<StringSDNode>(Node)) {
133    Op = Op + "\"" + N->getValue() + "\"";
134  } else if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(Node)) {
135    bool doExt = true;
136    switch (LD->getExtensionType()) {
137    default: doExt = false; break;
138    case ISD::EXTLOAD:
139      Op = Op + "<anyext ";
140      break;
141    case ISD::SEXTLOAD:
142      Op = Op + " <sext ";
143      break;
144    case ISD::ZEXTLOAD:
145      Op = Op + " <zext ";
146      break;
147    }
148    if (doExt)
149      Op = Op + MVT::getValueTypeString(LD->getLoadedVT()) + ">";
150
151    if (LD->getAddressingMode() == ISD::PRE_INDEXED)
152      Op = Op + "<pre>";
153    else if (LD->getAddressingMode() == ISD::POST_INDEXED)
154      Op = Op + "<post>";
155  }
156
157  return Op;
158}
159
160
161/// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
162/// rendered using 'dot'.
163///
164void SelectionDAG::viewGraph() {
165// This code is only for debugging!
166#ifndef NDEBUG
167  ViewGraph(this, "dag." + getMachineFunction().getFunction()->getName());
168#else
169  std::cerr << "SelectionDAG::viewGraph is only available in debug builds on "
170            << "systems with Graphviz or gv!\n";
171#endif  // NDEBUG
172}
173
174
175/// clearGraphAttrs - Clear all previously defined node graph attributes.
176/// Intended to be used from a debugging tool (eg. gdb).
177void SelectionDAG::clearGraphAttrs() {
178#ifndef NDEBUG
179  NodeGraphAttrs.clear();
180#else
181  std::cerr << "SelectionDAG::clearGraphAttrs is only available in debug builds"
182            << " on systems with Graphviz or gv!\n";
183#endif
184}
185
186
187/// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".)
188///
189void SelectionDAG::setGraphAttrs(const SDNode *N, const char *Attrs) {
190#ifndef NDEBUG
191  NodeGraphAttrs[N] = Attrs;
192#else
193  std::cerr << "SelectionDAG::setGraphAttrs is only available in debug builds"
194            << " on systems with Graphviz or gv!\n";
195#endif
196}
197
198
199/// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".)
200/// Used from getNodeAttributes.
201const std::string SelectionDAG::getGraphAttrs(const SDNode *N) const {
202#ifndef NDEBUG
203  std::map<const SDNode *, std::string>::const_iterator I =
204    NodeGraphAttrs.find(N);
205
206  if (I != NodeGraphAttrs.end())
207    return I->second;
208  else
209    return "";
210#else
211  std::cerr << "SelectionDAG::getGraphAttrs is only available in debug builds"
212            << " on systems with Graphviz or gv!\n";
213  return std::string("");
214#endif
215}
216
217/// setGraphColor - Convenience for setting node color attribute.
218///
219void SelectionDAG::setGraphColor(const SDNode *N, const char *Color) {
220#ifndef NDEBUG
221  NodeGraphAttrs[N] = std::string("color=") + Color;
222#else
223  std::cerr << "SelectionDAG::setGraphColor is only available in debug builds"
224            << " on systems with Graphviz or gv!\n";
225#endif
226}
227
228