mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-11 13:46:13 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12380 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
59c3569b14
commit
2ef703ec42
@ -33,10 +33,11 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/Transforms/Scalar.h"
|
#include "llvm/Transforms/Scalar.h"
|
||||||
#include "llvm/Function.h"
|
#include "llvm/Constant.h"
|
||||||
#include "llvm/iTerminators.h"
|
#include "llvm/iTerminators.h"
|
||||||
#include "llvm/iPHINode.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/Dominators.h"
|
||||||
#include "llvm/Analysis/LoopInfo.h"
|
#include "llvm/Analysis/LoopInfo.h"
|
||||||
#include "llvm/Support/CFG.h"
|
#include "llvm/Support/CFG.h"
|
||||||
@ -105,6 +106,36 @@ bool LoopSimplify::runOnFunction(Function &F) {
|
|||||||
bool LoopSimplify::ProcessLoop(Loop *L) {
|
bool LoopSimplify::ProcessLoop(Loop *L) {
|
||||||
bool Changed = false;
|
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...
|
// Does the loop already have a preheader? If so, don't modify the loop...
|
||||||
if (L->getLoopPreheader() == 0) {
|
if (L->getLoopPreheader() == 0) {
|
||||||
InsertPreheaderForLoop(L);
|
InsertPreheaderForLoop(L);
|
||||||
|
Loading…
Reference in New Issue
Block a user