mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-08 19:25:47 +00:00
Enhance ScalarEvolution::isKnownPredicate with support for
loop conditions which are invariants. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100995 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -380,6 +380,13 @@ namespace llvm {
|
|||||||
Constant *getConstantEvolutionLoopExitValue(PHINode *PN, const APInt& BEs,
|
Constant *getConstantEvolutionLoopExitValue(PHINode *PN, const APInt& BEs,
|
||||||
const Loop *L);
|
const Loop *L);
|
||||||
|
|
||||||
|
/// isKnownPredicateWithRanges - Test if the given expression is known to
|
||||||
|
/// satisfy the condition described by Pred and the known constant ranges
|
||||||
|
/// of LHS and RHS.
|
||||||
|
///
|
||||||
|
bool isKnownPredicateWithRanges(ICmpInst::Predicate Pred,
|
||||||
|
const SCEV *LHS, const SCEV *RHS);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static char ID; // Pass identification, replacement for typeid
|
static char ID; // Pass identification, replacement for typeid
|
||||||
ScalarEvolution();
|
ScalarEvolution();
|
||||||
|
@@ -4651,10 +4651,35 @@ bool ScalarEvolution::isKnownNonZero(const SCEV *S) {
|
|||||||
|
|
||||||
bool ScalarEvolution::isKnownPredicate(ICmpInst::Predicate Pred,
|
bool ScalarEvolution::isKnownPredicate(ICmpInst::Predicate Pred,
|
||||||
const SCEV *LHS, const SCEV *RHS) {
|
const SCEV *LHS, const SCEV *RHS) {
|
||||||
|
// If LHS or RHS is an addrec, check to see if the condition is true in
|
||||||
|
// every iteration of the loop.
|
||||||
|
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(LHS))
|
||||||
|
if (isLoopEntryGuardedByCond(
|
||||||
|
AR->getLoop(), Pred, AR->getStart(), RHS) &&
|
||||||
|
isLoopBackedgeGuardedByCond(
|
||||||
|
AR->getLoop(), Pred,
|
||||||
|
getAddExpr(AR, AR->getStepRecurrence(*this)), RHS))
|
||||||
|
return true;
|
||||||
|
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(RHS))
|
||||||
|
if (isLoopEntryGuardedByCond(
|
||||||
|
AR->getLoop(), Pred, LHS, AR->getStart()) &&
|
||||||
|
isLoopBackedgeGuardedByCond(
|
||||||
|
AR->getLoop(), Pred,
|
||||||
|
LHS, getAddExpr(AR, AR->getStepRecurrence(*this))))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Otherwise see what can be done with known constant ranges.
|
||||||
|
return isKnownPredicateWithRanges(Pred, LHS, RHS);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ScalarEvolution::isKnownPredicateWithRanges(ICmpInst::Predicate Pred,
|
||||||
|
const SCEV *LHS, const SCEV *RHS) {
|
||||||
if (HasSameValue(LHS, RHS))
|
if (HasSameValue(LHS, RHS))
|
||||||
return ICmpInst::isTrueWhenEqual(Pred);
|
return ICmpInst::isTrueWhenEqual(Pred);
|
||||||
|
|
||||||
|
// This code is split out from isKnownPredicate because it is called from
|
||||||
|
// within isLoopEntryGuardedByCond.
|
||||||
switch (Pred) {
|
switch (Pred) {
|
||||||
default:
|
default:
|
||||||
llvm_unreachable("Unexpected ICmpInst::Predicate value!");
|
llvm_unreachable("Unexpected ICmpInst::Predicate value!");
|
||||||
@@ -5026,26 +5051,26 @@ ScalarEvolution::isImpliedCondOperandsHelper(ICmpInst::Predicate Pred,
|
|||||||
break;
|
break;
|
||||||
case ICmpInst::ICMP_SLT:
|
case ICmpInst::ICMP_SLT:
|
||||||
case ICmpInst::ICMP_SLE:
|
case ICmpInst::ICMP_SLE:
|
||||||
if (isKnownPredicate(ICmpInst::ICMP_SLE, LHS, FoundLHS) &&
|
if (isKnownPredicateWithRanges(ICmpInst::ICMP_SLE, LHS, FoundLHS) &&
|
||||||
isKnownPredicate(ICmpInst::ICMP_SGE, RHS, FoundRHS))
|
isKnownPredicateWithRanges(ICmpInst::ICMP_SGE, RHS, FoundRHS))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case ICmpInst::ICMP_SGT:
|
case ICmpInst::ICMP_SGT:
|
||||||
case ICmpInst::ICMP_SGE:
|
case ICmpInst::ICMP_SGE:
|
||||||
if (isKnownPredicate(ICmpInst::ICMP_SGE, LHS, FoundLHS) &&
|
if (isKnownPredicateWithRanges(ICmpInst::ICMP_SGE, LHS, FoundLHS) &&
|
||||||
isKnownPredicate(ICmpInst::ICMP_SLE, RHS, FoundRHS))
|
isKnownPredicateWithRanges(ICmpInst::ICMP_SLE, RHS, FoundRHS))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case ICmpInst::ICMP_ULT:
|
case ICmpInst::ICMP_ULT:
|
||||||
case ICmpInst::ICMP_ULE:
|
case ICmpInst::ICMP_ULE:
|
||||||
if (isKnownPredicate(ICmpInst::ICMP_ULE, LHS, FoundLHS) &&
|
if (isKnownPredicateWithRanges(ICmpInst::ICMP_ULE, LHS, FoundLHS) &&
|
||||||
isKnownPredicate(ICmpInst::ICMP_UGE, RHS, FoundRHS))
|
isKnownPredicateWithRanges(ICmpInst::ICMP_UGE, RHS, FoundRHS))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case ICmpInst::ICMP_UGT:
|
case ICmpInst::ICMP_UGT:
|
||||||
case ICmpInst::ICMP_UGE:
|
case ICmpInst::ICMP_UGE:
|
||||||
if (isKnownPredicate(ICmpInst::ICMP_UGE, LHS, FoundLHS) &&
|
if (isKnownPredicateWithRanges(ICmpInst::ICMP_UGE, LHS, FoundLHS) &&
|
||||||
isKnownPredicate(ICmpInst::ICMP_ULE, RHS, FoundRHS))
|
isKnownPredicateWithRanges(ICmpInst::ICMP_ULE, RHS, FoundRHS))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user