summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorEli Friedman <efriedma@codeaurora.org>2017-01-11 21:07:15 +0000
committerEli Friedman <efriedma@codeaurora.org>2017-01-11 21:07:15 +0000
commitbd6dedaa7fa443f0175d3c73b14c7e4a9230d122 (patch)
treeefc706c47f77bf24cdc0cbad8f0d79a64c1f13e9 /llvm/lib/Analysis/ScalarEvolution.cpp
parentde0f50886f4d122a1142c77fa5f36ad1533c96d7 (diff)
downloadbcm5719-llvm-bd6dedaa7fa443f0175d3c73b14c7e4a9230d122.tar.gz
bcm5719-llvm-bd6dedaa7fa443f0175d3c73b14c7e4a9230d122.zip
[SCEV] Make howFarToZero max backedge-taken count check for precondition.
Refines max backedge-taken count if a loop like "for (int i = 0; i != n; ++i) { /* body */ }" is rotated. Differential Revision: https://reviews.llvm.org/D28536 llvm-svn: 291704
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index bd7e0e832f6..791042c61fb 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -7207,6 +7207,23 @@ ScalarEvolution::howFarToZero(const SCEV *V, const Loop *L, bool ControlsExit,
// N = Distance (as unsigned)
if (StepC->getValue()->equalsInt(1) || StepC->getValue()->isAllOnesValue()) {
APInt MaxBECount = getUnsignedRange(Distance).getUnsignedMax();
+
+ // When a loop like "for (int i = 0; i != n; ++i) { /* body */ }" is rotated,
+ // we end up with a loop whose backedge-taken count is n - 1. Detect this
+ // case, and see if we can improve the bound.
+ //
+ // Explicitly handling this here is necessary because getUnsignedRange
+ // isn't context-sensitive; it doesn't know that we only care about the
+ // range inside the loop.
+ const SCEV *Zero = getZero(Distance->getType());
+ const SCEV *One = getOne(Distance->getType());
+ const SCEV *DistancePlusOne = getAddExpr(Distance, One);
+ if (isLoopEntryGuardedByCond(L, ICmpInst::ICMP_NE, DistancePlusOne, Zero)) {
+ // If Distance + 1 doesn't overflow, we can compute the maximum distance
+ // as "unsigned_max(Distance + 1) - 1".
+ ConstantRange CR = getUnsignedRange(DistancePlusOne);
+ MaxBECount = APIntOps::umin(MaxBECount, CR.getUnsignedMax() - 1);
+ }
return ExitLimit(Distance, getConstant(MaxBECount), false, Predicates);
}
OpenPOWER on IntegriCloud