mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-27 12:26:08 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73706 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -35,9 +35,9 @@ class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
|
|||||||
public:
|
public:
|
||||||
IVStrideUse(IVUsersOfOneStride *parent,
|
IVStrideUse(IVUsersOfOneStride *parent,
|
||||||
const SCEVHandle &offset,
|
const SCEVHandle &offset,
|
||||||
Instruction* U, Value *O, bool issigned)
|
Instruction* U, Value *O)
|
||||||
: CallbackVH(U), Parent(parent), Offset(offset),
|
: CallbackVH(U), Parent(parent), Offset(offset),
|
||||||
OperandValToReplace(O), IsSigned(issigned),
|
OperandValToReplace(O),
|
||||||
IsUseOfPostIncrementedValue(false) {
|
IsUseOfPostIncrementedValue(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,8 +57,7 @@ public:
|
|||||||
|
|
||||||
/// getOffset - Return the offset to add to a theoeretical induction
|
/// getOffset - Return the offset to add to a theoeretical induction
|
||||||
/// variable that starts at zero and counts up by the stride to compute
|
/// 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,
|
/// 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.
|
|
||||||
SCEVHandle getOffset() const { return Offset; }
|
SCEVHandle getOffset() const { return Offset; }
|
||||||
|
|
||||||
/// setOffset - Assign a new offset to this use.
|
/// setOffset - Assign a new offset to this use.
|
||||||
@@ -78,13 +77,6 @@ public:
|
|||||||
OperandValToReplace = Op;
|
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
|
/// isUseOfPostIncrementedValue - True if this should use the
|
||||||
/// post-incremented version of this IV, not the preincremented version.
|
/// post-incremented version of this IV, not the preincremented version.
|
||||||
/// This can only be set in special cases, such as the terminating setcc
|
/// This can only be set in special cases, such as the terminating setcc
|
||||||
@@ -110,10 +102,6 @@ private:
|
|||||||
/// that this IVStrideUse is representing.
|
/// that this IVStrideUse is representing.
|
||||||
WeakVH OperandValToReplace;
|
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
|
/// IsUseOfPostIncrementedValue - True if this should use the
|
||||||
/// post-incremented version of this IV, not the preincremented version.
|
/// post-incremented version of this IV, not the preincremented version.
|
||||||
bool IsUseOfPostIncrementedValue;
|
bool IsUseOfPostIncrementedValue;
|
||||||
@@ -170,9 +158,8 @@ public:
|
|||||||
/// initial value and the operand that uses the IV.
|
/// initial value and the operand that uses the IV.
|
||||||
ilist<IVStrideUse> Users;
|
ilist<IVStrideUse> Users;
|
||||||
|
|
||||||
void addUser(const SCEVHandle &Offset,Instruction *User, Value *Operand,
|
void addUser(const SCEVHandle &Offset, Instruction *User, Value *Operand) {
|
||||||
bool isSigned) {
|
Users.push_back(new IVStrideUse(this, Offset, User, Operand));
|
||||||
Users.push_back(new IVStrideUse(this, Offset, User, Operand, isSigned));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -82,11 +82,8 @@ static bool containsAddRecFromDifferentLoop(SCEVHandle S, Loop *L) {
|
|||||||
/// outer loop of the current loop.
|
/// outer loop of the current loop.
|
||||||
static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L, Loop *UseLoop,
|
static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L, Loop *UseLoop,
|
||||||
SCEVHandle &Start, SCEVHandle &Stride,
|
SCEVHandle &Start, SCEVHandle &Stride,
|
||||||
bool &isSigned,
|
|
||||||
ScalarEvolution *SE, DominatorTree *DT) {
|
ScalarEvolution *SE, DominatorTree *DT) {
|
||||||
SCEVHandle TheAddRec = Start; // Initialize to zero.
|
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
|
// If the outer level is an AddExpr, the operands are all start values except
|
||||||
// for a nested AddRecExpr.
|
// for a nested AddRecExpr.
|
||||||
@@ -101,13 +98,6 @@ static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L, Loop *UseLoop,
|
|||||||
} else {
|
} else {
|
||||||
Start = SE->getAddExpr(Start, AE->getOperand(i));
|
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)) {
|
} else if (isa<SCEVAddRecExpr>(SH)) {
|
||||||
TheAddRec = SH;
|
TheAddRec = SH;
|
||||||
} else {
|
} else {
|
||||||
@@ -131,9 +121,6 @@ static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L, Loop *UseLoop,
|
|||||||
if (containsAddRecFromDifferentLoop(AddRecStart, L))
|
if (containsAddRecFromDifferentLoop(AddRecStart, L))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (isSExt || isZExt)
|
|
||||||
Start = SE->getTruncateExpr(Start, AddRec->getType());
|
|
||||||
|
|
||||||
Start = SE->getAddExpr(Start, AddRecStart);
|
Start = SE->getAddExpr(Start, AddRecStart);
|
||||||
|
|
||||||
// If stride is an instruction, make sure it dominates the loop preheader.
|
// 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;
|
Stride = AddRecStride;
|
||||||
isSigned = isSExt;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,9 +204,8 @@ bool IVUsers::AddUsersIfInteresting(Instruction *I) {
|
|||||||
Loop *UseLoop = LI->getLoopFor(I->getParent());
|
Loop *UseLoop = LI->getLoopFor(I->getParent());
|
||||||
SCEVHandle Start = SE->getIntegerSCEV(0, ISE->getType());
|
SCEVHandle Start = SE->getIntegerSCEV(0, ISE->getType());
|
||||||
SCEVHandle Stride = Start;
|
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.
|
return false; // Non-reducible symbolic expression, bail out.
|
||||||
|
|
||||||
SmallPtrSet<Instruction *, 4> UniqueUsers;
|
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
|
// The value used will be incremented by the stride more than we are
|
||||||
// expecting, so subtract this off.
|
// expecting, so subtract this off.
|
||||||
SCEVHandle NewStart = SE->getMinusSCEV(Start, Stride);
|
SCEVHandle NewStart = SE->getMinusSCEV(Start, Stride);
|
||||||
StrideUses->addUser(NewStart, User, I, isSigned);
|
StrideUses->addUser(NewStart, User, I);
|
||||||
StrideUses->Users.back().setIsUseOfPostIncrementedValue(true);
|
StrideUses->Users.back().setIsUseOfPostIncrementedValue(true);
|
||||||
DOUT << " USING POSTINC SCEV, START=" << *NewStart<< "\n";
|
DOUT << " USING POSTINC SCEV, START=" << *NewStart<< "\n";
|
||||||
} else {
|
} 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
|
/// getReplacementExpr - Return a SCEV expression which computes the
|
||||||
/// value of the OperandValToReplace of the given IVStrideUse.
|
/// value of the OperandValToReplace of the given IVStrideUse.
|
||||||
SCEVHandle IVUsers::getReplacementExpr(const IVStrideUse &U) const {
|
SCEVHandle IVUsers::getReplacementExpr(const IVStrideUse &U) const {
|
||||||
const Type *UseTy = U.getOperandValToReplace()->getType();
|
|
||||||
// Start with zero.
|
// Start with zero.
|
||||||
SCEVHandle RetVal = SE->getIntegerSCEV(0, U.getParent()->Stride->getType());
|
SCEVHandle RetVal = SE->getIntegerSCEV(0, U.getParent()->Stride->getType());
|
||||||
// Create the basic add recurrence.
|
// Create the basic add recurrence.
|
||||||
@@ -329,14 +313,6 @@ SCEVHandle IVUsers::getReplacementExpr(const IVStrideUse &U) const {
|
|||||||
if (ExitVal->isLoopInvariant(L))
|
if (ExitVal->isLoopInvariant(L))
|
||||||
RetVal = ExitVal;
|
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;
|
return RetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -336,13 +336,6 @@ namespace {
|
|||||||
/// EmittedBase.
|
/// EmittedBase.
|
||||||
Value *OperandValToReplace;
|
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
|
/// 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
|
/// before Inst, because it will be folded into the imm field of the
|
||||||
/// instruction. This is also sometimes used for loop-variant values that
|
/// instruction. This is also sometimes used for loop-variant values that
|
||||||
@@ -363,7 +356,6 @@ namespace {
|
|||||||
BasedUser(IVStrideUse &IVSU, ScalarEvolution *se)
|
BasedUser(IVStrideUse &IVSU, ScalarEvolution *se)
|
||||||
: SE(se), Base(IVSU.getOffset()), Inst(IVSU.getUser()),
|
: SE(se), Base(IVSU.getOffset()), Inst(IVSU.getUser()),
|
||||||
OperandValToReplace(IVSU.getOperandValToReplace()),
|
OperandValToReplace(IVSU.getOperandValToReplace()),
|
||||||
isSigned(IVSU.isSigned()),
|
|
||||||
Imm(SE->getIntegerSCEV(0, Base->getType())),
|
Imm(SE->getIntegerSCEV(0, Base->getType())),
|
||||||
isUseOfPostIncrementedValue(IVSU.isUseOfPostIncrementedValue()) {}
|
isUseOfPostIncrementedValue(IVSU.isUseOfPostIncrementedValue()) {}
|
||||||
|
|
||||||
@@ -428,11 +420,6 @@ Value *BasedUser::InsertCodeForBaseAtPosition(const SCEVHandle &NewBase,
|
|||||||
NewValSCEV = SE->getAddExpr(NewValSCEV, Imm);
|
NewValSCEV = SE->getAddExpr(NewValSCEV, Imm);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSigned)
|
|
||||||
NewValSCEV = SE->getTruncateOrSignExtend(NewValSCEV, Ty);
|
|
||||||
else
|
|
||||||
NewValSCEV = SE->getTruncateOrZeroExtend(NewValSCEV, Ty);
|
|
||||||
|
|
||||||
return Rewriter.expandCodeFor(NewValSCEV, Ty, IP);
|
return Rewriter.expandCodeFor(NewValSCEV, Ty, IP);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2047,7 +2034,7 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
|||||||
OldCond->replaceAllUsesWith(Cond);
|
OldCond->replaceAllUsesWith(Cond);
|
||||||
OldCond->eraseFromParent();
|
OldCond->eraseFromParent();
|
||||||
|
|
||||||
IU->IVUsesByStride[*NewStride]->addUser(NewOffset, Cond, NewCmpLHS, false);
|
IU->IVUsesByStride[*NewStride]->addUser(NewOffset, Cond, NewCmpLHS);
|
||||||
CondUse = &IU->IVUsesByStride[*NewStride]->Users.back();
|
CondUse = &IU->IVUsesByStride[*NewStride]->Users.back();
|
||||||
CondStride = NewStride;
|
CondStride = NewStride;
|
||||||
++NumEliminated;
|
++NumEliminated;
|
||||||
@@ -2397,8 +2384,7 @@ void LoopStrengthReduce::OptimizeLoopTermCond(Loop *L) {
|
|||||||
|
|
||||||
// Clone the IVUse, as the old use still exists!
|
// Clone the IVUse, as the old use still exists!
|
||||||
IU->IVUsesByStride[*CondStride]->addUser(CondUse->getOffset(), Cond,
|
IU->IVUsesByStride[*CondStride]->addUser(CondUse->getOffset(), Cond,
|
||||||
CondUse->getOperandValToReplace(),
|
CondUse->getOperandValToReplace());
|
||||||
false);
|
|
||||||
CondUse = &IU->IVUsesByStride[*CondStride]->Users.back();
|
CondUse = &IU->IVUsesByStride[*CondStride]->Users.back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
; RUN: llvm-as < %s | llc -march=x86-64 -f -o %t
|
; RUN: llvm-as < %s | llc -march=x86-64 -f -o %t
|
||||||
; RUN: grep inc %t | count 1
|
; RUN: grep inc %t | count 1
|
||||||
; RUN: grep dec %t | count 2
|
; RUN: grep dec %t | count 2
|
||||||
; RUN: grep addq %t | count 8
|
; RUN: grep addq %t | count 13
|
||||||
; RUN: grep addb %t | count 2
|
; RUN: not grep addb %t
|
||||||
; RUN: grep leaq %t | count 12
|
; RUN: grep leaq %t | count 8
|
||||||
; RUN: grep leal %t | count 2
|
; RUN: grep leal %t | count 4
|
||||||
; RUN: grep movq %t | count 4
|
; RUN: grep movq %t | count 5
|
||||||
|
|
||||||
; IV users in each of the loops from other loops shouldn't cause LSR
|
; IV users in each of the loops from other loops shouldn't cause LSR
|
||||||
; to insert new induction variables. Previously it would create a
|
; 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),
|
; Indvars should do the IV arithmetic in the canonical IV type (i64),
|
||||||
; and only use one truncation.
|
; 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 {
|
define fastcc void @foo() nounwind {
|
||||||
entry:
|
entry:
|
||||||
|
Reference in New Issue
Block a user