diff --git a/lib/Transforms/Utils/LoopSimplify.cpp b/lib/Transforms/Utils/LoopSimplify.cpp index dcad43fc2bf..7289f2261a6 100644 --- a/lib/Transforms/Utils/LoopSimplify.cpp +++ b/lib/Transforms/Utils/LoopSimplify.cpp @@ -105,6 +105,58 @@ bool LoopSimplify::runOnFunction(Function &F) { LI = &getAnalysis(); AA = getAnalysisToUpdate(); + // Check to see that no blocks (other than the header) in loops have + // predecessors that are not in loops. 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! + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { + // This case can only occur for unreachable blocks. Blocks that are + // unreachable can't be in loops, so filter those blocks out. + if (LI->getLoopFor(BB)) continue; + + bool BlockUnreachable = false; + TerminatorInst *TI = BB->getTerminator(); + + // Check to see if any successors of this block are non-loop-header loops + // that are not the header. + for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) { + // If this successor is not in a loop, BB is clearly ok. + Loop *L = LI->getLoopFor(TI->getSuccessor(i)); + if (!L) continue; + + // If the succ is the loop header, and if L is a top-level loop, then this + // is an entrance into a loop through the header, which is also ok. + if (L->getHeader() == TI->getSuccessor(i) && L->getParentLoop() == 0) + continue; + + // Otherwise, this is an entrance into a loop from some place invalid. + // Either the loop structure is invalid and this is not a natural loop (in + // which case the compiler is buggy somewhere else) or BB is unreachable. + BlockUnreachable = true; + break; + } + + // If this block is ok, check the next one. + if (!BlockUnreachable) continue; + + // Otherwise, this block is dead. To clean up the CFG and to allow later + // loop transformations to ignore this case, we delete the edges into the + // loop by replacing the terminator. + + // Remove PHI entries from the successors. + for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) + TI->getSuccessor(i)->removePredecessor(BB); + + // Add a new unreachable instruction. + new UnreachableInst(TI); + + // Delete the dead terminator. + if (AA) AA->deleteValue(&BB->back()); + BB->getInstList().pop_back(); + Changed |= true; + } + for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I) Changed |= ProcessLoop(*I); @@ -121,38 +173,10 @@ bool LoopSimplify::ProcessLoop(Loop *L) { for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I) Changed |= ProcessLoop(*I); - // 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. - if (AA) AA->deleteValue(&DeadBlock->back()); - 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... + // Does the loop already have a preheader? If so, don't insert one. if (L->getLoopPreheader() == 0) { InsertPreheaderForLoop(L); NumInserted++;