OSDN Git Service

Add RemoveDeadNode to remove a dead node and its (potentially) dead operands.
authorEvan Cheng <evan.cheng@apple.com>
Thu, 12 Oct 2006 20:34:05 +0000 (20:34 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Thu, 12 Oct 2006 20:34:05 +0000 (20:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30916 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAG.h
lib/CodeGen/SelectionDAG/SelectionDAG.cpp

index 168455e..ded775f 100644 (file)
@@ -129,7 +129,16 @@ public:
   /// RemoveDeadNodes - This method deletes all unreachable nodes in the
   /// SelectionDAG.
   void RemoveDeadNodes();
+
+  /// RemoveDeadNode - Remove the specified node from the system. If any of its
+  /// operands then becomes dead, remove them as well. The vector Deleted is
+  /// populated with nodes that are deleted.
+  void RemoveDeadNode(SDNode *N, std::vector<SDNode*> &Deleted);
   
+  /// DeleteNode - Remove the specified node from the system.  This node must
+  /// have no referrers.
+  void DeleteNode(SDNode *N);
+
   /// getVTList - Return an SDVTList that represents the list of values
   /// specified.
   SDVTList getVTList(MVT::ValueType VT);
@@ -407,10 +416,6 @@ public:
   void ReplaceAllUsesOfValueWith(SDOperand From, SDOperand To,
                                  std::vector<SDNode*> &Deleted);
 
-  /// DeleteNode - Remove the specified node from the system.  This node must
-  /// have no referrers.
-  void DeleteNode(SDNode *N);
-
   /// AssignNodeIds - Assign a unique node id for each node in the DAG based on
   /// their allnodes order. It returns the maximum id.
   unsigned AssignNodeIds();
index 8147324..d229375 100644 (file)
@@ -300,6 +300,39 @@ void SelectionDAG::RemoveDeadNodes() {
   setRoot(Dummy.getValue());
 }
 
+void SelectionDAG::RemoveDeadNode(SDNode *N, std::vector<SDNode*> &Deleted) {
+  SmallVector<SDNode*, 16> DeadNodes;
+  DeadNodes.push_back(N);
+
+  // Process the worklist, deleting the nodes and adding their uses to the
+  // worklist.
+  while (!DeadNodes.empty()) {
+    SDNode *N = DeadNodes.back();
+    DeadNodes.pop_back();
+    
+    // Take the node out of the appropriate CSE map.
+    RemoveNodeFromCSEMaps(N);
+
+    // Next, brutally remove the operand list.  This is safe to do, as there are
+    // no cycles in the graph.
+    for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) {
+      SDNode *Operand = I->Val;
+      Operand->removeUser(N);
+      
+      // Now that we removed this operand, see if there are no uses of it left.
+      if (Operand->use_empty())
+        DeadNodes.push_back(Operand);
+    }
+    delete[] N->OperandList;
+    N->OperandList = 0;
+    N->NumOperands = 0;
+    
+    // Finally, remove N itself.
+    Deleted.push_back(N);
+    AllNodes.erase(N);
+  }
+}
+
 void SelectionDAG::DeleteNode(SDNode *N) {
   assert(N->use_empty() && "Cannot delete a node that is not dead!");