forked from OSchip/llvm-project
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:
parent
56bd02c55c
commit
a0348809b6
|
@ -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));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue