Dan pointed out checking whether a node is dead by comparing its opcode to ISD::DELET...
authorEvan Cheng <evan.cheng@apple.com>
Sat, 9 Jan 2010 00:21:08 +0000 (00:21 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Sat, 9 Jan 2010 00:21:08 +0000 (00:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93031 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index c87e4bf716a303797a8cc473cae2394fa8803932..edcd91e8dedab9354a773251cb0cd223210f4d65 100644 (file)
@@ -438,6 +438,25 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB,
   SDB->clear();
 }
 
+namespace {
+/// WorkListRemover - This class is a DAGUpdateListener that removes any deleted
+/// nodes from the worklist.
+class SDOPsWorkListRemover : public SelectionDAG::DAGUpdateListener {
+  SmallVector<SDNode*, 128> &Worklist;
+public:
+  SDOPsWorkListRemover(SmallVector<SDNode*, 128> &wl) : Worklist(wl) {}
+
+  virtual void NodeDeleted(SDNode *N, SDNode *E) {
+    Worklist.erase(std::remove(Worklist.begin(), Worklist.end(), N),
+                   Worklist.end());
+  }
+
+  virtual void NodeUpdated(SDNode *N) {
+    // Ignore updates.
+  }
+};
+}
+
 /// ShrinkDemandedOps - A late transformation pass that shrink expressions
 /// using TargetLowering::TargetLoweringOpt::ShrinkDemandedOp. It converts
 /// x+y to (VT)((SmallVT)x+(SmallVT)y) if the casts are free.
@@ -459,8 +478,7 @@ void SelectionDAGISel::ShrinkDemandedOps() {
     SDNode *N = Worklist.pop_back_val();
 
     if (N->use_empty() && N != CurDAG->getRoot().getNode()) {
-      if (N->getOpcode() != ISD::DELETED_NODE)
-        CurDAG->DeleteNode(N);
+      CurDAG->DeleteNode(N);
       continue;
     }
 
@@ -485,7 +503,9 @@ void SelectionDAGISel::ShrinkDemandedOps() {
               errs() << '\n');
 
         Worklist.push_back(TLO.New.getNode());
-        CurDAG->ReplaceAllUsesOfValueWith(TLO.Old, TLO.New);
+
+        SDOPsWorkListRemover DeadNodes(Worklist);
+        CurDAG->ReplaceAllUsesOfValueWith(TLO.Old, TLO.New, &DeadNodes);
 
         if (TLO.Old.getNode()->use_empty()) {
           for (unsigned i = 0, e = TLO.Old.getNode()->getNumOperands();
@@ -493,15 +513,13 @@ void SelectionDAGISel::ShrinkDemandedOps() {
             SDNode *OpNode = TLO.Old.getNode()->getOperand(i).getNode(); 
             if (OpNode->hasOneUse()) {
               Worklist.erase(std::remove(Worklist.begin(), Worklist.end(),
-                                         OpNode),
-                             Worklist.end());
-              Worklist.push_back(TLO.Old.getNode()->getOperand(i).getNode());
+                                         OpNode), Worklist.end());
+              Worklist.push_back(OpNode);
             }
           }
 
           Worklist.erase(std::remove(Worklist.begin(), Worklist.end(),
-                                     TLO.Old.getNode()),
-                         Worklist.end());
+                                     TLO.Old.getNode()), Worklist.end());
           CurDAG->DeleteNode(TLO.Old.getNode());
         }
       }