aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2016-05-03 17:50:02 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2016-05-03 17:50:02 +0000
commit905fc27ebf9ec5a262dc320bb66e68f17d597248 (patch)
treed9ef19b195df25f735bc90385bee9b428f8c85e5 /llvm/lib/Transforms/Scalar/LoopDeletion.cpp
parent013a4ac4aa5da577fff807c44846eb6cfd6d32f4 (diff)
downloadllvm-905fc27ebf9ec5a262dc320bb66e68f17d597248.zip
llvm-905fc27ebf9ec5a262dc320bb66e68f17d597248.tar.gz
llvm-905fc27ebf9ec5a262dc320bb66e68f17d597248.tar.bz2
[LoopDeletion] Clear SCEV loop dispositions
`Loop::makeLoopInvariant` can hoist instructions out of loops, so loop dispositions for the loop it operated on may need to be cleared. We can be smarter here (especially around how `forgetLoopDispositions` is implemented), but let's be correct first. Fixes PR27570. llvm-svn: 268406
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LoopDeletion.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/LoopDeletion.cpp38
1 files changed, 27 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopDeletion.cpp b/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
index 786cd72..f888ad9 100644
--- a/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
@@ -44,10 +44,10 @@ namespace {
}
private:
- bool isLoopDead(Loop *L, SmallVectorImpl<BasicBlock *> &exitingBlocks,
- SmallVectorImpl<BasicBlock *> &exitBlocks,
- bool &Changed, BasicBlock *Preheader);
-
+ bool isLoopDead(Loop *L, ScalarEvolution &SE,
+ SmallVectorImpl<BasicBlock *> &exitingBlocks,
+ SmallVectorImpl<BasicBlock *> &exitBlocks, bool &Changed,
+ BasicBlock *Preheader);
};
}
@@ -65,7 +65,7 @@ Pass *llvm::createLoopDeletionPass() {
/// isLoopDead - Determined if a loop is dead. This assumes that we've already
/// checked for unique exit and exiting blocks, and that the code is in LCSSA
/// form.
-bool LoopDeletion::isLoopDead(Loop *L,
+bool LoopDeletion::isLoopDead(Loop *L, ScalarEvolution &SE,
SmallVectorImpl<BasicBlock *> &exitingBlocks,
SmallVectorImpl<BasicBlock *> &exitBlocks,
bool &Changed, BasicBlock *Preheader) {
@@ -77,6 +77,8 @@ bool LoopDeletion::isLoopDead(Loop *L,
// sufficient to guarantee that no loop-variant values are used outside
// of the loop.
BasicBlock::iterator BI = exitBlock->begin();
+ bool AllEntriesInvariant = true;
+ bool AllOutgoingValuesSame = true;
while (PHINode *P = dyn_cast<PHINode>(BI)) {
Value *incoming = P->getIncomingValueForBlock(exitingBlocks[0]);
@@ -85,17 +87,30 @@ bool LoopDeletion::isLoopDead(Loop *L,
// blocks, then it is impossible to statically determine which value should
// be used.
for (unsigned i = 1, e = exitingBlocks.size(); i < e; ++i) {
- if (incoming != P->getIncomingValueForBlock(exitingBlocks[i]))
- return false;
+ if (incoming != P->getIncomingValueForBlock(exitingBlocks[i])) {
+ AllOutgoingValuesSame = false;
+ break;
+ }
}
+ if (!AllOutgoingValuesSame)
+ break;
+
if (Instruction *I = dyn_cast<Instruction>(incoming))
- if (!L->makeLoopInvariant(I, Changed, Preheader->getTerminator()))
- return false;
+ if (!L->makeLoopInvariant(I, Changed, Preheader->getTerminator())) {
+ AllEntriesInvariant = false;
+ break;
+ }
++BI;
}
+ if (Changed)
+ SE.forgetLoopDispositions(L);
+
+ if (!AllEntriesInvariant || !AllOutgoingValuesSame)
+ return false;
+
// Make sure that no instructions in the block have potential side-effects.
// This includes instructions that could write to memory, and loads that are
// marked volatile. This could be made more aggressive by using aliasing
@@ -153,14 +168,15 @@ bool LoopDeletion::runOnLoop(Loop *L, LPPassManager &) {
if (exitBlocks.size() != 1)
return false;
+ ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
+
// Finally, we have to check that the loop really is dead.
bool Changed = false;
- if (!isLoopDead(L, exitingBlocks, exitBlocks, Changed, preheader))
+ if (!isLoopDead(L, SE, exitingBlocks, exitBlocks, Changed, preheader))
return Changed;
// Don't remove loops for which we can't solve the trip count.
// They could be infinite, in which case we'd be changing program behavior.
- ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
const SCEV *S = SE.getMaxBackedgeTakenCount(L);
if (isa<SCEVCouldNotCompute>(S))
return Changed;