diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 3f20c036a3f..1e099a2c150 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -1329,8 +1329,12 @@ public: /// std::string getOperationName(const SelectionDAG *G = 0) const; static const char* getIndexedModeName(ISD::MemIndexedMode AM); + void print_types(raw_ostream &OS, const SelectionDAG *G) const; + void print_details(raw_ostream &OS, const SelectionDAG *G) const; void print(raw_ostream &OS, const SelectionDAG *G = 0) const; + void printr(raw_ostream &OS, const SelectionDAG *G = 0) const; void dump() const; + void dumpr() const; void dump(const SelectionDAG *G) const; static bool classof(const SDNode *) { return true; } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index e3ff5a75257..ebc67dd0b9d 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5638,7 +5638,7 @@ void SDNode::dump(const SelectionDAG *G) const { errs().flush(); } -void SDNode::print(raw_ostream &OS, const SelectionDAG *G) const { +void SDNode::print_types(raw_ostream &OS, const SelectionDAG *G) const { OS << (void*)this << ": "; for (unsigned i = 0, e = getNumValues(); i != e; ++i) { @@ -5649,15 +5649,9 @@ void SDNode::print(raw_ostream &OS, const SelectionDAG *G) const { OS << getValueType(i).getMVTString(); } OS << " = " << getOperationName(G); +} - OS << " "; - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - if (i) OS << ", "; - OS << (void*)getOperand(i).getNode(); - if (unsigned RN = getOperand(i).getResNo()) - OS << ":" << RN; - } - +void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const { if (!isTargetOpcode() && getOpcode() == ISD::VECTOR_SHUFFLE) { SDNode *Mask = getOperand(2).getNode(); OS << "<"; @@ -5798,6 +5792,18 @@ void SDNode::print(raw_ostream &OS, const SelectionDAG *G) const { } } +void SDNode::print(raw_ostream &OS, const SelectionDAG *G) const { + print_types(OS, G); + OS << " "; + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + if (i) OS << ", "; + OS << (void*)getOperand(i).getNode(); + if (unsigned RN = getOperand(i).getResNo()) + OS << ":" << RN; + } + print_details(OS, G); +} + static void DumpNodes(const SDNode *N, unsigned indent, const SelectionDAG *G) { for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) if (N->getOperand(i).getNode()->hasOneUse()) @@ -5826,6 +5832,47 @@ void SelectionDAG::dump() const { cerr << "\n\n"; } +void SDNode::printr(raw_ostream &OS, const SelectionDAG *G) const { + print_types(OS, G); + print_details(OS, G); +} + +typedef SmallPtrSet VisitedSDNodeSet; +static void DumpNodesr(raw_ostream &OS, const SDNode *N, unsigned indent, const SelectionDAG *G, VisitedSDNodeSet &once) { + if (!once.insert(N)) // If we've been here before, return now. + return; + // Dump the current SDNode, but don't end the line yet. + OS << std::string(indent, ' '); + N->printr(OS, G); + // Having printed this SDNode, walk the children: + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + const SDNode *child = N->getOperand(i).getNode(); + if (i) OS << ","; + OS << " "; + if (child->getNumOperands() == 0) { + // This child has no grandchildren; print it inline right here. + child->printr(OS, G); + once.insert(child); + } else { // Just the address. FIXME: also print the child's opcode + OS << (void*)child; + if (unsigned RN = N->getOperand(i).getResNo()) + OS << ":" << RN; + } + } + OS << "\n"; + // Dump children that have grandchildren on their own line(s). + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + const SDNode *child = N->getOperand(i).getNode(); + DumpNodesr(OS, child, indent+2, G, once); + } +} + +void SDNode::dumpr() const { + VisitedSDNodeSet once; + DumpNodesr(errs(), this, 0, 0, once); + errs().flush(); +} + const Type *ConstantPoolSDNode::getType() const { if (isMachineConstantPoolEntry()) return Val.MachineCPVal->getType();