aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/Scalar/LoopStrengthReduce.cpp24
1 files changed, 21 insertions, 3 deletions
diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 6d66d14ec9..dbd22d90e0 100644
--- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -543,6 +543,7 @@ namespace {
// operands of Inst to use the new expression 'NewBase', with 'Imm' added
// to it.
void RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
+ Instruction *InsertPt,
SCEVExpander &Rewriter, Loop *L, Pass *P,
SmallPtrSet<Instruction*,16> &DeadInsts);
@@ -603,8 +604,12 @@ Value *BasedUser::InsertCodeForBaseAtPosition(const SCEVHandle &NewBase,
// Once we rewrite the code to insert the new IVs we want, update the
// operands of Inst to use the new expression 'NewBase', with 'Imm' added
-// to it.
+// to it. NewBasePt is the last instruction which contributes to the
+// value of NewBase in the case that it's a diffferent instruction from
+// the PHI that NewBase is computed from, or null otherwise.
+//
void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
+ Instruction *NewBasePt,
SCEVExpander &Rewriter, Loop *L, Pass *P,
SmallPtrSet<Instruction*,16> &DeadInsts) {
if (!isa<PHINode>(Inst)) {
@@ -620,7 +625,10 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
// value will be pinned to live somewhere after the original computation.
// In this case, we have to back off.
if (!isUseOfPostIncrementedValue) {
- if (Instruction *OpInst = dyn_cast<Instruction>(OperandValToReplace)) {
+ if (NewBasePt) {
+ InsertPt = NewBasePt;
+ ++InsertPt;
+ } else if (Instruction *OpInst = dyn_cast<Instruction>(OperandValToReplace)) {
InsertPt = OpInst;
while (isa<PHINode>(InsertPt)) ++InsertPt;
}
@@ -1400,6 +1408,15 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
SCEVHandle RewriteExpr = SE->getUnknown(RewriteOp);
+ // If we had to insert new instrutions for RewriteOp, we have to
+ // consider that they may not have been able to end up immediately
+ // next to RewriteOp, because non-PHI instructions may never precede
+ // PHI instructions in a block. In this case, remember where the last
+ // instruction was inserted so that we can use that point to expand
+ // the final RewriteExpr.
+ Instruction *NewBasePt = dyn_cast<Instruction>(RewriteOp);
+ if (RewriteOp == NewPHI) NewBasePt = 0;
+
// Clear the SCEVExpander's expression map so that we are guaranteed
// to have the code emitted where we expect it.
Rewriter.clear();
@@ -1426,7 +1443,8 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
// Add BaseV to the PHI value if needed.
RewriteExpr = SE->getAddExpr(RewriteExpr, SE->getUnknown(BaseV));
- User.RewriteInstructionToUseNewBase(RewriteExpr, Rewriter, L, this,
+ User.RewriteInstructionToUseNewBase(RewriteExpr, NewBasePt,
+ Rewriter, L, this,
DeadInsts);
// Mark old value we replaced as possibly dead, so that it is elminated