Remove the code from IVUsers that attempted to handle

casted induction variables in cases where the cast
isn't foldable. It ended up being a pessimization in
many cases. This could be fixed, but it would require
a bunch of complicated code in IVUsers' clients. The
advantages of this approach aren't visible enough to
justify it at this time.

llvm-svn: 73706
This commit is contained in:
Dan Gohman 2009-06-18 16:54:06 +00:00
parent 56bd02c55c
commit a0348809b6
6 changed files with 20 additions and 68 deletions

View File

@ -35,9 +35,9 @@ class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
public:
IVStrideUse(IVUsersOfOneStride *parent,
const SCEVHandle &offset,
Instruction* U, Value *O, bool issigned)
Instruction* U, Value *O)
: CallbackVH(U), Parent(parent), Offset(offset),
OperandValToReplace(O), IsSigned(issigned),
OperandValToReplace(O),
IsUseOfPostIncrementedValue(false) {
}
@ -57,8 +57,7 @@ public:
/// getOffset - Return the offset to add to a theoeretical induction
/// variable that starts at zero and counts up by the stride to compute
/// the value for the use. This always has the same type as the stride,
/// which may need to be casted to match the type of the use.
/// the value for the use. This always has the same type as the stride.
SCEVHandle getOffset() const { return Offset; }
/// setOffset - Assign a new offset to this use.
@ -78,13 +77,6 @@ public:
OperandValToReplace = Op;
}
/// isSigned - The stride (and thus also the Offset) of this use may be in
/// a narrower type than the use itself (OperandValToReplace->getType()).
/// When this is the case, isSigned() indicates whether the IV expression
/// should be signed-extended instead of zero-extended to fit the type of
/// the use.
bool isSigned() const { return IsSigned; }
/// isUseOfPostIncrementedValue - True if this should use the
/// post-incremented version of this IV, not the preincremented version.
/// This can only be set in special cases, such as the terminating setcc
@ -110,10 +102,6 @@ private:
/// that this IVStrideUse is representing.
WeakVH OperandValToReplace;
/// IsSigned - Determines whether the replacement value is sign or
/// zero extended to the type of the use.
bool IsSigned;
/// IsUseOfPostIncrementedValue - True if this should use the
/// post-incremented version of this IV, not the preincremented version.
bool IsUseOfPostIncrementedValue;
@ -170,9 +158,8 @@ public:
/// initial value and the operand that uses the IV.
ilist<IVStrideUse> Users;
void addUser(const SCEVHandle &Offset,Instruction *User, Value *Operand,
bool isSigned) {
Users.push_back(new IVStrideUse(this, Offset, User, Operand, isSigned));
void addUser(const SCEVHandle &Offset, Instruction *User, Value *Operand) {
Users.push_back(new IVStrideUse(this, Offset, User, Operand));
}
};

View File

