Teach IndVarSimplify how to eliminate comparisons involving induction

variables. For example, with code like this:

  for (i=0;i<n;++i)
    if (i<n)
      x[i] = 0;

IndVarSimplify will now recognize that i is always less than n inside
the loop, and eliminate the if.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101000 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman
2010-04-11 23:10:12 +00:00
parent 53c66eacc4
commit 3fddbb337d
2 changed files with 78 additions and 0 deletions

View File

@@ -97,6 +97,7 @@ namespace {
private:
void EliminateIVComparisons();
void RewriteNonIntegerIVs(Loop *L);
ICmpInst *LinearFunctionTestReplace(Loop *L, const SCEV *BackedgeTakenCount,
@@ -336,6 +337,40 @@ void IndVarSimplify::RewriteNonIntegerIVs(Loop *L) {
SE->forgetLoop(L);
}
void IndVarSimplify::EliminateIVComparisons() {
// Look for ICmp users.
for (IVUsers::iterator I = IU->begin(), E = IU->end(); I != E;) {
IVStrideUse &UI = *I++;
ICmpInst *ICmp = dyn_cast<ICmpInst>(UI.getUser());
if (!ICmp) continue;
bool Swapped = UI.getOperandValToReplace() == ICmp->getOperand(1);
ICmpInst::Predicate Pred = ICmp->getPredicate();
if (Swapped) Pred = ICmpInst::getSwappedPredicate(Pred);
// Get the SCEVs for the ICmp operands.
const SCEV *S = IU->getReplacementExpr(UI);
const SCEV *X = SE->getSCEV(ICmp->getOperand(!Swapped));
// Simplify unnecessary loops away.
const Loop *ICmpLoop = LI->getLoopFor(ICmp->getParent());
S = SE->getSCEVAtScope(S, ICmpLoop);
X = SE->getSCEVAtScope(X, ICmpLoop);
// If the condition is always true or always false, replace it with
// a constant value.
if (SE->isKnownPredicate(Pred, S, X))
ICmp->replaceAllUsesWith(ConstantInt::getTrue(ICmp->getContext()));
else if (SE->isKnownPredicate(ICmpInst::getInversePredicate(Pred), S, X))
ICmp->replaceAllUsesWith(ConstantInt::getFalse(ICmp->getContext()));
else
continue;
DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n');
ICmp->eraseFromParent();
}
}
bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
IU = &getAnalysis<IVUsers>();
LI = &getAnalysis<LoopInfo>();
@@ -362,6 +397,9 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount))
RewriteLoopExitValues(L, Rewriter);
// Simplify ICmp IV users.
EliminateIVComparisons();
// Compute the type of the largest recurrence expression, and decide whether
// a canonical induction variable should be inserted.
const Type *LargestType = 0;