166328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner//===-- SelectionDAGPrinter.cpp - Implement SelectionDAG::viewGraph() -----===//
2edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman//
366328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner//                     The LLVM Compiler Infrastructure
466328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// 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
14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/SelectionDAG.h"
1584fbac580941548a6ab1121ed3b0ffdc4e2bc080Dan Gohman#include "ScheduleDAGSDNodes.h"
16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/DenseSet.h"
17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/StringExtras.h"
18d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng#include "llvm/CodeGen/MachineConstantPool.h"
1966328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner#include "llvm/CodeGen/MachineFunction.h"
2010fff6078a7bc42f142c536bd55e9569253b280bBill Wendling#include "llvm/CodeGen/MachineModuleInfo.h"
210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h"
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DebugInfo.h"
23c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene#include "llvm/Support/Debug.h"
2466328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner#include "llvm/Support/GraphWriter.h"
2562ca32540f950d500227f1863b95cd08ad28099eChris Lattner#include "llvm/Support/raw_ostream.h"
26d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetMachine.h"
27d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetRegisterInfo.h"
2866328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattnerusing namespace llvm;
2966328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner
30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "dag-printer"
31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
32e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattnernamespace llvm {
33e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner  template<>
34e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner  struct DOTGraphTraits<SelectionDAG*> : public DefaultDOTGraphTraits {
35a10d598602308549d87d2c5d9848f5a72fda2b43Tobias Grosser
360baf2a302fe6e130756bf8b3da831547f0b87190Dan Gohman    explicit DOTGraphTraits(bool isSimple=false) :
370baf2a302fe6e130756bf8b3da831547f0b87190Dan Gohman      DefaultDOTGraphTraits(isSimple) {}
38a10d598602308549d87d2c5d9848f5a72fda2b43Tobias Grosser
39358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    static bool hasEdgeDestLabels() {
40358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman      return true;
41358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    }
42358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman
43358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    static unsigned numEdgeDestLabels(const void *Node) {
44358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman      return ((const SDNode *) Node)->getNumValues();
45358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    }
46358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman
47358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    static std::string getEdgeDestLabel(const void *Node, unsigned i) {
48e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson      return ((const SDNode *) Node)->getValueType(i).getEVTString();
49358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    }
50358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman
515b69fe767ca0786ecb50e703f2da8ea09de5da7cDan Gohman    template<typename EdgeIter>
525b69fe767ca0786ecb50e703f2da8ea09de5da7cDan Gohman    static std::string getEdgeSourceLabel(const void *Node, EdgeIter I) {
53141e99745adbd3ba9fa7315af3384c1d08c4c20cRoman Divacky      return itostr(I - SDNodeIterator::begin((const SDNode *) Node));
545b69fe767ca0786ecb50e703f2da8ea09de5da7cDan Gohman    }
555b69fe767ca0786ecb50e703f2da8ea09de5da7cDan Gohman
56358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    /// edgeTargetsEdgeSource - This method returns true if this outgoing edge
57a10d598602308549d87d2c5d9848f5a72fda2b43Tobias Grosser    /// should actually target another edge source, not a node.  If this method
58a10d598602308549d87d2c5d9848f5a72fda2b43Tobias Grosser    /// is implemented, getEdgeTarget should be implemented.
59358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    template<typename EdgeIter>
60358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I) {
61358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman      return true;
62358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    }
63358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman
64358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is
65358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    /// called to determine which outgoing edge of Node is the target of this
66358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    /// edge.
67358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    template<typename EdgeIter>
68358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    static EdgeIter getEdgeTarget(const void *Node, EdgeIter I) {
69358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman      SDNode *TargetNode = *I;
70358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman      SDNodeIterator NI = SDNodeIterator::begin(TargetNode);
7199a6cb92d173c142073416c81efe6d3daeb80b49Gabor Greif      std::advance(NI, I.getNode()->getOperand(I.getOperand()).getResNo());
72358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman      return NI;
73358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman    }
74358033102ffaef4d1afb1c0b7e96440906f0b48fDan Gohman
75e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner    static std::string getGraphName(const SelectionDAG *G) {
7696601ca332ab388754ca4673be8973396fea2dddCraig Topper      return G->getMachineFunction().getName();
77e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner    }
78e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner
79e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner    static bool renderGraphFromBottomUp() {
80e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner      return true;
81e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner    }
820baf2a302fe6e130756bf8b3da831547f0b87190Dan Gohman
83f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static std::string getNodeIdentifierLabel(const SDNode *Node,
84f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                              const SelectionDAG *Graph) {
85f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      std::string R;
86f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      raw_string_ostream OS(R);
87f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#ifndef NDEBUG
88f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      OS << 't' << Node->PersistentId;
89f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#else
90f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      OS << static_cast<const void *>(Node);
91f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#endif
92f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return R;
9337345fe3cd2dd56c3711592a5af6c294c10c7abaChris Lattner    }
940baf2a302fe6e130756bf8b3da831547f0b87190Dan Gohman
9534ab4d45d2aa11bee666836e3571be2627959a42Chris Lattner    /// If you want to override the dot attributes printed for a particular
9634ab4d45d2aa11bee666836e3571be2627959a42Chris Lattner    /// edge, override this method.
9734ab4d45d2aa11bee666836e3571be2627959a42Chris Lattner    template<typename EdgeIter>
98a91f86c49a63f7a37c662c3a9553055bff33a84bTobias Grosser    static std::string getEdgeAttributes(const void *Node, EdgeIter EI,
99a91f86c49a63f7a37c662c3a9553055bff33a84bTobias Grosser                                         const SelectionDAG *Graph) {
100475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue Op = EI.getNode()->getOperand(EI.getOperand());
101e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson      EVT VT = Op.getValueType();
102f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner      if (VT == MVT::Glue)
10334ab4d45d2aa11bee666836e3571be2627959a42Chris Lattner        return "color=red,style=bold";
104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      else if (VT == MVT::Other)
1057a0a4fc9127039cc7c55d74994fe7790ac30de43Dan Gohman        return "color=blue,style=dashed";
10634ab4d45d2aa11bee666836e3571be2627959a42Chris Lattner      return "";
10734ab4d45d2aa11bee666836e3571be2627959a42Chris Lattner    }
1080baf2a302fe6e130756bf8b3da831547f0b87190Dan Gohman
109e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner
11056f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser    static std::string getSimpleNodeLabel(const SDNode *Node,
11156f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser                                          const SelectionDAG *G) {
11256f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser      std::string Result = Node->getOperationName(G);
11356f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser      {
11456f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser        raw_string_ostream OS(Result);
11556f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser        Node->print_details(OS, G);
11656f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser      }
11756f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser      return Result;
11856f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser    }
11956f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser    std::string getNodeLabel(const SDNode *Node, const SelectionDAG *Graph);
120ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey    static std::string getNodeAttributes(const SDNode *N,
121ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey                                         const SelectionDAG *Graph) {
122ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#ifndef NDEBUG
123ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey      const std::string &Attrs = Graph->getGraphAttrs(N);
124ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey      if (!Attrs.empty()) {
125ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey        if (Attrs.find("shape=") == std::string::npos)
126ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey          return std::string("shape=Mrecord,") + Attrs;
127ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey        else
128ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey          return Attrs;
129ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey      }
130ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#endif
131e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner      return "shape=Mrecord";
132e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner    }
133fc08d9c789b6698fe5f5904d573bb03fcc52a32dChris Lattner
134fc08d9c789b6698fe5f5904d573bb03fcc52a32dChris Lattner    static void addCustomGraphFeatures(SelectionDAG *G,
135fc08d9c789b6698fe5f5904d573bb03fcc52a32dChris Lattner                                       GraphWriter<SelectionDAG*> &GW) {
136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      GW.emitSimpleNode(nullptr, "plaintext=circle", "GraphRoot");
137ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif      if (G->getRoot().getNode())
138dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        GW.emitEdge(nullptr, -1, G->getRoot().getNode(), G->getRoot().getResNo(),
139694caf56f15bec971d493069a1613a8f992f510aDan Gohman                    "color=blue,style=dashed");
140fc08d9c789b6698fe5f5904d573bb03fcc52a32dChris Lattner    }
141e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner  };
142e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner}
143e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner
144e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattnerstd::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
14556f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser                                                        const SelectionDAG *G) {
1460baf2a302fe6e130756bf8b3da831547f0b87190Dan Gohman  return DOTGraphTraits<SelectionDAG*>::getSimpleNodeLabel(Node, G);
147e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner}
148edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman
149e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner
15066328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner/// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
15166328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner/// rendered using 'dot'.
15266328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner///
153462dc7f4960e5074ddf4769ec8b2ef1ba7a4d2c8Dan Gohmanvoid SelectionDAG::viewGraph(const std::string &Title) {
154e388b5ea2c599a1db72497bf2d2920895da28f47Chris Lattner// This code is only for debugging!
155c5f44add43bf9ecb7f1f63a320e4440f8f0784c3Chris Lattner#ifndef NDEBUG
15696601ca332ab388754ca4673be8973396fea2dddCraig Topper  ViewGraph(this, "dag." + getMachineFunction().getName(),
157f6ccee5a9d2b9573f679bca6266ade3eb8cd3f88Daniel Dunbar            false, Title);
1589d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#else
15943ed267db3512823a9698f810be4e64bee227270Daniel Dunbar  errs() << "SelectionDAG::viewGraph is only available in debug builds on "
16043ed267db3512823a9698f810be4e64bee227270Daniel Dunbar         << "systems with Graphviz or gv!\n";
1619d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#endif  // NDEBUG
16266328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner}
163ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
1640b12aef49087b57d276ed760a83525d1e2602144Dan Gohman// This overload is defined out-of-line here instead of just using a
1650b12aef49087b57d276ed760a83525d1e2602144Dan Gohman// default parameter because this is easiest for gdb to call.
1660b12aef49087b57d276ed760a83525d1e2602144Dan Gohmanvoid SelectionDAG::viewGraph() {
1670b12aef49087b57d276ed760a83525d1e2602144Dan Gohman  viewGraph("");
1680b12aef49087b57d276ed760a83525d1e2602144Dan Gohman}
169ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
170ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey/// clearGraphAttrs - Clear all previously defined node graph attributes.
171ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey/// Intended to be used from a debugging tool (eg. gdb).
172ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskeyvoid SelectionDAG::clearGraphAttrs() {
173ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#ifndef NDEBUG
174ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey  NodeGraphAttrs.clear();
175ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#else
17643ed267db3512823a9698f810be4e64bee227270Daniel Dunbar  errs() << "SelectionDAG::clearGraphAttrs is only available in debug builds"
17743ed267db3512823a9698f810be4e64bee227270Daniel Dunbar         << " on systems with Graphviz or gv!\n";
178ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#endif
179ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey}
180ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
181ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
182ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey/// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".)
183ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey///
184ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskeyvoid SelectionDAG::setGraphAttrs(const SDNode *N, const char *Attrs) {
185ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#ifndef NDEBUG
186ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey  NodeGraphAttrs[N] = Attrs;
187ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#else
18843ed267db3512823a9698f810be4e64bee227270Daniel Dunbar  errs() << "SelectionDAG::setGraphAttrs is only available in debug builds"
18943ed267db3512823a9698f810be4e64bee227270Daniel Dunbar         << " on systems with Graphviz or gv!\n";
190ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#endif
191ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey}
192ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
193ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
194ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey/// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".)
195ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey/// Used from getNodeAttributes.
196ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskeyconst std::string SelectionDAG::getGraphAttrs(const SDNode *N) const {
197ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#ifndef NDEBUG
198ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey  std::map<const SDNode *, std::string>::const_iterator I =
199ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey    NodeGraphAttrs.find(N);
2000baf2a302fe6e130756bf8b3da831547f0b87190Dan Gohman
201ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey  if (I != NodeGraphAttrs.end())
202ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey    return I->second;
203ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey  else
204ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey    return "";
205ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#else
20643ed267db3512823a9698f810be4e64bee227270Daniel Dunbar  errs() << "SelectionDAG::getGraphAttrs is only available in debug builds"
20743ed267db3512823a9698f810be4e64bee227270Daniel Dunbar         << " on systems with Graphviz or gv!\n";
208d98af0a5b86425fdc723bb54fc59247c585d63abDan Gohman  return std::string();
209ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#endif
210ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey}
211ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
212ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey/// setGraphColor - Convenience for setting node color attribute.
213ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey///
214ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskeyvoid SelectionDAG::setGraphColor(const SDNode *N, const char *Color) {
215ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#ifndef NDEBUG
216ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey  NodeGraphAttrs[N] = std::string("color=") + Color;
217ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#else
21843ed267db3512823a9698f810be4e64bee227270Daniel Dunbar  errs() << "SelectionDAG::setGraphColor is only available in debug builds"
21943ed267db3512823a9698f810be4e64bee227270Daniel Dunbar         << " on systems with Graphviz or gv!\n";
220ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#endif
221ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey}
222ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
223c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene/// setSubgraphColorHelper - Implement setSubgraphColor.  Return
224c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene/// whether we truncated the search.
225c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene///
226c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greenebool SelectionDAG::setSubgraphColorHelper(SDNode *N, const char *Color, DenseSet<SDNode *> &visited,
227c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene                                          int level, bool &printed) {
228c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  bool hit_limit = false;
229c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene
230c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene#ifndef NDEBUG
231c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  if (level >= 20) {
232c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    if (!printed) {
233c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene      printed = true;
2349abe0bbd9089c98ae4ad7bae589ea0ebb51bb3f5David Greene      DEBUG(dbgs() << "setSubgraphColor hit max level\n");
235c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    }
236c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    return true;
237c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  }
238c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene
239c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  unsigned oldSize = visited.size();
240c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  visited.insert(N);
241c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  if (visited.size() != oldSize) {
242c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    setGraphColor(N, Color);
243c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    for(SDNodeIterator i = SDNodeIterator::begin(N), iend = SDNodeIterator::end(N);
244c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene        i != iend;
245c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene        ++i) {
246c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene      hit_limit = setSubgraphColorHelper(*i, Color, visited, level+1, printed) || hit_limit;
247c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    }
248c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  }
249c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene#else
25043ed267db3512823a9698f810be4e64bee227270Daniel Dunbar  errs() << "SelectionDAG::setSubgraphColor is only available in debug builds"
25143ed267db3512823a9698f810be4e64bee227270Daniel Dunbar         << " on systems with Graphviz or gv!\n";
252c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene#endif
253c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  return hit_limit;
254c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene}
255c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene
256c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene/// setSubgraphColor - Convenience for setting subgraph color attribute.
257c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene///
258c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greenevoid SelectionDAG::setSubgraphColor(SDNode *N, const char *Color) {
259c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene#ifndef NDEBUG
260c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  DenseSet<SDNode *> visited;
261c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  bool printed = false;
262c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  if (setSubgraphColorHelper(N, Color, visited, 0, printed)) {
263c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    // Visually mark that we hit the limit
2648e7fa916fe87733b3660466b3a1c91d650c473d3Ted Kremenek    if (strcmp(Color, "red") == 0) {
265c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene      setSubgraphColorHelper(N, "blue", visited, 0, printed);
2660baf2a302fe6e130756bf8b3da831547f0b87190Dan Gohman    } else if (strcmp(Color, "yellow") == 0) {
267c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene      setSubgraphColorHelper(N, "green", visited, 0, printed);
268c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    }
269c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  }
270c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene
271c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene#else
27243ed267db3512823a9698f810be4e64bee227270Daniel Dunbar  errs() << "SelectionDAG::setSubgraphColor is only available in debug builds"
27343ed267db3512823a9698f810be4e64bee227270Daniel Dunbar         << " on systems with Graphviz or gv!\n";
274c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene#endif
275c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene}
276c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene
277343f0c046702831a4a6aec951b6a297a23241a55Dan Gohmanstd::string ScheduleDAGSDNodes::getGraphNodeLabel(const SUnit *SU) const {
2787d1cd3f21d68179f4ebf4ee18fb7a0ddca9c5a37Dan Gohman  std::string s;
2797d1cd3f21d68179f4ebf4ee18fb7a0ddca9c5a37Dan Gohman  raw_string_ostream O(s);
2807d1cd3f21d68179f4ebf4ee18fb7a0ddca9c5a37Dan Gohman  O << "SU(" << SU->NodeNum << "): ";
2817d1cd3f21d68179f4ebf4ee18fb7a0ddca9c5a37Dan Gohman  if (SU->getNode()) {
28229d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner    SmallVector<SDNode *, 4> GluedNodes;
28329d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner    for (SDNode *N = SU->getNode(); N; N = N->getGluedNode())
28429d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner      GluedNodes.push_back(N);
28529d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner    while (!GluedNodes.empty()) {
28656f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser      O << DOTGraphTraits<SelectionDAG*>
28729d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner        ::getSimpleNodeLabel(GluedNodes.back(), DAG);
28829d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner      GluedNodes.pop_back();
28929d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner      if (!GluedNodes.empty())
2907d1cd3f21d68179f4ebf4ee18fb7a0ddca9c5a37Dan Gohman        O << "\n    ";
291d23e0f81bc76902052e9198cad3a0d87a412a632Dan Gohman    }
292505a551dab05029d2c7b5dc65a879d35e03e17c1Dan Gohman  } else {
2937d1cd3f21d68179f4ebf4ee18fb7a0ddca9c5a37Dan Gohman    O << "CROSS RC COPY";
2943e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  }
2957d1cd3f21d68179f4ebf4ee18fb7a0ddca9c5a37Dan Gohman  return O.str();
2963e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman}
2973e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
298343f0c046702831a4a6aec951b6a297a23241a55Dan Gohmanvoid ScheduleDAGSDNodes::getCustomGraphFeatures(GraphWriter<ScheduleDAG*> &GW) const {
299343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman  if (DAG) {
300343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman    // Draw a special "GraphRoot" node to indicate the root of the graph.
301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    GW.emitSimpleNode(nullptr, "plaintext=circle", "GraphRoot");
302343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman    const SDNode *N = DAG->getRoot().getNode();
303343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman    if (N && N->getNodeId() != -1)
304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      GW.emitEdge(nullptr, -1, &SUnits[N->getNodeId()], -1,
305343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman                  "color=blue,style=dashed");
306343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman  }
3073e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman}
308