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