[llvm] 0a1d394 - [NFC] Refactor loop-invariant getters to return Optional
Max Kazantsev via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 13 00:03:37 PST 2020
Author: Max Kazantsev
Date: 2020-11-13T15:03:10+07:00
New Revision: 0a1d394bf3a5ccb561d5c68a19559182a2b25939
URL: https://github.com/llvm/llvm-project/commit/0a1d394bf3a5ccb561d5c68a19559182a2b25939
DIFF: https://github.com/llvm/llvm-project/commit/0a1d394bf3a5ccb561d5c68a19559182a2b25939.diff
LOG: [NFC] Refactor loop-invariant getters to return Optional
Added:
Modified:
llvm/include/llvm/Analysis/ScalarEvolution.h
llvm/lib/Analysis/ScalarEvolution.cpp
llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index 3fd0968cb34a..71f56b8bbc0e 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -963,26 +963,33 @@ class ScalarEvolution {
Optional<const SCEV *> NumIter = None,
const Instruction *Context = nullptr);
- /// Return true if the result of the predicate LHS `Pred` RHS is loop
- /// invariant with respect to L. Set InvariantPred, InvariantLHS and
- /// InvariantLHS so that InvariantLHS `InvariantPred` InvariantRHS is the
- /// loop invariant form of LHS `Pred` RHS.
- bool isLoopInvariantPredicate(ICmpInst::Predicate Pred, const SCEV *LHS,
- const SCEV *RHS, const Loop *L,
- ICmpInst::Predicate &InvariantPred,
- const SCEV *&InvariantLHS,
- const SCEV *&InvariantRHS);
-
- /// Return true if the result of the predicate LHS `Pred` RHS is loop
- /// invariant with respect to L at given Context during at least first
- /// MaxIter iterations. Set InvariantPred, InvariantLHS and InvariantLHS so
- /// that InvariantLHS `InvariantPred` InvariantRHS is the loop invariant form
- /// of LHS `Pred` RHS. The predicate should be the loop's exit condition.
- bool isLoopInvariantExitCondDuringFirstIterations(
- ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
- const Instruction *Context, const SCEV *MaxIter,
- ICmpInst::Predicate &InvariantPred, const SCEV *&InvariantLHS,
- const SCEV *&InvariantRHS);
+ struct LoopInvariantPredicate {
+ ICmpInst::Predicate Pred;
+ const SCEV *LHS;
+ const SCEV *RHS;
+
+ LoopInvariantPredicate(ICmpInst::Predicate Pred, const SCEV *LHS,
+ const SCEV *RHS)
+ : Pred(Pred), LHS(LHS), RHS(RHS) {}
+ };
+ /// If the result of the predicate LHS `Pred` RHS is loop invariant with
+ /// respect to L, return a LoopInvariantPredicate with LHS and RHS being
+ /// invariants, available at L's entry. Otherwise, return None.
+ Optional<LoopInvariantPredicate>
+ getLoopInvariantPredicate(ICmpInst::Predicate Pred, const SCEV *LHS,
+ const SCEV *RHS, const Loop *L);
+
+ /// If the result of the predicate LHS `Pred` RHS is loop invariant with
+ /// respect to L at given Context during at least first MaxIter iterations,
+ /// return a LoopInvariantPredicate with LHS and RHS being invariants,
+ /// available at L's entry. Otherwise, return None. The predicate should be
+ /// the loop's exit condition.
+ Optional<LoopInvariantPredicate>
+ getLoopInvariantExitCondDuringFirstIterations(ICmpInst::Predicate Pred,
+ const SCEV *LHS,
+ const SCEV *RHS, const Loop *L,
+ const Instruction *Context,
+ const SCEV *MaxIter);
/// Simplify LHS and RHS in a comparison with predicate Pred. Return true
/// iff any changes were made. If the operands are provably equal or
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index a6ce5a001b0a..6f2b1f71faee 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -9552,15 +9552,15 @@ ScalarEvolution::getMonotonicPredicateTypeImpl(const SCEVAddRecExpr *LHS,
}
}
-bool ScalarEvolution::isLoopInvariantPredicate(
- ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
- ICmpInst::Predicate &InvariantPred, const SCEV *&InvariantLHS,
- const SCEV *&InvariantRHS) {
+Optional<ScalarEvolution::LoopInvariantPredicate>
+ScalarEvolution::getLoopInvariantPredicate(ICmpInst::Predicate Pred,
+ const SCEV *LHS, const SCEV *RHS,
+ const Loop *L) {
// If there is a loop-invariant, force it into the RHS, otherwise bail out.
if (!isLoopInvariant(RHS, L)) {
if (!isLoopInvariant(LHS, L))
- return false;
+ return None;
std::swap(LHS, RHS);
Pred = ICmpInst::getSwappedPredicate(Pred);
@@ -9568,11 +9568,11 @@ bool ScalarEvolution::isLoopInvariantPredicate(
const SCEVAddRecExpr *ArLHS = dyn_cast<SCEVAddRecExpr>(LHS);
if (!ArLHS || ArLHS->getLoop() != L)
- return false;
+ return None;
auto MonotonicType = getMonotonicPredicateType(ArLHS, Pred);
if (!MonotonicType)
- return false;
+ return None;
// If the predicate "ArLHS `Pred` RHS" monotonically increases from false to
// true as the loop iterates, and the backedge is control dependent on
// "ArLHS `Pred` RHS" == true then we can reason as follows:
@@ -9594,19 +9594,15 @@ bool ScalarEvolution::isLoopInvariantPredicate(
auto P = Increasing ? Pred : ICmpInst::getInversePredicate(Pred);
if (!isLoopBackedgeGuardedByCond(L, P, LHS, RHS))
- return false;
+ return None;
- InvariantPred = Pred;
- InvariantLHS = ArLHS->getStart();
- InvariantRHS = RHS;
- return true;
+ return ScalarEvolution::LoopInvariantPredicate(Pred, ArLHS->getStart(), RHS);
}
-bool ScalarEvolution::isLoopInvariantExitCondDuringFirstIterations(
+Optional<ScalarEvolution::LoopInvariantPredicate>
+ScalarEvolution::getLoopInvariantExitCondDuringFirstIterations(
ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
- const Instruction *Context, const SCEV *MaxIter,
- ICmpInst::Predicate &InvariantPred, const SCEV *&InvariantLHS,
- const SCEV *&InvariantRHS) {
+ const Instruction *Context, const SCEV *MaxIter) {
// Try to prove the following set of facts:
// - The predicate is monotonic in the iteration space.
// - If the check does not fail on the 1st iteration:
@@ -9617,7 +9613,7 @@ bool ScalarEvolution::isLoopInvariantExitCondDuringFirstIterations(
// If there is a loop-invariant, force it into the RHS, otherwise bail out.
if (!isLoopInvariant(RHS, L)) {
if (!isLoopInvariant(LHS, L))
- return false;
+ return None;
std::swap(LHS, RHS);
Pred = ICmpInst::getSwappedPredicate(Pred);
@@ -9625,22 +9621,19 @@ bool ScalarEvolution::isLoopInvariantExitCondDuringFirstIterations(
auto *AR = dyn_cast<SCEVAddRecExpr>(LHS);
if (!AR || AR->getLoop() != L)
- return false;
+ return None;
if (!getMonotonicPredicateType(AR, Pred, MaxIter, Context))
- return false;
+ return None;
// Value of IV on suggested last iteration.
const SCEV *Last = AR->evaluateAtIteration(MaxIter, *this);
// Does it still meet the requirement?
if (!isKnownPredicateAt(Pred, Last, RHS, Context))
- return false;
+ return None;
// Everything is fine.
- InvariantPred = Pred;
- InvariantLHS = AR->getStart();
- InvariantRHS = RHS;
- return true;
+ return ScalarEvolution::LoopInvariantPredicate(Pred, AR->getStart(), RHS);
}
bool ScalarEvolution::isKnownPredicateViaConstantRanges(
diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
index 2965349623f6..cc3bf87be46e 100644
--- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -1336,10 +1336,13 @@ analyzeCond(const Loop *L, BranchInst *BI, ScalarEvolution *SE,
return CannotOptimize;
// Check if there is a loop-invariant predicate equivalent to our check.
- if (!SE->isLoopInvariantExitCondDuringFirstIterations(
- Pred, LHSS, RHSS, L, BI, MaxIter, InvariantPred, InvariantLHS,
- InvariantRHS))
+ auto LIP = SE->getLoopInvariantExitCondDuringFirstIterations(Pred, LHSS, RHSS,
+ L, BI, MaxIter);
+ if (!LIP)
return CannotOptimize;
+ InvariantPred = LIP->Pred;
+ InvariantLHS = LIP->LHS;
+ InvariantRHS = LIP->RHS;
// Can we prove it to be trivially true?
if (SE->isKnownPredicateAt(InvariantPred, InvariantLHS, InvariantRHS, BI))
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index 8e2fa03e760c..f5c92a5f60cf 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -191,15 +191,15 @@ bool SimplifyIndvar::makeIVComparisonInvariant(ICmpInst *ICmp,
const SCEV *S = SE->getSCEVAtScope(ICmp->getOperand(IVOperIdx), ICmpLoop);
const SCEV *X = SE->getSCEVAtScope(ICmp->getOperand(1 - IVOperIdx), ICmpLoop);
- ICmpInst::Predicate InvariantPredicate;
- const SCEV *InvariantLHS, *InvariantRHS;
-
auto *PN = dyn_cast<PHINode>(IVOperand);
if (!PN)
return false;
- if (!SE->isLoopInvariantPredicate(Pred, S, X, L, InvariantPredicate,
- InvariantLHS, InvariantRHS))
+ auto LIP = SE->getLoopInvariantPredicate(Pred, S, X, L);
+ if (!LIP)
return false;
+ ICmpInst::Predicate InvariantPredicate = LIP->Pred;
+ const SCEV *InvariantLHS = LIP->LHS;
+ const SCEV *InvariantRHS = LIP->RHS;
// Rewrite the comparison to a loop invariant comparison if it can be done
// cheaply, where cheaply means "we don't need to emit any new
More information about the llvm-commits
mailing list