Clean up RemoveDeadNodes significantly, by eliminating the need for a temporary
authorChris Lattner <sabre@nondot.org>
Tue, 8 Nov 2005 18:52:27 +0000 (18:52 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 8 Nov 2005 18:52:27 +0000 (18:52 +0000)
set and eliminating the need to iterate whenever something is removed (which
can be really slow in some cases).  Thx to Jim for pointing out something silly
I was getting stuck on. :)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24241 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/SelectionDAG.cpp

index 7d3cddb656839b3ffa975c41acf81d2a1ab80869..c1cd169b24884ffcfebe149cf14193de22388072 100644 (file)
@@ -167,41 +167,47 @@ const TargetMachine &SelectionDAG::getTarget() const {
 /// chain but no other uses and no side effect.  If a node is passed in as an
 /// argument, it is used as the seed for node deletion.
 void SelectionDAG::RemoveDeadNodes(SDNode *N) {
-  std::set<SDNode*> AllNodeSet(AllNodes.begin(), AllNodes.end());
-
   // Create a dummy node (which is not added to allnodes), that adds a reference
   // to the root node, preventing it from being deleted.
   HandleSDNode Dummy(getRoot());
 
+  bool MadeChange = false;
+  
   // If we have a hint to start from, use it.
-  if (N) DeleteNodeIfDead(N, &AllNodeSet);
+  if (N && N->use_empty()) {
+    DestroyDeadNode(N);
+    MadeChange = true;
+  }
 
- Restart:
-  unsigned NumNodes = AllNodeSet.size();
-  for (std::set<SDNode*>::iterator I = AllNodeSet.begin(), E = AllNodeSet.end();
-       I != E; ++I) {
+  for (unsigned i = 0, e = AllNodes.size(); i != e; ++i) {
     // Try to delete this node.
-    DeleteNodeIfDead(*I, &AllNodeSet);
-
-    // If we actually deleted any nodes, do not use invalid iterators in
-    // AllNodeSet.
-    if (AllNodeSet.size() != NumNodes)
-      goto Restart;
+    SDNode *N = AllNodes[i];
+    if (N->use_empty() && N->getOpcode() != 65535) {
+      DestroyDeadNode(N);
+      MadeChange = true;
+    }
   }
-
-  // Restore AllNodes.
-  if (AllNodes.size() != NumNodes)
-    AllNodes.assign(AllNodeSet.begin(), AllNodeSet.end());
-
+  
+  // Walk the nodes list, removing the nodes we've marked as dead.
+  if (MadeChange) {
+    for (unsigned i = 0, e = AllNodes.size(); i != e; ++i)
+      if (AllNodes[i]->use_empty()) {
+        delete AllNodes[i];
+        AllNodes[i] = AllNodes.back();
+        AllNodes.pop_back();
+        --i; --e;
+      }
+  }
+  
   // If the root changed (e.g. it was a dead load, update the root).
   setRoot(Dummy.getValue());
 }
 
-
-void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) {
-  if (!N->use_empty())
-    return;
-
+/// DestroyDeadNode - We know that N is dead.  Nuke it from the CSE maps for the
+/// graph.  If it is the last user of any of its operands, recursively process
+/// them the same way.
+/// 
+void SelectionDAG::DestroyDeadNode(SDNode *N) {
   // Okay, we really are going to delete this node.  First take this out of the
   // appropriate CSE map.
   RemoveNodeFromCSEMaps(N);
@@ -214,16 +220,12 @@ void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) {
     O->removeUser(N);
     
     // Now that we removed this operand, see if there are no uses of it left.
-    DeleteNodeIfDead(O, NodeSet);
+    if (O->use_empty())
+      DestroyDeadNode(O);
   }
-  
-  // Remove the node from the nodes set and delete it.
-  std::set<SDNode*> &AllNodeSet = *(std::set<SDNode*>*)NodeSet;
-  AllNodeSet.erase(N);
-  
-  // Now that the node is gone, check to see if any of the operands of this node
-  // are dead now.
-  delete N;  
+
+  // Mark the node as dead.
+  N->MorphNodeTo(65535);
 }
 
 void SelectionDAG::DeleteNode(SDNode *N) {