summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp75
1 files changed, 17 insertions, 58 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index a6b3dce0a0d..d8a41944acb 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -6884,63 +6884,12 @@ ScalarEvolution::computeBackedgeTakenCount(const Loop *L,
ScalarEvolution::ExitLimit
ScalarEvolution::computeExitLimit(const Loop *L, BasicBlock *ExitingBlock,
bool AllowPredicates) {
- // Okay, we've chosen an exiting block. See what condition causes us to exit
- // at this block and remember the exit block and whether all other targets
- // lead to the loop header.
- bool MustExecuteLoopHeader = true;
- BasicBlock *Exit = nullptr;
- for (auto *SBB : successors(ExitingBlock))
- if (!L->contains(SBB)) {
- if (Exit) // Multiple exit successors.
- return getCouldNotCompute();
- Exit = SBB;
- } else if (SBB != L->getHeader()) {
- MustExecuteLoopHeader = false;
- }
-
- // At this point, we know we have a conditional branch that determines whether
- // the loop is exited. However, we don't know if the branch is executed each
- // time through the loop. If not, then the execution count of the branch will
- // not be equal to the trip count of the loop.
- //
- // Currently we check for this by checking to see if the Exit branch goes to
- // the loop header. If so, we know it will always execute the same number of
- // times as the loop. We also handle the case where the exit block *is* the
- // loop header. This is common for un-rotated loops.
- //
- // If both of those tests fail, walk up the unique predecessor chain to the
- // header, stopping if there is an edge that doesn't exit the loop. If the
- // header is reached, the execution count of the branch will be equal to the
- // trip count of the loop.
- //
- // More extensive analysis could be done to handle more cases here.
- //
- if (!MustExecuteLoopHeader && ExitingBlock != L->getHeader()) {
- // The simple checks failed, try climbing the unique predecessor chain
- // up to the header.
- bool Ok = false;
- for (BasicBlock *BB = ExitingBlock; BB; ) {
- BasicBlock *Pred = BB->getUniquePredecessor();
- if (!Pred)
- return getCouldNotCompute();
- TerminatorInst *PredTerm = Pred->getTerminator();
- for (const BasicBlock *PredSucc : PredTerm->successors()) {
- if (PredSucc == BB)
- continue;
- // If the predecessor has a successor that isn't BB and isn't
- // outside the loop, assume the worst.
- if (L->contains(PredSucc))
- return getCouldNotCompute();
- }
- if (Pred == L->getHeader()) {
- Ok = true;
- break;
- }
- BB = Pred;
- }
- if (!Ok)
- return getCouldNotCompute();
- }
+ assert(L->contains(ExitingBlock) && "Exit count for non-loop block?");
+ // If our exiting block does not dominate the latch, then its connection with
+ // loop's exit limit may be far from trivial.
+ const BasicBlock *Latch = L->getLoopLatch();
+ if (!Latch || !DT.dominates(ExitingBlock, Latch))
+ return getCouldNotCompute();
bool IsOnlyExit = (L->getExitingBlock() != nullptr);
TerminatorInst *Term = ExitingBlock->getTerminator();
@@ -6955,9 +6904,19 @@ ScalarEvolution::computeExitLimit(const Loop *L, BasicBlock *ExitingBlock,
/*ControlsExit=*/IsOnlyExit, AllowPredicates);
}
- if (SwitchInst *SI = dyn_cast<SwitchInst>(Term))
+ if (SwitchInst *SI = dyn_cast<SwitchInst>(Term)) {
+ // For switch, make sure that there is a single exit from the loop.
+ BasicBlock *Exit = nullptr;
+ for (auto *SBB : successors(ExitingBlock))
+ if (!L->contains(SBB)) {
+ if (Exit) // Multiple exit successors.
+ return getCouldNotCompute();
+ Exit = SBB;
+ }
+ assert(Exit && "Exiting block must have at least one exit");
return computeExitLimitFromSingleExitSwitch(L, SI, Exit,
/*ControlsExit=*/IsOnlyExit);
+ }
return getCouldNotCompute();
}
OpenPOWER on IntegriCloud