From: Philip Reames Date: Sat, 28 Feb 2015 01:52:09 +0000 (+0000) Subject: [RewriteStatepointsForGC] Fix another order of iteration bug X-Git-Tag: android-x86-7.1-r4~51111 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=af690c9cd32c482574c0999c795b1693065bbc53;p=android-x86%2Fexternal-llvm.git [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230835 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp index 8f8db94e0b2..22807f68945 100644 --- a/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ b/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -776,10 +776,20 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache, } // 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 Keys; + Keys.reserve(states.size()); for (auto Pair : states) { - Instruction *v = cast(Pair.first); - PhiState state = Pair.second; + Value *V = Pair.first; + 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(V); + PhiState state = states[V]; assert(!isKnownBaseResult(v) && "why did it get added?"); assert(!state.isUnknown() && "Optimistic algorithm didn't complete!"); if (!state.isConflict()) @@ -974,7 +984,13 @@ static void findBasePointers(const StatepointLiveSetTy &live, DenseMap &PointerToBase, DominatorTree *DT, DefiningValueMapTy &DVCache, DenseSet &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 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); assert(base && "failed to find base pointer"); PointerToBase[ptr] = base; diff --git a/test/Transforms/RewriteStatepointsForGC/base-pointers.ll b/test/Transforms/RewriteStatepointsForGC/base-pointers.ll index e7276821e1e..c5035eb3b1b 100644 --- a/test/Transforms/RewriteStatepointsForGC/base-pointers.ll +++ b/test/Transforms/RewriteStatepointsForGC/base-pointers.ll @@ -76,7 +76,7 @@ loop: ; preds = %loop, %entry ; CHECK-LABEL: loop ; CHECK: %base_phi = phi i64 addrspace(1)* ; CHECK-DAG: [ %base_obj, %entry ] -; CHECK-DAG: [ %base_select +; CHECK-DAG: [ %base_select.relocated, %loop ] ; CHECK-NOT: base_phi2 ; CHECK: next = select ; CHECK: base_select