mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-22 13:29:44 +00:00
Fix a source of non-determinism in the backend: the order of processing
IV strides dependend on the pointer order of the strides in memory. Non-determinism is bad. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23672 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
089c25ccb3
commit
7305ae28df
@ -91,6 +91,11 @@ namespace {
|
|||||||
/// are interested in. The key of the map is the stride of the access.
|
/// are interested in. The key of the map is the stride of the access.
|
||||||
std::map<SCEVHandle, IVUsersOfOneStride> IVUsesByStride;
|
std::map<SCEVHandle, IVUsersOfOneStride> IVUsesByStride;
|
||||||
|
|
||||||
|
/// StrideOrder - An ordering of the keys in IVUsesByStride that is stable:
|
||||||
|
/// We use this to iterate over the IVUsesByStride collection without being
|
||||||
|
/// dependent on random ordering of pointers in the process.
|
||||||
|
std::vector<SCEVHandle> StrideOrder;
|
||||||
|
|
||||||
/// CastedValues - As we need to cast values to uintptr_t, this keeps track
|
/// CastedValues - As we need to cast values to uintptr_t, this keeps track
|
||||||
/// of the casted version of each value. This is accessed by
|
/// of the casted version of each value. This is accessed by
|
||||||
/// getCastedVersionOf.
|
/// getCastedVersionOf.
|
||||||
@ -402,6 +407,10 @@ bool LoopStrengthReduce::AddUsersIfInteresting(Instruction *I, Loop *L,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (AddUserToIVUsers) {
|
if (AddUserToIVUsers) {
|
||||||
|
IVUsersOfOneStride &StrideUses = IVUsesByStride[Stride];
|
||||||
|
if (StrideUses.Users.empty()) // First occurance of this 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
|
||||||
// and decide what to do with it. If we are a use inside of the loop, use
|
// and decide what to do with it. If we are a use inside of the loop, use
|
||||||
// the value before incrementation, otherwise use it after incrementation.
|
// the value before incrementation, otherwise use it after incrementation.
|
||||||
@ -409,11 +418,11 @@ bool LoopStrengthReduce::AddUsersIfInteresting(Instruction *I, Loop *L,
|
|||||||
// 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 = SCEV::getMinusSCEV(Start, Stride);
|
SCEVHandle NewStart = SCEV::getMinusSCEV(Start, Stride);
|
||||||
IVUsesByStride[Stride].addUser(NewStart, User, I);
|
StrideUses.addUser(NewStart, User, I);
|
||||||
IVUsesByStride[Stride].Users.back().isUseOfPostIncrementedValue = true;
|
StrideUses.Users.back().isUseOfPostIncrementedValue = true;
|
||||||
DEBUG(std::cerr << " USING POSTINC SCEV, START=" << *NewStart<< "\n");
|
DEBUG(std::cerr << " USING POSTINC SCEV, START=" << *NewStart<< "\n");
|
||||||
} else {
|
} else {
|
||||||
IVUsesByStride[Stride].addUser(Start, User, I);
|
StrideUses.addUser(Start, User, I);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1040,11 +1049,20 @@ void LoopStrengthReduce::runOnLoop(Loop *L) {
|
|||||||
// If we only have one stride, we can more aggressively eliminate some things.
|
// If we only have one stride, we can more aggressively eliminate some things.
|
||||||
bool HasOneStride = IVUsesByStride.size() == 1;
|
bool HasOneStride = IVUsesByStride.size() == 1;
|
||||||
|
|
||||||
|
if (IVUsesByStride.size() == 123)
|
||||||
|
std::cerr << "FOO!\n";
|
||||||
|
|
||||||
// Note: this processes each stride/type pair individually. All users passed
|
// Note: this processes each stride/type pair individually. All users passed
|
||||||
// into StrengthReduceStridedIVUsers have the same type AND stride.
|
// into StrengthReduceStridedIVUsers have the same type AND stride. Also,
|
||||||
for (std::map<SCEVHandle, IVUsersOfOneStride>::iterator SI
|
// node that we iterate over IVUsesByStride indirectly by using StrideOrder.
|
||||||
= IVUsesByStride.begin(), E = IVUsesByStride.end(); SI != E; ++SI)
|
// This extra layer of indirection makes the ordering of strides deterministic
|
||||||
|
// - not dependent on map order.
|
||||||
|
for (unsigned Stride = 0, e = StrideOrder.size(); Stride != e; ++Stride) {
|
||||||
|
std::map<SCEVHandle, IVUsersOfOneStride>::iterator SI =
|
||||||
|
IVUsesByStride.find(StrideOrder[Stride]);
|
||||||
|
assert(SI != IVUsesByStride.end() && "Stride doesn't exist!");
|
||||||
StrengthReduceStridedIVUsers(SI->first, SI->second, L, HasOneStride);
|
StrengthReduceStridedIVUsers(SI->first, SI->second, L, HasOneStride);
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up after ourselves
|
// Clean up after ourselves
|
||||||
if (!DeadInsts.empty()) {
|
if (!DeadInsts.empty()) {
|
||||||
@ -1085,5 +1103,6 @@ void LoopStrengthReduce::runOnLoop(Loop *L) {
|
|||||||
|
|
||||||
CastedPointers.clear();
|
CastedPointers.clear();
|
||||||
IVUsesByStride.clear();
|
IVUsesByStride.clear();
|
||||||
|
StrideOrder.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user