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
1484fbac580941548a6ab1121ed3b0ffdc4e2bc080Dan Gohman#include "ScheduleDAGSDNodes.h"
155839bf2b3bd22689d9dd0e9de66c2dce71d130aeChris Lattner#include "llvm/Constants.h"
165839bf2b3bd22689d9dd0e9de66c2dce71d130aeChris Lattner#include "llvm/Function.h"
1752676510577a5fdab082eb0c065ae151903d9dcfChris Lattner#include "llvm/Assembly/Writer.h"
1866328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner#include "llvm/CodeGen/SelectionDAG.h"
19d6594ae54cfde4db4d30272192645c0a45fb9902Evan Cheng#include "llvm/CodeGen/MachineConstantPool.h"
2066328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner#include "llvm/CodeGen/MachineFunction.h"
2110fff6078a7bc42f142c536bd55e9569253b280bBill Wendling#include "llvm/CodeGen/MachineModuleInfo.h"
2283489bb7700c69b7a4a8da59365c42d3f5c8129bDevang Patel#include "llvm/Analysis/DebugInfo.h"
236f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman#include "llvm/Target/TargetRegisterInfo.h"
247228aa78686c2920c0f8588628b1278698720d07Chris Lattner#include "llvm/Target/TargetMachine.h"
25c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene#include "llvm/Support/Debug.h"
2666328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner#include "llvm/Support/GraphWriter.h"
2762ca32540f950d500227f1863b95cd08ad28099eChris Lattner#include "llvm/Support/raw_ostream.h"
28c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene#include "llvm/ADT/DenseSet.h"
29e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner#include "llvm/ADT/StringExtras.h"
3066328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattnerusing namespace llvm;
3166328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner
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) {
535b69fe767ca0786ecb50e703f2da8ea09de5da7cDan Gohman      return itostr(I - SDNodeIterator::begin((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) {
76e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner      return G->getMachineFunction().getFunction()->getName();
77e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner    }
78e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner
79e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner    static bool renderGraphFromBottomUp() {
80e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner      return true;
81e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner    }
820baf2a302fe6e130756bf8b3da831547f0b87190Dan Gohman
8337345fe3cd2dd56c3711592a5af6c294c10c7abaChris Lattner    static bool hasNodeAddressLabel(const SDNode *Node,
8437345fe3cd2dd56c3711592a5af6c294c10c7abaChris Lattner                                    const SelectionDAG *Graph) {
8537345fe3cd2dd56c3711592a5af6c294c10c7abaChris Lattner      return true;
8637345fe3cd2dd56c3711592a5af6c294c10c7abaChris Lattner    }
870baf2a302fe6e130756bf8b3da831547f0b87190Dan Gohman
8834ab4d45d2aa11bee666836e3571be2627959a42Chris Lattner    /// If you want to override the dot attributes printed for a particular
8934ab4d45d2aa11bee666836e3571be2627959a42Chris Lattner    /// edge, override this method.
9034ab4d45d2aa11bee666836e3571be2627959a42Chris Lattner    template<typename EdgeIter>
91a91f86c49a63f7a37c662c3a9553055bff33a84bTobias Grosser    static std::string getEdgeAttributes(const void *Node, EdgeIter EI,
92a91f86c49a63f7a37c662c3a9553055bff33a84bTobias Grosser                                         const SelectionDAG *Graph) {
93475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue Op = EI.getNode()->getOperand(EI.getOperand());
94e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson      EVT VT = Op.getValueType();
95f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner      if (VT == MVT::Glue)
9634ab4d45d2aa11bee666836e3571be2627959a42Chris Lattner        return "color=red,style=bold";
97825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      else if (VT == MVT::Other)
987a0a4fc9127039cc7c55d74994fe7790ac30de43Dan Gohman        return "color=blue,style=dashed";
9934ab4d45d2aa11bee666836e3571be2627959a42Chris Lattner      return "";
10034ab4d45d2aa11bee666836e3571be2627959a42Chris Lattner    }
1010baf2a302fe6e130756bf8b3da831547f0b87190Dan Gohman
102e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner
10356f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser    static std::string getSimpleNodeLabel(const SDNode *Node,
10456f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser                                          const SelectionDAG *G) {
10556f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser      std::string Result = Node->getOperationName(G);
10656f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser      {
10756f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser        raw_string_ostream OS(Result);
10856f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser        Node->print_details(OS, G);
10956f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser      }
11056f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser      return Result;
11156f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser    }
11256f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser    std::string getNodeLabel(const SDNode *Node, const SelectionDAG *Graph);
113ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey    static std::string getNodeAttributes(const SDNode *N,
114ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey                                         const SelectionDAG *Graph) {
115ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#ifndef NDEBUG
116ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey      const std::string &Attrs = Graph->getGraphAttrs(N);
117ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey      if (!Attrs.empty()) {
118ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey        if (Attrs.find("shape=") == std::string::npos)
119ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey          return std::string("shape=Mrecord,") + Attrs;
120ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey        else
121ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey          return Attrs;
122ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey      }
123ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#endif
124e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner      return "shape=Mrecord";
125e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner    }
126fc08d9c789b6698fe5f5904d573bb03fcc52a32dChris Lattner
127fc08d9c789b6698fe5f5904d573bb03fcc52a32dChris Lattner    static void addCustomGraphFeatures(SelectionDAG *G,
128fc08d9c789b6698fe5f5904d573bb03fcc52a32dChris Lattner                                       GraphWriter<SelectionDAG*> &GW) {
129fc08d9c789b6698fe5f5904d573bb03fcc52a32dChris Lattner      GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot");
130ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif      if (G->getRoot().getNode())
131ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif        GW.emitEdge(0, -1, G->getRoot().getNode(), G->getRoot().getResNo(),
132694caf56f15bec971d493069a1613a8f992f510aDan Gohman                    "color=blue,style=dashed");
133fc08d9c789b6698fe5f5904d573bb03fcc52a32dChris Lattner    }
134e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner  };
135e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner}
136e0646b86e3cdc35c5dd0e1c10b7ac564066e3bd6Chris Lattner
137e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattnerstd::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
13856f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser                                                        const SelectionDAG *G) {
1390baf2a302fe6e130756bf8b3da831547f0b87190Dan Gohman  return DOTGraphTraits<SelectionDAG*>::getSimpleNodeLabel(Node, G);
140e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner}
141edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman
142e9c44cdf18b1235841a5d8bfeb07bee9f5699b9aChris Lattner
14366328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner/// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
14466328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner/// rendered using 'dot'.
14566328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner///
146462dc7f4960e5074ddf4769ec8b2ef1ba7a4d2c8Dan Gohmanvoid SelectionDAG::viewGraph(const std::string &Title) {
147e388b5ea2c599a1db72497bf2d2920895da28f47Chris Lattner// This code is only for debugging!
148c5f44add43bf9ecb7f1f63a320e4440f8f0784c3Chris Lattner#ifndef NDEBUG
14925ad1cc32af8d526eb72893a513a486bc28c5106Benjamin Kramer  ViewGraph(this, "dag." + getMachineFunction().getFunction()->getName(),
150f6ccee5a9d2b9573f679bca6266ade3eb8cd3f88Daniel Dunbar            false, Title);
1519d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#else
15243ed267db3512823a9698f810be4e64bee227270Daniel Dunbar  errs() << "SelectionDAG::viewGraph is only available in debug builds on "
15343ed267db3512823a9698f810be4e64bee227270Daniel Dunbar         << "systems with Graphviz or gv!\n";
1549d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#endif  // NDEBUG
15566328480bb3eb6aa52e2c155657f3d19d4efea7aChris Lattner}
156ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
1570b12aef49087b57d276ed760a83525d1e2602144Dan Gohman// This overload is defined out-of-line here instead of just using a
1580b12aef49087b57d276ed760a83525d1e2602144Dan Gohman// default parameter because this is easiest for gdb to call.
1590b12aef49087b57d276ed760a83525d1e2602144Dan Gohmanvoid SelectionDAG::viewGraph() {
1600b12aef49087b57d276ed760a83525d1e2602144Dan Gohman  viewGraph("");
1610b12aef49087b57d276ed760a83525d1e2602144Dan Gohman}
162ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
163ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey/// clearGraphAttrs - Clear all previously defined node graph attributes.
164ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey/// Intended to be used from a debugging tool (eg. gdb).
165ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskeyvoid SelectionDAG::clearGraphAttrs() {
166ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#ifndef NDEBUG
167ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey  NodeGraphAttrs.clear();
168ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#else
16943ed267db3512823a9698f810be4e64bee227270Daniel Dunbar  errs() << "SelectionDAG::clearGraphAttrs is only available in debug builds"
17043ed267db3512823a9698f810be4e64bee227270Daniel Dunbar         << " on systems with Graphviz or gv!\n";
171ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#endif
172ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey}
173ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
174ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
175ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey/// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".)
176ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey///
177ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskeyvoid SelectionDAG::setGraphAttrs(const SDNode *N, const char *Attrs) {
178ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#ifndef NDEBUG
179ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey  NodeGraphAttrs[N] = Attrs;
180ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#else
18143ed267db3512823a9698f810be4e64bee227270Daniel Dunbar  errs() << "SelectionDAG::setGraphAttrs is only available in debug builds"
18243ed267db3512823a9698f810be4e64bee227270Daniel Dunbar         << " on systems with Graphviz or gv!\n";
183ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#endif
184ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey}
185ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
186ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
187ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey/// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".)
188ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey/// Used from getNodeAttributes.
189ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskeyconst std::string SelectionDAG::getGraphAttrs(const SDNode *N) const {
190ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#ifndef NDEBUG
191ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey  std::map<const SDNode *, std::string>::const_iterator I =
192ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey    NodeGraphAttrs.find(N);
1930baf2a302fe6e130756bf8b3da831547f0b87190Dan Gohman
194ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey  if (I != NodeGraphAttrs.end())
195ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey    return I->second;
196ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey  else
197ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey    return "";
198ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#else
19943ed267db3512823a9698f810be4e64bee227270Daniel Dunbar  errs() << "SelectionDAG::getGraphAttrs is only available in debug builds"
20043ed267db3512823a9698f810be4e64bee227270Daniel Dunbar         << " on systems with Graphviz or gv!\n";
201d98af0a5b86425fdc723bb54fc59247c585d63abDan Gohman  return std::string();
202ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#endif
203ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey}
204ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
205ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey/// setGraphColor - Convenience for setting node color attribute.
206ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey///
207ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskeyvoid SelectionDAG::setGraphColor(const SDNode *N, const char *Color) {
208ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#ifndef NDEBUG
209ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey  NodeGraphAttrs[N] = std::string("color=") + Color;
210ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#else
21143ed267db3512823a9698f810be4e64bee227270Daniel Dunbar  errs() << "SelectionDAG::setGraphColor is only available in debug builds"
21243ed267db3512823a9698f810be4e64bee227270Daniel Dunbar         << " on systems with Graphviz or gv!\n";
213ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey#endif
214ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey}
215ec20402c90b605afeedbcf0e3aabe6f8054f23ddJim Laskey
216c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene/// setSubgraphColorHelper - Implement setSubgraphColor.  Return
217c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene/// whether we truncated the search.
218c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene///
219c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greenebool SelectionDAG::setSubgraphColorHelper(SDNode *N, const char *Color, DenseSet<SDNode *> &visited,
220c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene                                          int level, bool &printed) {
221c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  bool hit_limit = false;
222c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene
223c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene#ifndef NDEBUG
224c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  if (level >= 20) {
225c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    if (!printed) {
226c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene      printed = true;
2279abe0bbd9089c98ae4ad7bae589ea0ebb51bb3f5David Greene      DEBUG(dbgs() << "setSubgraphColor hit max level\n");
228c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    }
229c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    return true;
230c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  }
231c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene
232c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  unsigned oldSize = visited.size();
233c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  visited.insert(N);
234c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  if (visited.size() != oldSize) {
235c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    setGraphColor(N, Color);
236c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    for(SDNodeIterator i = SDNodeIterator::begin(N), iend = SDNodeIterator::end(N);
237c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene        i != iend;
238c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene        ++i) {
239c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene      hit_limit = setSubgraphColorHelper(*i, Color, visited, level+1, printed) || hit_limit;
240c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    }
241c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  }
242c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene#else
24343ed267db3512823a9698f810be4e64bee227270Daniel Dunbar  errs() << "SelectionDAG::setSubgraphColor is only available in debug builds"
24443ed267db3512823a9698f810be4e64bee227270Daniel Dunbar         << " on systems with Graphviz or gv!\n";
245c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene#endif
246c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  return hit_limit;
247c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene}
248c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene
249c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene/// setSubgraphColor - Convenience for setting subgraph color attribute.
250c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene///
251c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greenevoid SelectionDAG::setSubgraphColor(SDNode *N, const char *Color) {
252c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene#ifndef NDEBUG
253c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  DenseSet<SDNode *> visited;
254c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  bool printed = false;
255c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  if (setSubgraphColorHelper(N, Color, visited, 0, printed)) {
256c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    // Visually mark that we hit the limit
2578e7fa916fe87733b3660466b3a1c91d650c473d3Ted Kremenek    if (strcmp(Color, "red") == 0) {
258c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene      setSubgraphColorHelper(N, "blue", visited, 0, printed);
2590baf2a302fe6e130756bf8b3da831547f0b87190Dan Gohman    } else if (strcmp(Color, "yellow") == 0) {
260c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene      setSubgraphColorHelper(N, "green", visited, 0, printed);
261c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene    }
262c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene  }
263c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene
264c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene#else
26543ed267db3512823a9698f810be4e64bee227270Daniel Dunbar  errs() << "SelectionDAG::setSubgraphColor is only available in debug builds"
26643ed267db3512823a9698f810be4e64bee227270Daniel Dunbar         << " on systems with Graphviz or gv!\n";
267c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene#endif
268c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene}
269c5e7e8d87d4a3b10edd5ac93ba1f3cdb4d1b449aDavid Greene
270343f0c046702831a4a6aec951b6a297a23241a55Dan Gohmanstd::string ScheduleDAGSDNodes::getGraphNodeLabel(const SUnit *SU) const {
2717d1cd3f21d68179f4ebf4ee18fb7a0ddca9c5a37Dan Gohman  std::string s;
2727d1cd3f21d68179f4ebf4ee18fb7a0ddca9c5a37Dan Gohman  raw_string_ostream O(s);
2737d1cd3f21d68179f4ebf4ee18fb7a0ddca9c5a37Dan Gohman  O << "SU(" << SU->NodeNum << "): ";
2747d1cd3f21d68179f4ebf4ee18fb7a0ddca9c5a37Dan Gohman  if (SU->getNode()) {
27529d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner    SmallVector<SDNode *, 4> GluedNodes;
27629d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner    for (SDNode *N = SU->getNode(); N; N = N->getGluedNode())
27729d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner      GluedNodes.push_back(N);
27829d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner    while (!GluedNodes.empty()) {
27956f4ef3232850e29c4635d0923910acce8887bd0Tobias Grosser      O << DOTGraphTraits<SelectionDAG*>
28029d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner        ::getSimpleNodeLabel(GluedNodes.back(), DAG);
28129d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner      GluedNodes.pop_back();
28229d8f0cae425f1bba583565227eaebf58f26ce73Chris Lattner      if (!GluedNodes.empty())
2837d1cd3f21d68179f4ebf4ee18fb7a0ddca9c5a37Dan Gohman        O << "\n    ";
284d23e0f81bc76902052e9198cad3a0d87a412a632Dan Gohman    }
285505a551dab05029d2c7b5dc65a879d35e03e17c1Dan Gohman  } else {
2867d1cd3f21d68179f4ebf4ee18fb7a0ddca9c5a37Dan Gohman    O << "CROSS RC COPY";
2873e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  }
2887d1cd3f21d68179f4ebf4ee18fb7a0ddca9c5a37Dan Gohman  return O.str();
2893e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman}
2903e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
291343f0c046702831a4a6aec951b6a297a23241a55Dan Gohmanvoid ScheduleDAGSDNodes::getCustomGraphFeatures(GraphWriter<ScheduleDAG*> &GW) const {
292343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman  if (DAG) {
293343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman    // Draw a special "GraphRoot" node to indicate the root of the graph.
294343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman    GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot");
295343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman    const SDNode *N = DAG->getRoot().getNode();
296343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman    if (N && N->getNodeId() != -1)
297343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman      GW.emitEdge(0, -1, &SUnits[N->getNodeId()], -1,
298343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman                  "color=blue,style=dashed");
299343f0c046702831a4a6aec951b6a297a23241a55Dan Gohman  }
3003e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman}
301