diff options
author | Chris Lattner <sabre@nondot.org> | 2004-03-14 03:59:22 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-03-14 03:59:22 +0000 |
commit | d078812f966dc16b1a05994e68d2eb7554f4eac6 (patch) | |
tree | 0f9f6e8a9f445ce508711db12983c6468d5766f4 /llvm/lib/Transforms/Scalar/LoopSimplify.cpp | |
parent | 9ece94b02bf9d20cfcf542b35b88afdab046e741 (diff) | |
download | bcm5719-llvm-d078812f966dc16b1a05994e68d2eb7554f4eac6.tar.gz bcm5719-llvm-d078812f966dc16b1a05994e68d2eb7554f4eac6.zip |
If a block is dead, dominators will not be calculated for it. Because of this
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.
llvm-svn: 12380
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LoopSimplify.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopSimplify.cpp | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopSimplify.cpp b/llvm/lib/Transforms/Scalar/LoopSimplify.cpp index 08bbc093c05..6fbf261835a 100644 --- a/llvm/lib/Transforms/Scalar/LoopSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/LoopSimplify.cpp @@ -33,10 +33,11 @@ //===----------------------------------------------------------------------===// #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); |