If a block is dead, dominators will not be calculated for it. Because of this
authorChris Lattner <sabre@nondot.org>
Sun, 14 Mar 2004 03:59:22 +0000 (03:59 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 14 Mar 2004 03:59:22 +0000 (03:59 +0000)
loop information won't see it, and we could have unreachable blocks pointing to
the non-header node of blocks in a natural loop.  This isn't tidy, so have the
loopsimplify pass clean it up.

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

lib/Transforms/Utils/LoopSimplify.cpp

index 08bbc093c0531efd1b2d125520c003ae494cda27..6fbf261835a9e00e5ae41616b97d5e0a95518219 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/Scalar.h"
-#include "llvm/Function.h"
+#include "llvm/Constant.h"
 #include "llvm/iTerminators.h"
 #include "llvm/iPHINode.h"
-#include "llvm/Constant.h"
+#include "llvm/Function.h"
+#include "llvm/Type.h"
 #include "llvm/Analysis/Dominators.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Support/CFG.h"
@@ -105,6 +106,36 @@ bool LoopSimplify::runOnFunction(Function &F) {
 bool LoopSimplify::ProcessLoop(Loop *L) {
   bool Changed = false;
 
+  // Check to see that no blocks (other than the header) in the loop have
+  // predecessors that are not in the loop.  This is not valid for natural
+  // loops, but can occur if the blocks are unreachable.  Since they are
+  // unreachable we can just shamelessly destroy their terminators to make them
+  // not branch into the loop!
+  assert(L->getBlocks()[0] == L->getHeader() &&
+         "Header isn't first block in loop?");
+  for (unsigned i = 1, e = L->getBlocks().size(); i != e; ++i) {
+    BasicBlock *LoopBB = L->getBlocks()[i];
+  Retry:
+    for (pred_iterator PI = pred_begin(LoopBB), E = pred_end(LoopBB);
+         PI != E; ++PI)
+      if (!L->contains(*PI)) {
+        // This predecessor is not in the loop.  Kill its terminator!
+        BasicBlock *DeadBlock = *PI;
+        for (succ_iterator SI = succ_begin(DeadBlock), E = succ_end(DeadBlock);
+             SI != E; ++SI)
+          (*SI)->removePredecessor(DeadBlock);  // Remove PHI node entries
+
+        // Delete the dead terminator.
+        DeadBlock->getInstList().pop_back();
+
+        Value *RetVal = 0;
+        if (LoopBB->getParent()->getReturnType() != Type::VoidTy)
+          RetVal = Constant::getNullValue(LoopBB->getParent()->getReturnType());
+        new ReturnInst(RetVal, DeadBlock);
+        goto Retry;  // We just invalidated the pred_iterator.  Retry.
+      }
+  }
+
   // Does the loop already have a preheader?  If so, don't modify the loop...
   if (L->getLoopPreheader() == 0) {
     InsertPreheaderForLoop(L);