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:
Chris Lattner 2005-10-09 06:20:55 +00:00
parent 089c25ccb3
commit 7305ae28df

View File

@ -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;
} }