Skip to content

Commit 9e0da50

Browse files
committed
fixup! Do not use getTopologicallySortedNodes in AssignTopologicalOrder
1 parent a61f8d7 commit 9e0da50

File tree

1 file changed

+81
-11
lines changed

1 file changed

+81
-11
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 81 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12610,17 +12610,87 @@ void SelectionDAG::ReplaceAllUsesOfValuesWith(const SDValue *From,
1261012610
/// based on their topological order. It returns the maximum id and a vector
1261112611
/// of the SDNodes* in assigned order by reference.
1261212612
unsigned SelectionDAG::AssignTopologicalOrder() {
12613-
SmallVector<const SDNode *> SortedNodes(AllNodes.size());
12614-
getTopologicallyOrderedNodes(SortedNodes);
12615-
12616-
for (auto [Idx, ConstN] : enumerate(SortedNodes)) {
12617-
auto *N = const_cast<SDNode *>(ConstN);
12618-
N->setNodeId(Idx);
12619-
if (N->getIterator() != std::prev(allnodes_end()))
12620-
AllNodes.push_back(AllNodes.remove(N));
12621-
}
12622-
12623-
return SortedNodes.size();
12613+
unsigned DAGSize = 0;
12614+
12615+
// SortedPos tracks the progress of the algorithm. Nodes before it are
12616+
// sorted, nodes after it are unsorted. When the algorithm completes
12617+
// it is at the end of the list.
12618+
allnodes_iterator SortedPos = allnodes_begin();
12619+
12620+
// Visit all the nodes. Move nodes with no operands to the front of
12621+
// the list immediately. Annotate nodes that do have operands with their
12622+
// operand count. Before we do this, the Node Id fields of the nodes
12623+
// may contain arbitrary values. After, the Node Id fields for nodes
12624+
// before SortedPos will contain the topological sort index, and the
12625+
// Node Id fields for nodes At SortedPos and after will contain the
12626+
// count of outstanding operands.
12627+
for (SDNode &N : llvm::make_early_inc_range(allnodes())) {
12628+
checkForCycles(&N, this);
12629+
unsigned Degree = N.getNumOperands();
12630+
if (Degree == 0) {
12631+
// A node with no uses, add it to the result array immediately.
12632+
N.setNodeId(DAGSize++);
12633+
allnodes_iterator Q(&N);
12634+
if (Q != SortedPos)
12635+
SortedPos = AllNodes.insert(SortedPos, AllNodes.remove(Q));
12636+
assert(SortedPos != AllNodes.end() && "Overran node list");
12637+
++SortedPos;
12638+
} else {
12639+
// Temporarily use the Node Id as scratch space for the degree count.
12640+
N.setNodeId(Degree);
12641+
}
12642+
}
12643+
12644+
// Visit all the nodes. As we iterate, move nodes into sorted order,
12645+
// such that by the time the end is reached all nodes will be sorted.
12646+
for (SDNode &Node : allnodes()) {
12647+
SDNode *N = &Node;
12648+
checkForCycles(N, this);
12649+
// N is in sorted position, so all its uses have one less operand
12650+
// that needs to be sorted.
12651+
for (SDNode *P : N->users()) {
12652+
unsigned Degree = P->getNodeId();
12653+
assert(Degree != 0 && "Invalid node degree");
12654+
--Degree;
12655+
if (Degree == 0) {
12656+
// All of P's operands are sorted, so P may sorted now.
12657+
P->setNodeId(DAGSize++);
12658+
if (P->getIterator() != SortedPos)
12659+
SortedPos = AllNodes.insert(SortedPos, AllNodes.remove(P));
12660+
assert(SortedPos != AllNodes.end() && "Overran node list");
12661+
++SortedPos;
12662+
} else {
12663+
// Update P's outstanding operand count.
12664+
P->setNodeId(Degree);
12665+
}
12666+
}
12667+
if (Node.getIterator() == SortedPos) {
12668+
#ifndef NDEBUG
12669+
allnodes_iterator I(N);
12670+
SDNode *S = &*++I;
12671+
dbgs() << "Overran sorted position:\n";
12672+
S->dumprFull(this); dbgs() << "\n";
12673+
dbgs() << "Checking if this is due to cycles\n";
12674+
checkForCycles(this, true);
12675+
#endif
12676+
llvm_unreachable(nullptr);
12677+
}
12678+
}
12679+
12680+
assert(SortedPos == AllNodes.end() &&
12681+
"Topological sort incomplete!");
12682+
assert(AllNodes.front().getOpcode() == ISD::EntryToken &&
12683+
"First node in topological sort is not the entry token!");
12684+
assert(AllNodes.front().getNodeId() == 0 &&
12685+
"First node in topological sort has non-zero id!");
12686+
assert(AllNodes.front().getNumOperands() == 0 &&
12687+
"First node in topological sort has operands!");
12688+
assert(AllNodes.back().getNodeId() == (int)DAGSize-1 &&
12689+
"Last node in topologic sort has unexpected id!");
12690+
assert(AllNodes.back().use_empty() &&
12691+
"Last node in topologic sort has users!");
12692+
assert(DAGSize == allnodes_size() && "Node count mismatch!");
12693+
return DAGSize;
1262412694
}
1262512695

1262612696
void SelectionDAG::getTopologicallyOrderedNodes(

0 commit comments

Comments
 (0)