1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

[RewriteStatepointsForGC] Fix another order of iteration bug

It turns out the naming of inserted phis and selects is sensative to the order in which two sets are iterated.  We need to nail this down to avoid non-deterministic output and possible test failures.  

The modified test is the one I first noticed something odd in.  The change is making it more strict to report the error.  With the test change, but without the code change, the test fails roughly 1 in 5.  With the code change, I've run ~30 runs without error.

Long term, the right fix here is to adjust the naming scheme.  I'm checking in this hack to avoid any possible non-determinism in the tests over the weekend.  HJust because I only noticed one case doesn't mean it's actually the only case.  I hope to get to the right change Monday.

std->llvm data structure changes bugfix change #3

llvm-svn: 230835
This commit is contained in:
Philip Reames 2015-02-28 01:52:09 +00:00
parent 5658248d0a
commit 7a2e8f33b1
2 changed files with 21 additions and 5 deletions

View File

@ -776,10 +776,20 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache,
} }
// Insert Phis for all conflicts // Insert Phis for all conflicts
// Only changing keys in 'states', thus safe to keep iterators // We want to keep naming deterministic in the loop that follows, so
// sort the keys before iteration. This is useful in allowing us to
// write stable tests. Note that there is no invalidation issue here.
SmallVector<Value*, 16> Keys;
Keys.reserve(states.size());
for (auto Pair : states) { for (auto Pair : states) {
Instruction *v = cast<Instruction>(Pair.first); Value *V = Pair.first;
PhiState state = Pair.second; Keys.push_back(V);
}
std::sort(Keys.begin(), Keys.end(), order_by_name);
// TODO: adjust naming patterns to avoid this order of iteration dependency
for (Value *V : Keys) {
Instruction *v = cast<Instruction>(V);
PhiState state = states[V];
assert(!isKnownBaseResult(v) && "why did it get added?"); assert(!isKnownBaseResult(v) && "why did it get added?");
assert(!state.isUnknown() && "Optimistic algorithm didn't complete!"); assert(!state.isUnknown() && "Optimistic algorithm didn't complete!");
if (!state.isConflict()) if (!state.isConflict())
@ -974,7 +984,13 @@ static void findBasePointers(const StatepointLiveSetTy &live,
DenseMap<llvm::Value *, llvm::Value *> &PointerToBase, DenseMap<llvm::Value *, llvm::Value *> &PointerToBase,
DominatorTree *DT, DefiningValueMapTy &DVCache, DominatorTree *DT, DefiningValueMapTy &DVCache,
DenseSet<llvm::Value *> &NewInsertedDefs) { DenseSet<llvm::Value *> &NewInsertedDefs) {
for (Value *ptr : live) { // For the naming of values inserted to be deterministic - which makes for
// much cleaner and more stable tests - we need to assign an order to the
// live values. DenseSets do not provide a deterministic order across runs.
SmallVector<Value*, 64> Temp;
Temp.insert(Temp.end(), live.begin(), live.end());
std::sort(Temp.begin(), Temp.end(), order_by_name);
for (Value *ptr : Temp) {
Value *base = findBasePointer(ptr, DVCache, NewInsertedDefs); Value *base = findBasePointer(ptr, DVCache, NewInsertedDefs);
assert(base && "failed to find base pointer"); assert(base && "failed to find base pointer");
PointerToBase[ptr] = base; PointerToBase[ptr] = base;

View File

@ -76,7 +76,7 @@ loop: ; preds = %loop, %entry
; CHECK-LABEL: loop ; CHECK-LABEL: loop
; CHECK: %base_phi = phi i64 addrspace(1)* ; CHECK: %base_phi = phi i64 addrspace(1)*
; CHECK-DAG: [ %base_obj, %entry ] ; CHECK-DAG: [ %base_obj, %entry ]
; CHECK-DAG: [ %base_select ; CHECK-DAG: [ %base_select.relocated, %loop ]
; CHECK-NOT: base_phi2 ; CHECK-NOT: base_phi2
; CHECK: next = select ; CHECK: next = select
; CHECK: base_select ; CHECK: base_select