aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/ScalarEvolutionExpander.cpp27
1 files changed, 26 insertions, 1 deletions
diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp
index b153c6f..e2a98d4 100644
--- a/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -87,9 +87,34 @@ Value *SCEVExpander::visitAddRecExpr(SCEVAddRecExpr *S) {
// Get the canonical induction variable I for this loop.
Value *I = getOrInsertCanonicalInductionVariable(L, Ty);
+ // If this is a simple linear addrec, emit it now as a special case.
if (S->getNumOperands() == 2) { // {0,+,F} --> i*F
Value *F = expandInTy(S->getOperand(1), Ty);
- return BinaryOperator::createMul(I, F, "tmp.", InsertPt);
+
+ // IF the step is by one, just return the inserted IV.
+ if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(F))
+ if (CI->getRawValue() == 1)
+ return I;
+
+ // If the insert point is directly inside of the loop, emit the multiply at
+ // the insert point. Otherwise, L is a loop that is a parent of the insert
+ // point loop. If we can, move the multiply to the outer most loop that it
+ // is safe to be in.
+ Instruction *MulInsertPt = InsertPt;
+ Loop *InsertPtLoop = LI.getLoopFor(MulInsertPt->getParent());
+ if (InsertPtLoop != L && InsertPtLoop &&
+ L->contains(InsertPtLoop->getHeader())) {
+ while (InsertPtLoop != L) {
+ // If we cannot hoist the multiply out of this loop, don't.
+ if (!InsertPtLoop->isLoopInvariant(F)) break;
+
+ // Otherwise, move the insert point to the preheader of the loop.
+ MulInsertPt = InsertPtLoop->getLoopPreheader()->getTerminator();
+ InsertPtLoop = InsertPtLoop->getParentLoop();
+ }
+ }
+
+ return BinaryOperator::createMul(I, F, "tmp.", MulInsertPt);
}
// If this is a chain of recurrences, turn it into a closed form, using the