From 3200d92947cd64f82ca748d65d1e58c3d45f440f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 26 Aug 2008 21:42:18 +0000 Subject: [PATCH] Optimize SelectionDAG's topological sort to use one pass instead of two, and to not need a scratch std::vector. Also, use the SelectionDAG's topological sort in LegalizeDAG instead of having a separate implementation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55389 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 49 +++-------------------- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 19 ++++----- 2 files changed, 12 insertions(+), 56 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 96eafbe5028..e5a1f57ef51 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -270,45 +270,6 @@ SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag) "Too many value types for ValueTypeActions to hold!"); } -/// ComputeTopDownOrdering - Compute a top-down ordering of the dag, where Order -/// contains all of a nodes operands before it contains the node. -static void ComputeTopDownOrdering(SelectionDAG &DAG, - SmallVector &Order) { - - DenseMap Visited; - std::vector Worklist; - Worklist.reserve(128); - - // Compute ordering from all of the leaves in the graphs, those (like the - // entry node) that have no operands. - for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), - E = DAG.allnodes_end(); I != E; ++I) { - if (I->getNumOperands() == 0) { - Visited[I] = 0 - 1U; - Worklist.push_back(I); - } - } - - while (!Worklist.empty()) { - SDNode *N = Worklist.back(); - Worklist.pop_back(); - - if (++Visited[N] != N->getNumOperands()) - continue; // Haven't visited all operands yet - - Order.push_back(N); - - // Now that we have N in, add anything that uses it if all of their operands - // are now done. - Worklist.insert(Worklist.end(), N->use_begin(), N->use_end()); - } - - assert(Order.size() == Visited.size() && - Order.size() == DAG.allnodes_size() && - "Error: DAG is cyclic!"); -} - - void SelectionDAGLegalize::LegalizeDAG() { LastCALLSEQ_END = DAG.getEntryNode(); IsLegalizingCall = false; @@ -319,11 +280,11 @@ void SelectionDAGLegalize::LegalizeDAG() { // practice however, this causes us to run out of stack space on large basic // blocks. To avoid this problem, compute an ordering of the nodes where each // node is only legalized after all of its operands are legalized. - SmallVector Order; - ComputeTopDownOrdering(DAG, Order); - - for (unsigned i = 0, e = Order.size(); i != e; ++i) - HandleOp(SDValue(Order[i], 0)); + std::vector TopOrder; + unsigned N = DAG.AssignTopologicalOrder(TopOrder); + for (unsigned i = N; i != 0; --i) + HandleOp(SDValue(TopOrder[i-1], 0)); + TopOrder.clear(); // Finally, it's possible the root changed. Get the new root. SDValue OldRoot = DAG.getRoot(); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 71a60fbff7e..640fc97dcf7 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4427,40 +4427,35 @@ void SelectionDAG::ReplaceAllUsesOfValuesWith(const SDValue *From, /// of the SDNodes* in assigned order by reference. unsigned SelectionDAG::AssignTopologicalOrder(std::vector &TopOrder) { unsigned DAGSize = AllNodes.size(); - std::vector InDegree(DAGSize); std::vector Sources; - // Use a two pass approach to avoid using a std::map which is slow. - unsigned Id = 0; for (allnodes_iterator I = allnodes_begin(),E = allnodes_end(); I != E; ++I){ SDNode *N = I; - N->setNodeId(Id++); unsigned Degree = N->use_size(); - InDegree[N->getNodeId()] = Degree; + // Temporarily use the Node Id as scratch space for the degree count. + N->setNodeId(Degree); if (Degree == 0) Sources.push_back(N); } TopOrder.clear(); TopOrder.reserve(DAGSize); + int Id = 0; while (!Sources.empty()) { SDNode *N = Sources.back(); Sources.pop_back(); TopOrder.push_back(N); + N->setNodeId(Id++); for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) { SDNode *P = I->getVal(); - unsigned Degree = --InDegree[P->getNodeId()]; + unsigned Degree = P->getNodeId(); + --Degree; + P->setNodeId(Degree); if (Degree == 0) Sources.push_back(P); } } - // Second pass, assign the actual topological order as node ids. - Id = 0; - for (std::vector::iterator TI = TopOrder.begin(),TE = TopOrder.end(); - TI != TE; ++TI) - (*TI)->setNodeId(Id++); - return Id; }