summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorMax Kazantsev <max.kazantsev@azul.com>2018-03-27 07:30:38 +0000
committerMax Kazantsev <max.kazantsev@azul.com>2018-03-27 07:30:38 +0000
commit7094c8deb2b2bc0a5a4b79f5a5cc195bf4e1d5ca (patch)
tree70c5cdcf3057d66d3a4425049b150a98ad16a87b /llvm/lib/Analysis/ScalarEvolution.cpp
parent3ddeb33e0017209792e72b33dee1a0ba69b316f1 (diff)
downloadbcm5719-llvm-7094c8deb2b2bc0a5a4b79f5a5cc195bf4e1d5ca.tar.gz
bcm5719-llvm-7094c8deb2b2bc0a5a4b79f5a5cc195bf4e1d5ca.zip
[SCEV] Make exact taken count calculation more optimistic
Currently, `getExact` fails if it sees two exit counts in different blocks. There is no solid reason to do so, given that we only calculate exact non-taken count for exiting blocks that dominate latch. Using this fact, we can simply take min out of all exits of all blocks to get the exact taken count. This patch makes the calculation more optimistic with enforcing our assumption with asserts. It allows us to calculate exact backedge taken count in trivial loops like for (int i = 0; i < 100; i++) { if (i > 50) break; . . . } Differential Revision: https://reviews.llvm.org/D44676 Reviewed By: fhahn llvm-svn: 328611
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp22
1 files changed, 16 insertions, 6 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index b44107d9a89..3a1c6fbd408 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -6413,11 +6413,11 @@ const SCEV *ScalarEvolution::getExitCount(const Loop *L,
const SCEV *
ScalarEvolution::getPredicatedBackedgeTakenCount(const Loop *L,
SCEVUnionPredicate &Preds) {
- return getPredicatedBackedgeTakenInfo(L).getExact(this, &Preds);
+ return getPredicatedBackedgeTakenInfo(L).getExact(L, this, &Preds);
}
const SCEV *ScalarEvolution::getBackedgeTakenCount(const Loop *L) {
- return getBackedgeTakenInfo(L).getExact(this);
+ return getBackedgeTakenInfo(L).getExact(L, this);
}
/// Similar to getBackedgeTakenCount, except return the least SCEV value that is
@@ -6474,8 +6474,8 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
// must be cleared in this scope.
BackedgeTakenInfo Result = computeBackedgeTakenCount(L);
- if (Result.getExact(this) != getCouldNotCompute()) {
- assert(isLoopInvariant(Result.getExact(this), L) &&
+ if (Result.getExact(L, this) != getCouldNotCompute()) {
+ assert(isLoopInvariant(Result.getExact(L, this), L) &&
isLoopInvariant(Result.getMax(this), L) &&
"Computed backedge-taken count isn't loop invariant for loop!");
++NumTripCountsComputed;
@@ -6656,20 +6656,30 @@ void ScalarEvolution::forgetValue(Value *V) {
/// caller's responsibility to specify the relevant loop exit using
/// getExact(ExitingBlock, SE).
const SCEV *
-ScalarEvolution::BackedgeTakenInfo::getExact(ScalarEvolution *SE,
+ScalarEvolution::BackedgeTakenInfo::getExact(const Loop *L, ScalarEvolution *SE,
SCEVUnionPredicate *Preds) const {
// If any exits were not computable, the loop is not computable.
if (!isComplete() || ExitNotTaken.empty())
return SE->getCouldNotCompute();
const SCEV *BECount = nullptr;
+ const BasicBlock *Latch = L->getLoopLatch();
+ // All exits we have collected must dominate the only latch.
+ if (!Latch)
+ return SE->getCouldNotCompute();
+
+ // All exits we have gathered dominate loop's latch, so exact trip count is
+ // simply a minimum out of all these calculated exit counts.
for (auto &ENT : ExitNotTaken) {
assert(ENT.ExactNotTaken != SE->getCouldNotCompute() && "bad exit SCEV");
+ assert(SE->DT.dominates(ENT.ExitingBlock, Latch) &&
+ "We should only have known counts for exits that dominate latch!");
if (!BECount)
BECount = ENT.ExactNotTaken;
else if (BECount != ENT.ExactNotTaken)
- return SE->getCouldNotCompute();
+ BECount = SE->getUMinFromMismatchedTypes(BECount, ENT.ExactNotTaken);
+
if (Preds && !ENT.hasAlwaysTruePredicate())
Preds->add(ENT.Predicate.get());
OpenPOWER on IntegriCloud