SelectionDAGPrinter.cpp revision d6594ae54cfde4db4d30272192645c0a45fb9902
166328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner//===-- SelectionDAGPrinter.cpp - Implement SelectionDAG::viewGraph() -----===//
2edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman//
366328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner//                     The LLVM Compiler Infrastructure
466328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner//
566328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner// This file was developed by the LLVM research group and is distributed under
666328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner// the University of Illinois Open Source License. See LICENSE.TXT for details.
7edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman//
866328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner//===----------------------------------------------------------------------===//
966328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner//
1066328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner// This implements the SelectionDAG::viewGraph method.
1166328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner//
1266328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner//===----------------------------------------------------------------------===//
1366328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner
145839bf2b3bd22689d9dd0e9de66c2dce71d130aeChris Lattner#include "llvm/Constants.h"
155839bf2b3bd22689d9dd0e9de66c2dce71d130aeChris Lattner#include "llvm/Function.h"
1652676510577a5fdab082eb0c065ae151903d9dcfChris Lattner#include "llvm/Assembly/Writer.h"
1766328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner#include "llvm/CodeGen/SelectionDAG.h"
18d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng#include "llvm/CodeGen/MachineConstantPool.h"
1966328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner#include "llvm/CodeGen/MachineFunction.h"
207228aa78686c2920c0f8588628b1278698720d07Chris Lattner#include "llvm/Target/MRegisterInfo.h"
217228aa78686c2920c0f8588628b1278698720d07Chris Lattner#include "llvm/Target/TargetMachine.h"
2266328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner#include "llvm/Support/GraphWriter.h"
23e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner#include "llvm/ADT/StringExtras.h"
246e741f8842b5570e30f25912dbdaaa2edf36110cChris Lattner#include "llvm/Config/config.h"
2566328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner#include <fstream>
2652676510577a5fdab082eb0c065ae151903d9dcfChris Lattner#include <sstream>
2766328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattnerusing namespace llvm;
2866328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner
29e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattnernamespace llvm {
30e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner  template<>
31e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner  struct DOTGraphTraits<SelectionDAG*> : public DefaultDOTGraphTraits {
32e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner    static std::string getGraphName(const SelectionDAG *G) {
33e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner      return G->getMachineFunction().getFunction()->getName();
34e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner    }
35e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner
36e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner    static bool renderGraphFromBottomUp() {
37e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner      return true;
38e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner    }
3937345fe3cd2dd56c3711592a5af6c294c10c7abaChris Lattner
4037345fe3cd2dd56c3711592a5af6c294c10c7abaChris Lattner    static bool hasNodeAddressLabel(const SDNode *Node,
4137345fe3cd2dd56c3711592a5af6c294c10c7abaChris Lattner                                    const SelectionDAG *Graph) {
4237345fe3cd2dd56c3711592a5af6c294c10c7abaChris Lattner      return true;
4337345fe3cd2dd56c3711592a5af6c294c10c7abaChris Lattner    }
44e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner
45e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner    static std::string getNodeLabel(const SDNode *Node,
46e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner                                    const SelectionDAG *Graph);
47e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner    static std::string getNodeAttributes(const SDNode *N) {
48e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner      return "shape=Mrecord";
49e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner    }
50fc08d9c789b6698fe5f5904d573bb03fcc52a32dChris Lattner
51fc08d9c789b6698fe5f5904d573bb03fcc52a32dChris Lattner    static void addCustomGraphFeatures(SelectionDAG *G,
52fc08d9c789b6698fe5f5904d573bb03fcc52a32dChris Lattner                                       GraphWriter<SelectionDAG*> &GW) {
53fc08d9c789b6698fe5f5904d573bb03fcc52a32dChris Lattner      GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot");
54fc08d9c789b6698fe5f5904d573bb03fcc52a32dChris Lattner      GW.emitEdge(0, -1, G->getRoot().Val, -1, "");
55fc08d9c789b6698fe5f5904d573bb03fcc52a32dChris Lattner    }
56e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner  };
57e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner}
58e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner
59e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattnerstd::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
60e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner                                                        const SelectionDAG *G) {
61ad95d6ab201bad53ae155a06d49cc16cfbebe507Chris Lattner  std::string Op = Node->getOperationName(G);
62c871e1d56fa9e4c73f01419d4f1fef6d47f24d29Chris Lattner
63ad95d6ab201bad53ae155a06d49cc16cfbebe507Chris Lattner  for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i)
64ad95d6ab201bad53ae155a06d49cc16cfbebe507Chris Lattner    if (Node->getValueType(i) == MVT::Other)
65ad95d6ab201bad53ae155a06d49cc16cfbebe507Chris Lattner      Op += ":ch";
66ad95d6ab201bad53ae155a06d49cc16cfbebe507Chris Lattner    else
67ad95d6ab201bad53ae155a06d49cc16cfbebe507Chris Lattner      Op = Op + ":" + MVT::getValueTypeString(Node->getValueType(i));
68ad95d6ab201bad53ae155a06d49cc16cfbebe507Chris Lattner
69e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner  if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(Node)) {
70e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner    Op += ": " + utostr(CSDN->getValue());
71e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner  } else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(Node)) {
72e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner    Op += ": " + ftostr(CSDN->getValue());
73edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman  } else if (const GlobalAddressSDNode *GADN =
74e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner             dyn_cast<GlobalAddressSDNode>(Node)) {
7561ca74bc3a29b2af2be7e4bd612289da8aae85b5Evan Cheng    int offset = GADN->getOffset();
76e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner    Op += ": " + GADN->getGlobal()->getName();
7761ca74bc3a29b2af2be7e4bd612289da8aae85b5Evan Cheng    if (offset > 0)
7861ca74bc3a29b2af2be7e4bd612289da8aae85b5Evan Cheng      Op += "+" + itostr(offset);
7961ca74bc3a29b2af2be7e4bd612289da8aae85b5Evan Cheng    else
8061ca74bc3a29b2af2be7e4bd612289da8aae85b5Evan Cheng      Op += itostr(offset);
81dedf2bd5a34dac25e4245f58bb902ced6b64edd9Misha Brukman  } else if (const FrameIndexSDNode *FIDN = dyn_cast<FrameIndexSDNode>(Node)) {
82e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner    Op += " " + itostr(FIDN->getIndex());
83e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner  } else if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Node)){
84d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng    if (CP->isMachineConstantPoolEntry()) {
8552676510577a5fdab082eb0c065ae151903d9dcfChris Lattner      std::ostringstream SS;
86d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng      CP->getMachineCPVal()->print(SS);
8752676510577a5fdab082eb0c065ae151903d9dcfChris Lattner      Op += "<" + SS.str() + ">";
88d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng    } else {
89d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng      if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
90d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng        Op += "<" + ftostr(CFP->getValue()) + ">";
91d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng      else if (ConstantInt *CI = dyn_cast<ConstantInt>(CP->getConstVal()))
92d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng        Op += "<" + utostr(CI->getZExtValue()) + ">";
93d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng      else {
94d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng        std::ostringstream SS;
95d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng        WriteAsOperand(SS, CP->getConstVal(), false);
96d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng        Op += "<" + SS.str() + ">";
97d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng      }
9852676510577a5fdab082eb0c065ae151903d9dcfChris Lattner    }
99dedf2bd5a34dac25e4245f58bb902ced6b64edd9Misha Brukman  } else if (const BasicBlockSDNode *BBDN = dyn_cast<BasicBlockSDNode>(Node)) {
100e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner    Op = "BB: ";
101e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner    const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock();
102e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner    if (LBB)
103e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner      Op += LBB->getName();
104e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner    //Op += " " + (const void*)BBDN->getBasicBlock();
105d5d0f9bd20d9df07d6b4d41b7e8ed6d33b6a649dChris Lattner  } else if (const RegisterSDNode *R = dyn_cast<RegisterSDNode>(Node)) {
10644fa764355eec81d8ef8fbd63824695b1554c4abChris Lattner    if (G && R->getReg() != 0 && MRegisterInfo::isPhysicalRegister(R->getReg())) {
1077228aa78686c2920c0f8588628b1278698720d07Chris Lattner      Op = Op + " " + G->getTarget().getRegisterInfo()->getName(R->getReg());
1087228aa78686c2920c0f8588628b1278698720d07Chris Lattner    } else {
1097228aa78686c2920c0f8588628b1278698720d07Chris Lattner      Op += " #" + utostr(R->getReg());
1107228aa78686c2920c0f8588628b1278698720d07Chris Lattner    }
111e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner  } else if (const ExternalSymbolSDNode *ES =
112e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner             dyn_cast<ExternalSymbolSDNode>(Node)) {
113e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner    Op += "'" + std::string(ES->getSymbol()) + "'";
1142bf3c26b2bb783aada259f1c70be6dd0798f6126Chris Lattner  } else if (const SrcValueSDNode *M = dyn_cast<SrcValueSDNode>(Node)) {
1152bf3c26b2bb783aada259f1c70be6dd0798f6126Chris Lattner    if (M->getValue())
1162bf3c26b2bb783aada259f1c70be6dd0798f6126Chris Lattner      Op += "<" + M->getValue()->getName() + ":" + itostr(M->getOffset()) + ">";
1172bf3c26b2bb783aada259f1c70be6dd0798f6126Chris Lattner    else
1182bf3c26b2bb783aada259f1c70be6dd0798f6126Chris Lattner      Op += "<null:" + itostr(M->getOffset()) + ">";
119a23e8154dc58a62225074bb4eb1633c363ce331bChris Lattner  } else if (const VTSDNode *N = dyn_cast<VTSDNode>(Node)) {
120e39db07713641cb933d1183a343ffe4eb8f44492Chris Lattner    Op = Op + " VT=" + getValueTypeString(N->getVT());
12136ce69195ed488034d0bb11180cc2ebd923679c8Chris Lattner  } else if (const StringSDNode *N = dyn_cast<StringSDNode>(Node)) {
12236ce69195ed488034d0bb11180cc2ebd923679c8Chris Lattner    Op = Op + "\"" + N->getValue() + "\"";
123e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner  }
12436ce69195ed488034d0bb11180cc2ebd923679c8Chris Lattner
125e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner  return Op;
126e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner}
127edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman
128e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner
12966328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner/// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
13066328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner/// rendered using 'dot'.
13166328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner///
13266328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattnervoid SelectionDAG::viewGraph() {
133e388b5ea2c599a1db72497bf2d2920895da28f47Chris Lattner// This code is only for debugging!
134c5f44add43bf9ecb7f1f63a320e4440f8f0784c3Chris Lattner#ifndef NDEBUG
1359d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  ViewGraph(this, "dag." + getMachineFunction().getFunction()->getName());
1369d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#else
137c5f44add43bf9ecb7f1f63a320e4440f8f0784c3Chris Lattner  std::cerr << "SelectionDAG::viewGraph is only available in debug builds on "
138c5f44add43bf9ecb7f1f63a320e4440f8f0784c3Chris Lattner            << "systems with Graphviz or gv!\n";
1399d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#endif  // NDEBUG
14066328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner}
141