mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[SCEV] Factor out isKnownViaInduction. NFC.
This just extracts the isKnownViaInduction from isKnownPredicate. Reviewers: sanjoy, mkazantsev, reames Reviewed By: mkazantsev Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D44554 llvm-svn: 327824
This commit is contained in:
parent
ee51ad3ba8
commit
f7b67d048b
@ -848,6 +848,27 @@ public:
|
|||||||
std::pair<const SCEV *, const SCEV *> SplitIntoInitAndPostInc(const Loop *L,
|
std::pair<const SCEV *, const SCEV *> SplitIntoInitAndPostInc(const Loop *L,
|
||||||
const SCEV *S);
|
const SCEV *S);
|
||||||
|
|
||||||
|
/// We'd like to check the predicate on every iteration of the most dominated
|
||||||
|
/// loop between loops used in LHS and RHS.
|
||||||
|
/// To do this we use the following list of steps:
|
||||||
|
/// 1. Collect set S all loops on which either LHS or RHS depend.
|
||||||
|
/// 2. If S is non-empty
|
||||||
|
/// a. Let PD be the element of S which is dominated by all other elements.
|
||||||
|
/// b. Let E(LHS) be value of LHS on entry of PD.
|
||||||
|
/// To get E(LHS), we should just take LHS and replace all AddRecs that are
|
||||||
|
/// attached to PD on with their entry values.
|
||||||
|
/// Define E(RHS) in the same way.
|
||||||
|
/// c. Let B(LHS) be value of L on backedge of PD.
|
||||||
|
/// To get B(LHS), we should just take LHS and replace all AddRecs that are
|
||||||
|
/// attached to PD on with their backedge values.
|
||||||
|
/// Define B(RHS) in the same way.
|
||||||
|
/// d. Note that E(LHS) and E(RHS) are automatically available on entry of PD,
|
||||||
|
/// so we can assert on that.
|
||||||
|
/// e. Return true if isLoopEntryGuardedByCond(Pred, E(LHS), E(RHS)) &&
|
||||||
|
/// isLoopBackedgeGuardedByCond(Pred, B(LHS), B(RHS))
|
||||||
|
bool isKnownViaInduction(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||||
|
const SCEV *RHS);
|
||||||
|
|
||||||
/// Test if the given expression is known to satisfy the condition described
|
/// Test if the given expression is known to satisfy the condition described
|
||||||
/// by Pred, LHS, and RHS.
|
/// by Pred, LHS, and RHS.
|
||||||
bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS,
|
bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS,
|
||||||
|
@ -8687,35 +8687,16 @@ ScalarEvolution::SplitIntoInitAndPostInc(const Loop *L, const SCEV *S) {
|
|||||||
return { Start, PostInc };
|
return { Start, PostInc };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScalarEvolution::isKnownPredicate(ICmpInst::Predicate Pred,
|
bool ScalarEvolution::isKnownViaInduction(ICmpInst::Predicate Pred,
|
||||||
const SCEV *LHS, const SCEV *RHS) {
|
const SCEV *LHS, const SCEV *RHS) {
|
||||||
// Canonicalize the inputs first.
|
|
||||||
(void)SimplifyICmpOperands(Pred, LHS, RHS);
|
|
||||||
|
|
||||||
// We'd like to check the predicate on every iteration of the most dominated
|
|
||||||
// loop between loops used in LHS and RHS.
|
|
||||||
// To do this we use the following list of steps:
|
|
||||||
// 1. Collect set S all loops on which either LHS or RHS depend.
|
|
||||||
// 2. If S is non-empty
|
|
||||||
// a. Let PD be the element of S which is dominated by all other elements of S
|
|
||||||
// b. Let E(LHS) be value of LHS on entry of PD.
|
|
||||||
// To get E(LHS), we should just take LHS and replace all AddRecs that are
|
|
||||||
// attached to PD on with their entry values.
|
|
||||||
// Define E(RHS) in the same way.
|
|
||||||
// c. Let B(LHS) be value of L on backedge of PD.
|
|
||||||
// To get B(LHS), we should just take LHS and replace all AddRecs that are
|
|
||||||
// attached to PD on with their backedge values.
|
|
||||||
// Define B(RHS) in the same way.
|
|
||||||
// d. Note that E(LHS) and E(RHS) are automatically available on entry of PD,
|
|
||||||
// so we can assert on that.
|
|
||||||
// e. Return true if isLoopEntryGuardedByCond(Pred, E(LHS), E(RHS)) &&
|
|
||||||
// isLoopBackedgeGuardedByCond(Pred, B(LHS), B(RHS))
|
|
||||||
|
|
||||||
// First collect all loops.
|
// First collect all loops.
|
||||||
SmallPtrSet<const Loop *, 8> LoopsUsed;
|
SmallPtrSet<const Loop *, 8> LoopsUsed;
|
||||||
getUsedLoops(LHS, LoopsUsed);
|
getUsedLoops(LHS, LoopsUsed);
|
||||||
getUsedLoops(RHS, LoopsUsed);
|
getUsedLoops(RHS, LoopsUsed);
|
||||||
|
|
||||||
|
if (LoopsUsed.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
// Domination relationship must be a linear order on collected loops.
|
// Domination relationship must be a linear order on collected loops.
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
for (auto *L1 : LoopsUsed)
|
for (auto *L1 : LoopsUsed)
|
||||||
@ -8724,35 +8705,43 @@ bool ScalarEvolution::isKnownPredicate(ICmpInst::Predicate Pred,
|
|||||||
DT.dominates(L2->getHeader(), L1->getHeader())) &&
|
DT.dominates(L2->getHeader(), L1->getHeader())) &&
|
||||||
"Domination relationship is not a linear order");
|
"Domination relationship is not a linear order");
|
||||||
#endif
|
#endif
|
||||||
if (!LoopsUsed.empty()) {
|
|
||||||
const Loop *MDL = *std::max_element(LoopsUsed.begin(), LoopsUsed.end(),
|
const Loop *MDL = *std::max_element(LoopsUsed.begin(), LoopsUsed.end(),
|
||||||
[&](const Loop *L1, const Loop *L2) {
|
[&](const Loop *L1, const Loop *L2) {
|
||||||
return DT.dominates(L1->getHeader(), L2->getHeader());
|
return DT.dominates(L1->getHeader(), L2->getHeader());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get init and post increment value for LHS.
|
// Get init and post increment value for LHS.
|
||||||
auto SplitLHS = SplitIntoInitAndPostInc(MDL, LHS);
|
auto SplitLHS = SplitIntoInitAndPostInc(MDL, LHS);
|
||||||
if (SplitLHS.first != getCouldNotCompute()) {
|
// if LHS contains unknown non-invariant SCEV then bail out.
|
||||||
// if LHS does not contain unknown non-invariant SCEV then
|
if (SplitLHS.first == getCouldNotCompute())
|
||||||
// get init and post increment value for RHS.
|
return false;
|
||||||
auto SplitRHS = SplitIntoInitAndPostInc(MDL, RHS);
|
assert (SplitLHS.first != getCouldNotCompute() && "Unexpected CNC");
|
||||||
if (SplitRHS.first != getCouldNotCompute()) {
|
// Get init and post increment value for RHS.
|
||||||
// if RHS does not contain unknown non-invariant SCEV then
|
auto SplitRHS = SplitIntoInitAndPostInc(MDL, RHS);
|
||||||
// check whether implication is possible.
|
// if RHS contains unknown non-invariant SCEV then bail out.
|
||||||
// It is possible that init SCEV contains an invariant load but it does
|
if (SplitRHS.first == getCouldNotCompute())
|
||||||
// not dominate MDL and is not available at MDL loop entry, so we should
|
return false;
|
||||||
// check it here.
|
assert (SplitRHS.first != getCouldNotCompute() && "Unexpected CNC");
|
||||||
if (isAvailableAtLoopEntry(SplitLHS.first, MDL) &&
|
// It is possible that init SCEV contains an invariant load but it does
|
||||||
isAvailableAtLoopEntry(SplitRHS.first, MDL)) {
|
// not dominate MDL and is not available at MDL loop entry, so we should
|
||||||
if (isLoopEntryGuardedByCond(MDL, Pred, SplitLHS.first,
|
// check it here.
|
||||||
SplitRHS.first) &&
|
if (!isAvailableAtLoopEntry(SplitLHS.first, MDL) ||
|
||||||
isLoopBackedgeGuardedByCond(MDL, Pred, SplitLHS.second,
|
!isAvailableAtLoopEntry(SplitRHS.first, MDL))
|
||||||
SplitRHS.second))
|
return false;
|
||||||
return true;
|
|
||||||
}
|
return isLoopEntryGuardedByCond(MDL, Pred, SplitLHS.first, SplitRHS.first) &&
|
||||||
}
|
isLoopBackedgeGuardedByCond(MDL, Pred, SplitLHS.second,
|
||||||
}
|
SplitRHS.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScalarEvolution::isKnownPredicate(ICmpInst::Predicate Pred,
|
||||||
|
const SCEV *LHS, const SCEV *RHS) {
|
||||||
|
// Canonicalize the inputs first.
|
||||||
|
(void)SimplifyICmpOperands(Pred, LHS, RHS);
|
||||||
|
|
||||||
|
if (isKnownViaInduction(Pred, LHS, RHS))
|
||||||
|
return true;
|
||||||
|
|
||||||
if (isKnownPredicateViaSplitting(Pred, LHS, RHS))
|
if (isKnownPredicateViaSplitting(Pred, LHS, RHS))
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user