@ -82,11 +82,8 @@ static bool containsAddRecFromDifferentLoop(SCEVHandle S, Loop *L) {
/// outer loop of the current loop.
static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L, Loop *UseLoop,
SCEVHandle &Start, SCEVHandle &Stride,
bool &isSigned,
ScalarEvolution *SE, DominatorTree *DT) {
SCEVHandle TheAddRec = Start; // Initialize to zero.
bool isSExt = false;
bool isZExt = false;
// If the outer level is an AddExpr, the operands are all start values except
// for a nested AddRecExpr.
@ -101,13 +98,6 @@ static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L, Loop *UseLoop,
} else {
Start = SE->getAddExpr(Start, AE->getOperand(i));
}
} else if (const SCEVZeroExtendExpr *Z = dyn_cast<SCEVZeroExtendExpr>(SH)) {
TheAddRec = Z->getOperand();
isZExt = true;
} else if (const SCEVSignExtendExpr *S = dyn_cast<SCEVSignExtendExpr>(SH)) {
TheAddRec = S->getOperand();
isSExt = true;
} else if (isa<SCEVAddRecExpr>(SH)) {
TheAddRec = SH;
} else {
@ -131,9 +121,6 @@ static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L, Loop *UseLoop,
if (containsAddRecFromDifferentLoop(AddRecStart, L))
return false;
if (isSExt || isZExt)
Start = SE->getTruncateExpr(Start, AddRec->getType());
Start = SE->getAddExpr(Start, AddRecStart);
// If stride is an instruction, make sure it dominates the loop preheader.
@ -148,7 +135,6 @@ static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L, Loop *UseLoop,
}
Stride = AddRecStride;
isSigned = isSExt;
return true;
}
@ -218,9 +204,8 @@ bool IVUsers::AddUsersIfInteresting(Instruction *I) {
Loop *UseLoop = LI->getLoopFor(I->getParent());
SCEVHandle Start = SE->getIntegerSCEV(0, ISE->getType());
SCEVHandle Stride = Start;
bool isSigned = false; // Arbitrary initial value - pacifies compiler.
if (!getSCEVStartAndStride(ISE, L, UseLoop, Start, Stride, isSigned, SE, DT))
if (!getSCEVStartAndStride(ISE, L, UseLoop, Start, Stride, SE, DT))
return false; // Non-reducible symbolic expression, bail out.
SmallPtrSet<Instruction *, 4> UniqueUsers;
@ -271,11 +256,11 @@ bool IVUsers::AddUsersIfInteresting(Instruction *I) {
// The value used will be incremented by the stride more than we are
// expecting, so subtract this off.
SCEVHandle NewStart = SE->getMinusSCEV(Start, Stride);
StrideUses->addUser(NewStart, User, I, isSigned);
StrideUses->addUser(NewStart, User, I);
StrideUses->Users.back().setIsUseOfPostIncrementedValue(true);
DOUT << " USING POSTINC SCEV, START=" << *NewStart<< "\n";
} else {
StrideUses->addUser(Start, User, I, isSigned);
StrideUses->addUser(Start, User, I);
}
}
}
@ -312,7 +297,6 @@ bool IVUsers::runOnLoop(Loop *l, LPPassManager &LPM) {
/// getReplacementExpr - Return a SCEV expression which computes the
/// value of the OperandValToReplace of the given IVStrideUse.
SCEVHandle IVUsers::getReplacementExpr(const IVStrideUse &U) const {
const Type *UseTy = U.getOperandValToReplace()->getType();
// Start with zero.
SCEVHandle RetVal = SE->getIntegerSCEV(0, U.getParent()->Stride->getType());
// Create the basic add recurrence.
@ -329,14 +313,6 @@ SCEVHandle IVUsers::getReplacementExpr(const IVStrideUse &U) const {
if (ExitVal->isLoopInvariant(L))
RetVal = ExitVal;
}
// Promote the result to the type of the use.
if (SE->getTypeSizeInBits(RetVal->getType()) !=
SE->getTypeSizeInBits(UseTy)) {
if (U.isSigned())
RetVal = SE->getSignExtendExpr(RetVal, UseTy);
else
RetVal = SE->getZeroExtendExpr(RetVal, UseTy);
}
return RetVal;
}

View File

@ -336,13 +336,6 @@ namespace {
/// EmittedBase.
Value *OperandValToReplace;
/// isSigned - The stride (and thus also the Base) of this use may be in
/// a narrower type than the use itself (OperandValToReplace->getType()).
/// When this is the case, the isSigned field indicates whether the
/// IV expression should be signed-extended instead of zero-extended to
/// fit the type of the use.
bool isSigned;
/// Imm - The immediate value that should be added to the base immediately
/// before Inst, because it will be folded into the imm field of the
/// instruction. This is also sometimes used for loop-variant values that
@ -363,7 +356,6 @@ namespace {
BasedUser(IVStrideUse &IVSU, ScalarEvolution *se)
: SE(se), Base(IVSU.getOffset()), Inst(IVSU.getUser()),
OperandValToReplace(IVSU.getOperandValToReplace()),
isSigned(IVSU.isSigned()),
Imm(SE->getIntegerSCEV(0, Base->getType())),
isUseOfPostIncrementedValue(IVSU.isUseOfPostIncrementedValue()) {}
@ -428,11 +420,6 @@ Value *BasedUser::InsertCodeForBaseAtPosition(const SCEVHandle &NewBase,
NewValSCEV = SE->getAddExpr(NewValSCEV, Imm);
}
if (isSigned)
NewValSCEV = SE->getTruncateOrSignExtend(NewValSCEV, Ty);
else
NewValSCEV = SE->getTruncateOrZeroExtend(NewValSCEV, Ty);
return Rewriter.expandCodeFor(NewValSCEV, Ty, IP);
}
@ -2047,7 +2034,7 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
OldCond->replaceAllUsesWith(Cond);
OldCond->eraseFromParent();
IU->IVUsesByStride[*NewStride]->addUser(NewOffset, Cond, NewCmpLHS, false);
IU->IVUsesByStride[*NewStride]->addUser(NewOffset, Cond, NewCmpLHS);
CondUse = &IU->IVUsesByStride[*NewStride]->Users.back();
CondStride = NewStride;
++NumEliminated;
@ -2397,8 +2384,7 @@ void LoopStrengthReduce::OptimizeLoopTermCond(Loop *L) {
// Clone the IVUse, as the old use still exists!
IU->IVUsesByStride[*CondStride]->addUser(CondUse->getOffset(), Cond,
CondUse->getOperandValToReplace(),
false);
CondUse->getOperandValToReplace());
CondUse = &IU->IVUsesByStride[*CondStride]->Users.back();
}
}

View File

@ -1,11 +1,11 @@
; RUN: llvm-as < %s | llc -march=x86-64 -f -o %t
; RUN: grep inc %t | count 1
; RUN: grep dec %t | count 2
; RUN: grep addq %t | count 8
; RUN: grep addb %t | count 2
; RUN: grep leaq %t | count 12
; RUN: grep leal %t | count 2
; RUN: grep movq %t | count 4
; RUN: grep addq %t | count 13
; RUN: not grep addb %t
; RUN: grep leaq %t | count 8
; RUN: grep leal %t | count 4
; RUN: grep movq %t | count 5
; IV users in each of the loops from other loops shouldn't cause LSR
; to insert new induction variables. Previously it would create a

View File

@ -1,4 +1,6 @@
; RUN: llvm-as < %s | opt -indvars | llvm-dis | grep trunc | count 1
; RUN: llvm-as < %s | opt -indvars | llvm-dis > %t
; RUN: not grep trunc %t
; RUN: grep and %t | count 1
; Indvars should do the IV arithmetic in the canonical IV type (i64),
; and only use one truncation.

View File

@ -1,4 +1,5 @@
; RUN: llvm-as < %s | opt -iv-users -analyze -disable-output | grep store
; RUN: llvm-as < %s | opt -scalar-evolution -analyze -disable-output \
; RUN: | grep {\\--> (zext i4 {-7,+,-8}<loop> to i32)}
define fastcc void @foo() nounwind {
entry: