[llvm-commits] [llvm] r55389 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp SelectionDAG.cpp

Dan Gohman gohman at apple.com
Tue Aug 26 14:42:18 PDT 2008


Author: djg
Date: Tue Aug 26 16:42:18 2008
New Revision: 55389

URL: http://llvm.org/viewvc/llvm-project?rev=55389&view=rev
Log:
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.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=55389&r1=55388&r2=55389&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Aug 26 16:42:18 2008
@@ -270,45 +270,6 @@
          "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<SDNode*, 64> &Order) {
-
-  DenseMap<SDNode*, unsigned> Visited;
-  std::vector<SDNode*> 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 @@
   // 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<SDNode*, 64> Order;
-  ComputeTopDownOrdering(DAG, Order);
-  
-  for (unsigned i = 0, e = Order.size(); i != e; ++i)
-    HandleOp(SDValue(Order[i], 0));
+  std::vector<SDNode *> 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();

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=55389&r1=55388&r2=55389&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Aug 26 16:42:18 2008
@@ -4427,40 +4427,35 @@
 /// of the SDNodes* in assigned order by reference.
 unsigned SelectionDAG::AssignTopologicalOrder(std::vector<SDNode*> &TopOrder) {
   unsigned DAGSize = AllNodes.size();
-  std::vector<unsigned> InDegree(DAGSize);
   std::vector<SDNode*> 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<SDNode*>::iterator TI = TopOrder.begin(),TE = TopOrder.end();
-       TI != TE; ++TI)
-    (*TI)->setNodeId(Id++);
-
   return Id;
 }
 





More information about the llvm-commits mailing list