1
0
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:
Serguei Katkov 2018-03-19 08:32:09 +00:00
parent ee51ad3ba8
commit f7b67d048b
2 changed files with 59 additions and 49 deletions

View File

@ -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,

View File

@ -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;