summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/LoopSimplify.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-03-14 03:59:22 +0000
committerChris Lattner <sabre@nondot.org>2004-03-14 03:59:22 +0000
commitd078812f966dc16b1a05994e68d2eb7554f4eac6 (patch)
tree0f9f6e8a9f445ce508711db12983c6468d5766f4 /llvm/lib/Transforms/Scalar/LoopSimplify.cpp
parent9ece94b02bf9d20cfcf542b35b88afdab046e741 (diff)
downloadbcm5719-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.cpp35
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);
OpenPOWER on IntegriCloud