Skip to content

Commit c2c2e4e

Browse files
authored
[SelectionDAG] Add support to dump DAGs with sorted nodes (#161097)
An alternative approach to #149732 , which sorts the DAG before dumping it. That approach runs a risk of altering the codegen result as we don't know if any of the downstream DAG users relies on the node ID, which was updated as part of the sorting. The new method proposed by this PR does not update the node ID or any of the DAG's internal states: the newly added `SelectionDAG::getTopologicallyOrderedNodes` is a const member function that returns a list of all nodes in their topological order.
1 parent c488dca commit c2c2e4e

File tree

4 files changed

+74
-13
lines changed

4 files changed

+74
-13
lines changed

llvm/include/llvm/CodeGen/SelectionDAG.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1959,6 +1959,10 @@ class SelectionDAG {
19591959
LLVM_ABI SDValue makeEquivalentMemoryOrdering(LoadSDNode *OldLoad,
19601960
SDValue NewMemOp);
19611961

1962+
/// Get all the nodes in their topological order without modifying any states.
1963+
LLVM_ABI void getTopologicallyOrderedNodes(
1964+
SmallVectorImpl<const SDNode *> &SortedNodes) const;
1965+
19621966
/// Topological-sort the AllNodes list and a
19631967
/// assign a unique node id for each node in the DAG based on their
19641968
/// topological order. Returns the number of nodes.
@@ -2009,7 +2013,9 @@ class SelectionDAG {
20092013
/// function mirrors \c llvm::salvageDebugInfo.
20102014
LLVM_ABI void salvageDebugInfo(SDNode &N);
20112015

2012-
LLVM_ABI void dump() const;
2016+
/// Dump the textual format of this DAG. Print nodes in sorted orders if \p
2017+
/// Sorted is true.
2018+
LLVM_ABI void dump(bool Sorted = false) const;
20132019

20142020
/// In most cases this function returns the ABI alignment for a given type,
20152021
/// except for illegal vector types where the alignment exceeds that of the

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12698,6 +12698,45 @@ unsigned SelectionDAG::AssignTopologicalOrder() {
1269812698
return DAGSize;
1269912699
}
1270012700

12701+
void SelectionDAG::getTopologicallyOrderedNodes(
12702+
SmallVectorImpl<const SDNode *> &SortedNodes) const {
12703+
SortedNodes.clear();
12704+
// Node -> remaining number of outstanding operands.
12705+
DenseMap<const SDNode *, unsigned> RemainingOperands;
12706+
12707+
// Put nodes without any operands into SortedNodes first.
12708+
for (const SDNode &N : allnodes()) {
12709+
checkForCycles(&N, this);
12710+
unsigned NumOperands = N.getNumOperands();
12711+
if (NumOperands == 0)
12712+
SortedNodes.push_back(&N);
12713+
else
12714+
// Record their total number of outstanding operands.
12715+
RemainingOperands[&N] = NumOperands;
12716+
}
12717+
12718+
// A node is pushed into SortedNodes when all of its operands (predecessors in
12719+
// the graph) are also in SortedNodes.
12720+
for (unsigned i = 0U; i < SortedNodes.size(); ++i) {
12721+
const SDNode *N = SortedNodes[i];
12722+
for (const SDNode *U : N->users()) {
12723+
unsigned &NumRemOperands = RemainingOperands[U];
12724+
assert(NumRemOperands && "Invalid number of remaining operands");
12725+
--NumRemOperands;
12726+
if (!NumRemOperands)
12727+
SortedNodes.push_back(U);
12728+
}
12729+
}
12730+
12731+
assert(SortedNodes.size() == AllNodes.size() && "Node count mismatch");
12732+
assert(SortedNodes.front()->getOpcode() == ISD::EntryToken &&
12733+
"First node in topological sort is not the entry token");
12734+
assert(SortedNodes.front()->getNumOperands() == 0 &&
12735+
"First node in topological sort has operands");
12736+
assert(SortedNodes.back()->use_empty() &&
12737+
"Last node in topologic sort has users");
12738+
}
12739+
1270112740
/// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means the
1270212741
/// value is produced by SD.
1270312742
void SelectionDAG::AddDbgValue(SDDbgValue *DB, bool isParameter) {

llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,13 +1061,24 @@ static void DumpNodes(const SDNode *N, unsigned indent, const SelectionDAG *G) {
10611061
N->dump(G);
10621062
}
10631063

1064-
LLVM_DUMP_METHOD void SelectionDAG::dump() const {
1064+
LLVM_DUMP_METHOD void SelectionDAG::dump(bool Sorted) const {
10651065
dbgs() << "SelectionDAG has " << AllNodes.size() << " nodes:\n";
10661066

1067-
for (const SDNode &N : allnodes()) {
1067+
auto dumpEachNode = [this](const SDNode &N) {
10681068
if (!N.hasOneUse() && &N != getRoot().getNode() &&
10691069
(!shouldPrintInline(N, this) || N.use_empty()))
10701070
DumpNodes(&N, 2, this);
1071+
};
1072+
1073+
if (Sorted) {
1074+
SmallVector<const SDNode *> SortedNodes;
1075+
SortedNodes.reserve(AllNodes.size());
1076+
getTopologicallyOrderedNodes(SortedNodes);
1077+
for (const SDNode *N : SortedNodes)
1078+
dumpEachNode(*N);
1079+
} else {
1080+
for (const SDNode &N : allnodes())
1081+
dumpEachNode(N);
10711082
}
10721083

10731084
if (getRoot().getNode()) DumpNodes(getRoot().getNode(), 2, this);

llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ UseMBPI("use-mbpi",
144144
cl::init(true), cl::Hidden);
145145

146146
#ifndef NDEBUG
147+
static cl::opt<bool>
148+
DumpSortedDAG("dump-sorted-dags", cl::Hidden,
149+
cl::desc("Print DAGs with sorted nodes in debug dump"),
150+
cl::init(false));
151+
147152
static cl::opt<std::string>
148153
FilterDAGBasicBlockName("filter-view-dags", cl::Hidden,
149154
cl::desc("Only display the basic block whose name "
@@ -932,7 +937,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
932937
ISEL_DUMP(dbgs() << "\nInitial selection DAG: "
933938
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
934939
<< "'\n";
935-
CurDAG->dump());
940+
CurDAG->dump(DumpSortedDAG));
936941

937942
#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
938943
if (TTI->hasBranchDivergence())
@@ -952,7 +957,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
952957
ISEL_DUMP(dbgs() << "\nOptimized lowered selection DAG: "
953958
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
954959
<< "'\n";
955-
CurDAG->dump());
960+
CurDAG->dump(DumpSortedDAG));
956961

957962
#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
958963
if (TTI->hasBranchDivergence())
@@ -974,7 +979,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
974979
ISEL_DUMP(dbgs() << "\nType-legalized selection DAG: "
975980
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
976981
<< "'\n";
977-
CurDAG->dump());
982+
CurDAG->dump(DumpSortedDAG));
978983

979984
#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
980985
if (TTI->hasBranchDivergence())
@@ -998,7 +1003,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
9981003
ISEL_DUMP(dbgs() << "\nOptimized type-legalized selection DAG: "
9991004
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
10001005
<< "'\n";
1001-
CurDAG->dump());
1006+
CurDAG->dump(DumpSortedDAG));
10021007

10031008
#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
10041009
if (TTI->hasBranchDivergence())
@@ -1016,7 +1021,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
10161021
ISEL_DUMP(dbgs() << "\nVector-legalized selection DAG: "
10171022
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
10181023
<< "'\n";
1019-
CurDAG->dump());
1024+
CurDAG->dump(DumpSortedDAG));
10201025

10211026
#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
10221027
if (TTI->hasBranchDivergence())
@@ -1032,7 +1037,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
10321037
ISEL_DUMP(dbgs() << "\nVector/type-legalized selection DAG: "
10331038
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
10341039
<< "'\n";
1035-
CurDAG->dump());
1040+
CurDAG->dump(DumpSortedDAG));
10361041

10371042
#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
10381043
if (TTI->hasBranchDivergence())
@@ -1052,7 +1057,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
10521057
ISEL_DUMP(dbgs() << "\nOptimized vector-legalized selection DAG: "
10531058
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
10541059
<< "'\n";
1055-
CurDAG->dump());
1060+
CurDAG->dump(DumpSortedDAG));
10561061

10571062
#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
10581063
if (TTI->hasBranchDivergence())
@@ -1072,7 +1077,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
10721077
ISEL_DUMP(dbgs() << "\nLegalized selection DAG: "
10731078
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
10741079
<< "'\n";
1075-
CurDAG->dump());
1080+
CurDAG->dump(DumpSortedDAG));
10761081

10771082
#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
10781083
if (TTI->hasBranchDivergence())
@@ -1092,7 +1097,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
10921097
ISEL_DUMP(dbgs() << "\nOptimized legalized selection DAG: "
10931098
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
10941099
<< "'\n";
1095-
CurDAG->dump());
1100+
CurDAG->dump(DumpSortedDAG));
10961101

10971102
#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
10981103
if (TTI->hasBranchDivergence())
@@ -1116,7 +1121,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
11161121
ISEL_DUMP(dbgs() << "\nSelected selection DAG: "
11171122
<< printMBBReference(*FuncInfo->MBB) << " '" << BlockName
11181123
<< "'\n";
1119-
CurDAG->dump());
1124+
CurDAG->dump(DumpSortedDAG));
11201125

11211126
if (ViewSchedDAGs && MatchFilterBB)
11221127
CurDAG->viewGraph("scheduler input for " + BlockName);

0 commit comments

Comments
 (0)