Fix a bug in the unreachable block elim pass. Dropping all references on a
authorChris Lattner <sabre@nondot.org>
Tue, 6 Jul 2004 06:36:11 +0000 (06:36 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 6 Jul 2004 06:36:11 +0000 (06:36 +0000)
basic block clear()'s all of the operands lists, including phis.  This
caused removePredecessor to get confused later.  Because of this, we just
nuke (without prejudice) PHI nodes in unreachable blocks.

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

lib/CodeGen/UnreachableBlockElim.cpp

index bcc124538d31c37b0ebc7d782158650ece079f55..1b59ac4a666eeac7bc94222cbecd47a3215b9862 100644 (file)
@@ -21,6 +21,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/iPHINode.h"
+#include "llvm/Constant.h"
 #include "llvm/Function.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CFG.h"
@@ -52,10 +54,15 @@ bool UnreachableBlockElim::runOnFunction(Function &F) {
   std::vector<BasicBlock*> DeadBlocks;
   for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
     if (!Reachable.count(I)) {
-      DeadBlocks.push_back(I);
-      for (succ_iterator SI = succ_begin(&*I), E = succ_end(&*I); SI != E; ++SI)
-        (*SI)->removePredecessor(I);
-      I->dropAllReferences();
+      BasicBlock *BB = I;
+      DeadBlocks.push_back(BB);
+      while (PHINode *PN = dyn_cast<PHINode>(BB->begin())) {
+        PN->replaceAllUsesWith(Constant::getNullValue(PN->getType()));
+        BB->getInstList().pop_front();
+      }
+      for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI)
+        (*SI)->removePredecessor(BB);
+      BB->dropAllReferences();
     }
 
   if (DeadBlocks.empty()) return false;