mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-18 10:31:57 +00:00
Clarify that the scale factor from CheckForIVReuse
can be negative. Keep track of whether all uses of an IV are outside the loop. Some cosmetics; no functional change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61109 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fd3b7b7df3
commit
b0390620d4
@ -191,7 +191,7 @@ private:
|
|||||||
bool FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse,
|
bool FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse,
|
||||||
const SCEVHandle *&CondStride);
|
const SCEVHandle *&CondStride);
|
||||||
bool RequiresTypeConversion(const Type *Ty, const Type *NewTy);
|
bool RequiresTypeConversion(const Type *Ty, const Type *NewTy);
|
||||||
unsigned CheckForIVReuse(bool, bool, const SCEVHandle&,
|
int64_t CheckForIVReuse(bool, bool, bool, const SCEVHandle&,
|
||||||
IVExpr&, const Type*,
|
IVExpr&, const Type*,
|
||||||
const std::vector<BasedUser>& UsersToProcess);
|
const std::vector<BasedUser>& UsersToProcess);
|
||||||
bool ValidStride(bool, int64_t,
|
bool ValidStride(bool, int64_t,
|
||||||
@ -200,6 +200,7 @@ private:
|
|||||||
IVUsersOfOneStride &Uses,
|
IVUsersOfOneStride &Uses,
|
||||||
Loop *L,
|
Loop *L,
|
||||||
bool &AllUsesAreAddresses,
|
bool &AllUsesAreAddresses,
|
||||||
|
bool &AllUsesAreOutsideLoop,
|
||||||
std::vector<BasedUser> &UsersToProcess);
|
std::vector<BasedUser> &UsersToProcess);
|
||||||
void StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
void StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
||||||
IVUsersOfOneStride &Uses,
|
IVUsersOfOneStride &Uses,
|
||||||
@ -522,7 +523,7 @@ bool LoopStrengthReduce::AddUsersIfInteresting(Instruction *I, Loop *L,
|
|||||||
|
|
||||||
if (AddUserToIVUsers) {
|
if (AddUserToIVUsers) {
|
||||||
IVUsersOfOneStride &StrideUses = IVUsesByStride[Stride];
|
IVUsersOfOneStride &StrideUses = IVUsesByStride[Stride];
|
||||||
if (StrideUses.Users.empty()) // First occurance of this stride?
|
if (StrideUses.Users.empty()) // First occurrence of this stride?
|
||||||
StrideOrder.push_back(Stride);
|
StrideOrder.push_back(Stride);
|
||||||
|
|
||||||
// Okay, we found a user that we cannot reduce. Analyze the instruction
|
// Okay, we found a user that we cannot reduce. Analyze the instruction
|
||||||
@ -1060,7 +1061,7 @@ RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
|||||||
UseTy = SI->getOperand(0)->getType();
|
UseTy = SI->getOperand(0)->getType();
|
||||||
if (!fitsInAddressMode(FreeResult, UseTy, TLI, Result!=Zero)) {
|
if (!fitsInAddressMode(FreeResult, UseTy, TLI, Result!=Zero)) {
|
||||||
// FIXME: could split up FreeResult into pieces here, some hoisted
|
// FIXME: could split up FreeResult into pieces here, some hoisted
|
||||||
// and some not. Doesn't seem worth it for now.
|
// and some not. There is no obvious advantage to this.
|
||||||
Result = SE->getAddExpr(Result, FreeResult);
|
Result = SE->getAddExpr(Result, FreeResult);
|
||||||
FreeResult = Zero;
|
FreeResult = Zero;
|
||||||
break;
|
break;
|
||||||
@ -1166,9 +1167,10 @@ bool LoopStrengthReduce::RequiresTypeConversion(const Type *Ty1,
|
|||||||
/// of a previous stride and it is a legal value for the target addressing
|
/// of a previous stride and it is a legal value for the target addressing
|
||||||
/// mode scale component and optional base reg. This allows the users of
|
/// mode scale component and optional base reg. This allows the users of
|
||||||
/// this stride to be rewritten as prev iv * factor. It returns 0 if no
|
/// this stride to be rewritten as prev iv * factor. It returns 0 if no
|
||||||
/// reuse is possible.
|
/// reuse is possible. Factors can be negative on same targets, e.g. ARM.
|
||||||
unsigned LoopStrengthReduce::CheckForIVReuse(bool HasBaseReg,
|
int64_t LoopStrengthReduce::CheckForIVReuse(bool HasBaseReg,
|
||||||
bool AllUsesAreAddresses,
|
bool AllUsesAreAddresses,
|
||||||
|
bool AllUsesAreOutsideLoop,
|
||||||
const SCEVHandle &Stride,
|
const SCEVHandle &Stride,
|
||||||
IVExpr &IV, const Type *Ty,
|
IVExpr &IV, const Type *Ty,
|
||||||
const std::vector<BasedUser>& UsersToProcess) {
|
const std::vector<BasedUser>& UsersToProcess) {
|
||||||
@ -1236,6 +1238,7 @@ SCEVHandle LoopStrengthReduce::CollectIVUsers(const SCEVHandle &Stride,
|
|||||||
IVUsersOfOneStride &Uses,
|
IVUsersOfOneStride &Uses,
|
||||||
Loop *L,
|
Loop *L,
|
||||||
bool &AllUsesAreAddresses,
|
bool &AllUsesAreAddresses,
|
||||||
|
bool &AllUsesAreOutsideLoop,
|
||||||
std::vector<BasedUser> &UsersToProcess) {
|
std::vector<BasedUser> &UsersToProcess) {
|
||||||
UsersToProcess.reserve(Uses.Users.size());
|
UsersToProcess.reserve(Uses.Users.size());
|
||||||
for (unsigned i = 0, e = Uses.Users.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Uses.Users.size(); i != e; ++i) {
|
||||||
@ -1275,7 +1278,7 @@ SCEVHandle LoopStrengthReduce::CollectIVUsers(const SCEVHandle &Stride,
|
|||||||
UsersToProcess[i].Base =
|
UsersToProcess[i].Base =
|
||||||
SE->getIntegerSCEV(0, UsersToProcess[i].Base->getType());
|
SE->getIntegerSCEV(0, UsersToProcess[i].Base->getType());
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Addressing modes can be folded into loads and stores. Be careful that
|
// Addressing modes can be folded into loads and stores. Be careful that
|
||||||
// the store is through the expression, not of the expression though.
|
// the store is through the expression, not of the expression though.
|
||||||
bool isPHI = false;
|
bool isPHI = false;
|
||||||
@ -1286,6 +1289,9 @@ SCEVHandle LoopStrengthReduce::CollectIVUsers(const SCEVHandle &Stride,
|
|||||||
++NumPHI;
|
++NumPHI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not all uses are outside the loop.
|
||||||
|
AllUsesAreOutsideLoop = false;
|
||||||
|
|
||||||
// If this use isn't an address, then not all uses are addresses.
|
// If this use isn't an address, then not all uses are addresses.
|
||||||
if (!isAddress && !isPHI)
|
if (!isAddress && !isPHI)
|
||||||
AllUsesAreAddresses = false;
|
AllUsesAreAddresses = false;
|
||||||
@ -1320,6 +1326,11 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
|||||||
// smaller-stride IV.
|
// smaller-stride IV.
|
||||||
bool AllUsesAreAddresses = true;
|
bool AllUsesAreAddresses = true;
|
||||||
|
|
||||||
|
// Keep track if every use of a single stride is outside the loop. If so,
|
||||||
|
// we want to be more aggressive about reusing a smaller-stride IV; a
|
||||||
|
// multiply outside the loop is better than another IV inside. Well, usually.
|
||||||
|
bool AllUsesAreOutsideLoop = true;
|
||||||
|
|
||||||
// Transform our list of users and offsets to a bit more complex table. In
|
// Transform our list of users and offsets to a bit more complex table. In
|
||||||
// this new vector, each 'BasedUser' contains 'Base' the base of the
|
// this new vector, each 'BasedUser' contains 'Base' the base of the
|
||||||
// strided accessas well as the old information from Uses. We progressively
|
// strided accessas well as the old information from Uses. We progressively
|
||||||
@ -1327,6 +1338,7 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
|||||||
// have the full access expression to rewrite the use.
|
// have the full access expression to rewrite the use.
|
||||||
std::vector<BasedUser> UsersToProcess;
|
std::vector<BasedUser> UsersToProcess;
|
||||||
SCEVHandle CommonExprs = CollectIVUsers(Stride, Uses, L, AllUsesAreAddresses,
|
SCEVHandle CommonExprs = CollectIVUsers(Stride, Uses, L, AllUsesAreAddresses,
|
||||||
|
AllUsesAreOutsideLoop,
|
||||||
UsersToProcess);
|
UsersToProcess);
|
||||||
|
|
||||||
// If we managed to find some expressions in common, we'll need to carry
|
// If we managed to find some expressions in common, we'll need to carry
|
||||||
@ -1345,8 +1357,9 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
|||||||
IVExpr ReuseIV(SE->getIntegerSCEV(0, Type::Int32Ty),
|
IVExpr ReuseIV(SE->getIntegerSCEV(0, Type::Int32Ty),
|
||||||
SE->getIntegerSCEV(0, Type::Int32Ty),
|
SE->getIntegerSCEV(0, Type::Int32Ty),
|
||||||
0, 0);
|
0, 0);
|
||||||
unsigned RewriteFactor = 0;
|
int64_t RewriteFactor = 0;
|
||||||
RewriteFactor = CheckForIVReuse(HaveCommonExprs, AllUsesAreAddresses,
|
RewriteFactor = CheckForIVReuse(HaveCommonExprs, AllUsesAreAddresses,
|
||||||
|
AllUsesAreOutsideLoop,
|
||||||
Stride, ReuseIV, CommonExprs->getType(),
|
Stride, ReuseIV, CommonExprs->getType(),
|
||||||
UsersToProcess);
|
UsersToProcess);
|
||||||
if (RewriteFactor != 0) {
|
if (RewriteFactor != 0) {
|
||||||
@ -1445,7 +1458,7 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
|||||||
// Get a base value.
|
// Get a base value.
|
||||||
SCEVHandle Base = UsersToProcess[i].Base;
|
SCEVHandle Base = UsersToProcess[i].Base;
|
||||||
|
|
||||||
// Compact everything with this base to be consequtive with this one.
|
// Compact everything with this base to be consecutive with this one.
|
||||||
for (unsigned j = i+1; j != e; ++j) {
|
for (unsigned j = i+1; j != e; ++j) {
|
||||||
if (UsersToProcess[j].Base == Base) {
|
if (UsersToProcess[j].Base == Base) {
|
||||||
std::swap(UsersToProcess[i+1], UsersToProcess[j]);
|
std::swap(UsersToProcess[i+1], UsersToProcess[j]);
|
||||||
@ -1508,7 +1521,7 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
|||||||
|
|
||||||
SCEVHandle RewriteExpr = SE->getUnknown(RewriteOp);
|
SCEVHandle RewriteExpr = SE->getUnknown(RewriteOp);
|
||||||
|
|
||||||
// If we had to insert new instrutions for RewriteOp, we have to
|
// If we had to insert new instructions for RewriteOp, we have to
|
||||||
// consider that they may not have been able to end up immediately
|
// consider that they may not have been able to end up immediately
|
||||||
// next to RewriteOp, because non-PHI instructions may never precede
|
// next to RewriteOp, because non-PHI instructions may never precede
|
||||||
// PHI instructions in a block. In this case, remember where the last
|
// PHI instructions in a block. In this case, remember where the last
|
||||||
@ -1535,7 +1548,7 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
|||||||
if (!isa<ConstantInt>(CommonBaseV) ||
|
if (!isa<ConstantInt>(CommonBaseV) ||
|
||||||
!cast<ConstantInt>(CommonBaseV)->isZero())
|
!cast<ConstantInt>(CommonBaseV)->isZero())
|
||||||
RewriteExpr = SE->getAddExpr(RewriteExpr,
|
RewriteExpr = SE->getAddExpr(RewriteExpr,
|
||||||
SE->getUnknown(CommonBaseV));
|
SE->getUnknown(CommonBaseV));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that we know what we need to do, insert code before User for the
|
// Now that we know what we need to do, insert code before User for the
|
||||||
@ -1729,9 +1742,11 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool AllUsesAreAddresses = true;
|
bool AllUsesAreAddresses = true;
|
||||||
|
bool AllUsesAreOutsideLoop = true;
|
||||||
std::vector<BasedUser> UsersToProcess;
|
std::vector<BasedUser> UsersToProcess;
|
||||||
SCEVHandle CommonExprs = CollectIVUsers(SI->first, SI->second, L,
|
SCEVHandle CommonExprs = CollectIVUsers(SI->first, SI->second, L,
|
||||||
AllUsesAreAddresses,
|
AllUsesAreAddresses,
|
||||||
|
AllUsesAreOutsideLoop,
|
||||||
UsersToProcess);
|
UsersToProcess);
|
||||||
// Avoid rewriting the compare instruction with an iv of new stride
|
// Avoid rewriting the compare instruction with an iv of new stride
|
||||||
// if it's likely the new stride uses will be rewritten using the
|
// if it's likely the new stride uses will be rewritten using the
|
||||||
@ -2103,7 +2118,7 @@ bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager &LPM) {
|
|||||||
UIntPtrTy = TD->getIntPtrType();
|
UIntPtrTy = TD->getIntPtrType();
|
||||||
Changed = false;
|
Changed = false;
|
||||||
|
|
||||||
// Find all uses of induction variables in this loop, and catagorize
|
// Find all uses of induction variables in this loop, and categorize
|
||||||
// them by stride. Start by finding all of the PHI nodes in the header for
|
// them by stride. Start by finding all of the PHI nodes in the header for
|
||||||
// this loop. If they are induction variables, inspect their uses.
|
// this loop. If they are induction variables, inspect their uses.
|
||||||
SmallPtrSet<Instruction*,16> Processed; // Don't reprocess instructions.
|
SmallPtrSet<Instruction*,16> Processed; // Don't reprocess instructions.
|
||||||
|
Loading…
Reference in New Issue
Block a user