summaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/IndVarSimplify.cpp
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2011-05-12 00:04:28 +0000
committerAndrew Trick <atrick@apple.com>2011-05-12 00:04:28 +0000
commitaeee4616dd12d58fd8d040ab00277747f0312321 (patch)
tree7c38455951ff267fc06afd72bbc8d5a0057fbe6c /lib/Transforms/Scalar/IndVarSimplify.cpp
parent6dcd413fbb488222200c6b42c4f5d55ce39db557 (diff)
downloadllvm-aeee4616dd12d58fd8d040ab00277747f0312321.tar.gz
llvm-aeee4616dd12d58fd8d040ab00277747f0312321.tar.bz2
llvm-aeee4616dd12d58fd8d040ab00277747f0312321.tar.xz
indvars: Added SimplifyIVUsers.
Interleave IV simplifications. Currently involves EliminateComparison and EliminateRemainder. Next I'll add EliminateExtend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131210 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/IndVarSimplify.cpp')
-rw-r--r--lib/Transforms/Scalar/IndVarSimplify.cpp184
1 files changed, 99 insertions, 85 deletions
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp
index a0e8b6e458..ab9e21a9ec 100644
--- a/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -109,8 +109,11 @@ namespace {
private:
bool isValidRewrite(Value *FromVal, Value *ToVal);
- void EliminateIVComparisons();
- void EliminateIVRemainders();
+ void SimplifyIVUsers();
+ void EliminateIVComparison(ICmpInst *ICmp, Value *IVOperand);
+ void EliminateIVRemainder(BinaryOperator *Rem,
+ Value *IVOperand,
+ bool isSigned);
void RewriteNonIntegerIVs(Loop *L);
const Type *WidenIVs(Loop *L, SCEVExpander &Rewriter);
@@ -451,96 +454,111 @@ void IndVarSimplify::RewriteNonIntegerIVs(Loop *L) {
SE->forgetLoop(L);
}
-void IndVarSimplify::EliminateIVComparisons() {
- // Look for ICmp users.
+/// SimplifyIVUsers - Iteratively perform simplification on IVUsers within this
+/// loop. IVUsers is treated as a worklist. Each successive simplification may
+/// push more users which may themselves be candidates for simplification.
+void IndVarSimplify::SimplifyIVUsers() {
for (IVUsers::iterator I = IU->begin(), E = IU->end(); I != E; ++I) {
- 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
+ Instruction *UseInst = I->getUser();
+ Value *IVOperand = I->getOperandValToReplace();
+
+ if (ICmpInst *ICmp = dyn_cast<ICmpInst>(UseInst)) {
+ EliminateIVComparison(ICmp, IVOperand);
continue;
+ }
- DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n');
- DeadInsts.push_back(ICmp);
+ if (BinaryOperator *Rem = dyn_cast<BinaryOperator>(UseInst)) {
+ bool isSigned = Rem->getOpcode() == Instruction::SRem;
+ if (isSigned || Rem->getOpcode() == Instruction::URem) {
+ EliminateIVRemainder(Rem, IVOperand, isSigned);
+ continue;
+ }
+ }
}
}
-void IndVarSimplify::EliminateIVRemainders() {
- // Look for SRem and URem users.
- for (IVUsers::iterator I = IU->begin(), E = IU->end(); I != E; ++I) {
- IVStrideUse &UI = *I;
- BinaryOperator *Rem = dyn_cast<BinaryOperator>(UI.getUser());
- if (!Rem) continue;
+void IndVarSimplify::EliminateIVComparison(ICmpInst *ICmp, Value *IVOperand) {
+ unsigned IVOperIdx = 0;
+ ICmpInst::Predicate Pred = ICmp->getPredicate();
+ if (IVOperand != ICmp->getOperand(0)) {
+ // Swapped
+ assert(IVOperand == ICmp->getOperand(1) && "Can't find IVOperand");
+ IVOperIdx = 1;
+ Pred = ICmpInst::getSwappedPredicate(Pred);
+ }
- bool isSigned = Rem->getOpcode() == Instruction::SRem;
- if (!isSigned && Rem->getOpcode() != Instruction::URem)
- continue;
+ // Get the SCEVs for the ICmp operands.
+ const SCEV *S = SE->getSCEV(ICmp->getOperand(IVOperIdx));
+ const SCEV *X = SE->getSCEV(ICmp->getOperand(1 - IVOperIdx));
+
+ // 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
+ return;
- // We're only interested in the case where we know something about
- // the numerator.
- if (UI.getOperandValToReplace() != Rem->getOperand(0))
- continue;
+ DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n');
+ DeadInsts.push_back(ICmp);
+}
- // Get the SCEVs for the ICmp operands.
- const SCEV *S = SE->getSCEV(Rem->getOperand(0));
- const SCEV *X = SE->getSCEV(Rem->getOperand(1));
-
- // Simplify unnecessary loops away.
- const Loop *ICmpLoop = LI->getLoopFor(Rem->getParent());
- S = SE->getSCEVAtScope(S, ICmpLoop);
- X = SE->getSCEVAtScope(X, ICmpLoop);
-
- // i % n --> i if i is in [0,n).
- if ((!isSigned || SE->isKnownNonNegative(S)) &&
- SE->isKnownPredicate(isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT,
- S, X))
- Rem->replaceAllUsesWith(Rem->getOperand(0));
- else {
- // (i+1) % n --> (i+1)==n?0:(i+1) if i is in [0,n).
- const SCEV *LessOne =
- SE->getMinusSCEV(S, SE->getConstant(S->getType(), 1));
- if ((!isSigned || SE->isKnownNonNegative(LessOne)) &&
- SE->isKnownPredicate(isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT,
- LessOne, X)) {
- ICmpInst *ICmp = new ICmpInst(Rem, ICmpInst::ICMP_EQ,
- Rem->getOperand(0), Rem->getOperand(1),
- "tmp");
- SelectInst *Sel =
- SelectInst::Create(ICmp,
- ConstantInt::get(Rem->getType(), 0),
- Rem->getOperand(0), "tmp", Rem);
- Rem->replaceAllUsesWith(Sel);
- } else
- continue;
- }
+void IndVarSimplify::EliminateIVRemainder(BinaryOperator *Rem,
+ Value *IVOperand,
+ bool isSigned) {
+ // We're only interested in the case where we know something about
+ // the numerator.
+ if (IVOperand != Rem->getOperand(0))
+ return;
+
+ // Get the SCEVs for the ICmp operands.
+ const SCEV *S = SE->getSCEV(Rem->getOperand(0));
+ const SCEV *X = SE->getSCEV(Rem->getOperand(1));
+
+ // Simplify unnecessary loops away.
+ const Loop *ICmpLoop = LI->getLoopFor(Rem->getParent());
+ S = SE->getSCEVAtScope(S, ICmpLoop);
+ X = SE->getSCEVAtScope(X, ICmpLoop);
+
+ // i % n --> i if i is in [0,n).
+ if ((!isSigned || SE->isKnownNonNegative(S)) &&
+ SE->isKnownPredicate(isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT,
+ S, X))
+ Rem->replaceAllUsesWith(Rem->getOperand(0));
+ else {
+ // (i+1) % n --> (i+1)==n?0:(i+1) if i is in [0,n).
+ const SCEV *LessOne =
+ SE->getMinusSCEV(S, SE->getConstant(S->getType(), 1));
+ if (isSigned && !SE->isKnownNonNegative(LessOne))
+ return;
- // Inform IVUsers about the new users.
- if (Instruction *I = dyn_cast<Instruction>(Rem->getOperand(0)))
- IU->AddUsersIfInteresting(I);
+ if (!SE->isKnownPredicate(isSigned ?
+ ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT,
+ LessOne, X))
+ return;
- DEBUG(dbgs() << "INDVARS: Simplified rem: " << *Rem << '\n');
- DeadInsts.push_back(Rem);
+ ICmpInst *ICmp = new ICmpInst(Rem, ICmpInst::ICMP_EQ,
+ Rem->getOperand(0), Rem->getOperand(1),
+ "tmp");
+ SelectInst *Sel =
+ SelectInst::Create(ICmp,
+ ConstantInt::get(Rem->getType(), 0),
+ Rem->getOperand(0), "tmp", Rem);
+ Rem->replaceAllUsesWith(Sel);
}
+
+ // Inform IVUsers about the new users.
+ if (Instruction *I = dyn_cast<Instruction>(Rem->getOperand(0)))
+ IU->AddUsersIfInteresting(I);
+
+ DEBUG(dbgs() << "INDVARS: Simplified rem: " << *Rem << '\n');
+ DeadInsts.push_back(Rem);
}
bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
@@ -589,11 +607,7 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount))
RewriteLoopExitValues(L, Rewriter);
- // Simplify ICmp IV users.
- EliminateIVComparisons();
-
- // Simplify SRem and URem IV users.
- EliminateIVRemainders();
+ SimplifyIVUsers();
// Compute the type of the largest recurrence expression, and decide whether
// a canonical induction variable should be inserted.