aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/IndVarSimplify.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-06-24 01:18:18 +0000
committerDan Gohman <gohman@apple.com>2009-06-24 01:18:18 +0000
commit40a5a1b39ee1cd40ff9d04740386b667fb27b340 (patch)
tree0e7c7275525d07b2805e5da9b929fb820a2fd24b /lib/Transforms/Scalar/IndVarSimplify.cpp
parentb825aaa0289206a63f7e6ce7b5ca7c2d6a2c063e (diff)
Extend ScalarEvolution's multiple-exit support to compute exact
trip counts in more cases. Generalize ScalarEvolution's isLoopGuardedByCond code to recognize And and Or conditions, splitting the code out into an isNecessaryCond helper function so that it can evaluate Ands and Ors recursively, and make SCEVExpander be much more aggressive about hoisting instructions out of loops. test/CodeGen/X86/pr3495.ll has an additional instruction now, but it appears to be due to an arbitrary register allocation difference. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74048 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/IndVarSimplify.cpp')
-rw-r--r--lib/Transforms/Scalar/IndVarSimplify.cpp46
1 files changed, 19 insertions, 27 deletions
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp
index 6c20e7d140..658b788e0b 100644
--- a/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -104,7 +104,8 @@ namespace {
void RewriteLoopExitValues(Loop *L, const SCEV *BackedgeTakenCount);
void RewriteIVExpressions(Loop *L, const Type *LargestType,
- SCEVExpander &Rewriter);
+ SCEVExpander &Rewriter,
+ BasicBlock::iterator InsertPt);
void SinkUnusedInvariants(Loop *L, SCEVExpander &Rewriter);
@@ -170,6 +171,8 @@ ICmpInst *IndVarSimplify::LinearFunctionTestReplace(Loop *L,
}
// Expand the code for the iteration count into the preheader of the loop.
+ assert(RHS->isLoopInvariant(L) &&
+ "Computed iteration count is not loop invariant!");
BasicBlock *Preheader = L->getLoopPreheader();
Value *ExitCnt = Rewriter.expandCodeFor(RHS, IndVar->getType(),
Preheader->getTerminator());
@@ -434,10 +437,10 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
ExitingBlock, BI, Rewriter);
}
- Rewriter.setInsertionPoint(Header->getFirstNonPHI());
+ BasicBlock::iterator InsertPt = Header->getFirstNonPHI();
// Rewrite IV-derived expressions. Clears the rewriter cache.
- RewriteIVExpressions(L, LargestType, Rewriter);
+ RewriteIVExpressions(L, LargestType, Rewriter, InsertPt);
// The Rewriter may only be used for isInsertedInstruction queries from this
// point on.
@@ -462,7 +465,8 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
}
void IndVarSimplify::RewriteIVExpressions(Loop *L, const Type *LargestType,
- SCEVExpander &Rewriter) {
+ SCEVExpander &Rewriter,
+ BasicBlock::iterator InsertPt) {
SmallVector<WeakVH, 16> DeadInsts;
// Rewrite all induction variable expressions in terms of the canonical
@@ -488,29 +492,17 @@ void IndVarSimplify::RewriteIVExpressions(Loop *L, const Type *LargestType,
// Compute the final addrec to expand into code.
const SCEV* AR = IU->getReplacementExpr(*UI);
- Value *NewVal = 0;
- if (AR->isLoopInvariant(L)) {
- BasicBlock::iterator I = Rewriter.getInsertionPoint();
- // Expand loop-invariant values in the loop preheader. They will
- // be sunk to the exit block later, if possible.
- NewVal =
- Rewriter.expandCodeFor(AR, UseTy,
- L->getLoopPreheader()->getTerminator());
- Rewriter.setInsertionPoint(I);
- ++NumReplaced;
- } else {
- // FIXME: It is an extremely bad idea to indvar substitute anything more
- // complex than affine induction variables. Doing so will put expensive
- // polynomial evaluations inside of the loop, and the str reduction pass
- // currently can only reduce affine polynomials. For now just disable
- // indvar subst on anything more complex than an affine addrec, unless
- // it can be expanded to a trivial value.
- if (!Stride->isLoopInvariant(L))
- continue;
-
- // Now expand it into actual Instructions and patch it into place.
- NewVal = Rewriter.expandCodeFor(AR, UseTy);
- }
+ // FIXME: It is an extremely bad idea to indvar substitute anything more
+ // complex than affine induction variables. Doing so will put expensive
+ // polynomial evaluations inside of the loop, and the str reduction pass
+ // currently can only reduce affine polynomials. For now just disable
+ // indvar subst on anything more complex than an affine addrec, unless
+ // it can be expanded to a trivial value.
+ if (!AR->isLoopInvariant(L) && !Stride->isLoopInvariant(L))
+ continue;
+
+ // Now expand it into actual Instructions and patch it into place.
+ Value *NewVal = Rewriter.expandCodeFor(AR, UseTy, InsertPt);
// Patch the new value into place.
if (Op->hasName())