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