Skip to content

Commit 15d5563

Browse files
committedSep 9, 2015
[RewriteStatepointsForGC] Make base pointer inference deterministic
Previously, the base pointer algorithm wasn't deterministic. The core fixed point was (of course), but we were inserting new nodes and optimizing them in an order which was unspecified and variable. We'd somewhat hacked around this for testing by sorting by value name, but that doesn't solve the general determinism problem. Instead, we can use the order of traversal over the def/use graph to give us a single consistent ordering. Today, this is a DFS order, but the exact order doesn't mater provided it's deterministic for a given input. (Q: It is safe to rely on a deterministic order of operands right?) Note that this only fixes the determinism within a single inference step. The inference step is currently invoked many times in a non-deterministic order. That's a future change in the sequence. :) Differential Revision: http://reviews.llvm.org/D12640 llvm-svn: 247208
1 parent f4a1b77 commit 15d5563

File tree

1 file changed

+35
-44
lines changed

1 file changed

+35
-44
lines changed
 

‎llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp

+35-44
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/ADT/DenseSet.h"
2222
#include "llvm/ADT/SetVector.h"
2323
#include "llvm/ADT/StringRef.h"
24+
#include "llvm/ADT/MapVector.h"
2425
#include "llvm/IR/BasicBlock.h"
2526
#include "llvm/IR/CallSite.h"
2627
#include "llvm/IR/Dominators.h"
@@ -661,7 +662,6 @@ static raw_ostream &operator<<(raw_ostream &OS, const BDVState &State) {
661662
#endif
662663

663664
namespace {
664-
typedef DenseMap<Value *, BDVState> ConflictStateMapTy;
665665
// Values of type BDVState form a lattice, and this is a helper
666666
// class that implementes the meet operation. The meat of the meet
667667
// operation is implemented in MeetBDVStates::pureMeet
@@ -761,14 +761,17 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
761761

762762
// Once populated, will contain a mapping from each potentially non-base BDV
763763
// to a lattice value (described above) which corresponds to that BDV.
764-
ConflictStateMapTy states;
765-
// Recursively fill in all phis & selects reachable from the initial one
766-
// for which we don't already know a definite base value for
764+
// We use the order of insertion (DFS over the def/use graph) to provide a
765+
// stable deterministic ordering for visiting DenseMaps (which are unordered)
766+
// below. This is important for deterministic compilation.
767+
MapVector<Value *, BDVState> states;
768+
769+
// Recursively fill in all base defining values reachable from the initial
770+
// one for which we don't already know a definite base value for
767771
/* scope */ {
768-
DenseSet<Value *> Visited;
769772
SmallVector<Value*, 16> Worklist;
770773
Worklist.push_back(def);
771-
Visited.insert(def);
774+
states.insert(std::make_pair(def, BDVState()));
772775
while (!Worklist.empty()) {
773776
Value *Current = Worklist.pop_back_val();
774777
assert(!isKnownBaseResult(Current) && "why did it get added?");
@@ -781,7 +784,7 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
781784
return;
782785
assert(isExpectedBDVType(Base) && "the only non-base values "
783786
"we see should be base defining values");
784-
if (Visited.insert(Base).second)
787+
if (states.insert(std::make_pair(Base, BDVState())).second)
785788
Worklist.push_back(Base);
786789
};
787790
if (PHINode *Phi = dyn_cast<PHINode>(Current)) {
@@ -799,12 +802,6 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
799802
llvm_unreachable("unimplemented instruction case");
800803
}
801804
}
802-
// The frontier of visited instructions are the ones we might need to
803-
// duplicate, so fill in the starting state for the optimistic algorithm
804-
// that follows.
805-
for (Value *BDV : Visited) {
806-
states[BDV] = BDVState();
807-
}
808805
}
809806

810807
#ifndef NDEBUG
@@ -830,7 +827,10 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
830827
size_t oldSize = states.size();
831828
#endif
832829
progress = false;
833-
// We're only changing keys in this loop, thus safe to keep iterators
830+
// We're only changing values in this loop, thus safe to keep iterators.
831+
// Since this is computing a fixed point, the order of visit does not
832+
// effect the result. TODO: We could use a worklist here and make this run
833+
// much faster.
834834
for (auto Pair : states) {
835835
Value *v = Pair.first;
836836
assert(!isKnownBaseResult(v) && "why did it get added?");
@@ -856,7 +856,6 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
856856
calculateMeet.meetWith(getStateForInput(EE->getVectorOperand()));
857857
}
858858

859-
860859
BDVState oldState = states[v];
861860
BDVState newState = calculateMeet.getResult();
862861
if (oldState != newState) {
@@ -877,20 +876,10 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
877876
#endif
878877

879878
// Insert Phis for all conflicts
880-
// We want to keep naming deterministic in the loop that follows, so
881-
// sort the keys before iteration. This is useful in allowing us to
882-
// write stable tests. Note that there is no invalidation issue here.
883-
SmallVector<Value *, 16> Keys;
884-
Keys.reserve(states.size());
885-
for (auto Pair : states) {
886-
Value *V = Pair.first;
887-
Keys.push_back(V);
888-
}
889-
std::sort(Keys.begin(), Keys.end(), order_by_name);
890879
// TODO: adjust naming patterns to avoid this order of iteration dependency
891-
for (Value *V : Keys) {
892-
Instruction *I = cast<Instruction>(V);
893-
BDVState State = states[I];
880+
for (auto Pair : states) {
881+
Instruction *I = cast<Instruction>(Pair.first);
882+
BDVState State = Pair.second;
894883
assert(!isKnownBaseResult(I) && "why did it get added?");
895884
assert(!State.isUnknown() && "Optimistic algorithm didn't complete!");
896885

@@ -974,7 +963,9 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
974963
return Base;
975964
};
976965

977-
// Fixup all the inputs of the new PHIs
966+
// Fixup all the inputs of the new PHIs. Visit order needs to be
967+
// deterministic and predictable because we're naming newly created
968+
// instructions.
978969
for (auto Pair : states) {
979970
Instruction *v = cast<Instruction>(Pair.first);
980971
BDVState state = Pair.second;
@@ -1059,18 +1050,18 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
10591050
// Keys we sorted above for this purpose. Note that we are papering over a
10601051
// bigger problem with the algorithm above - it's visit order is not
10611052
// deterministic. A larger change is needed to fix this.
1062-
for (auto Key : Keys) {
1063-
Value *V = Key;
1064-
auto State = states[Key];
1053+
for (auto Pair : states) {
1054+
auto *BDV = Pair.first;
1055+
auto State = Pair.second;
10651056
Value *Base = State.getBase();
1066-
assert(V && Base);
1067-
assert(!isKnownBaseResult(V) && "why did it get added?");
1057+
assert(BDV && Base);
1058+
assert(!isKnownBaseResult(BDV) && "why did it get added?");
10681059
assert(isKnownBaseResult(Base) &&
10691060
"must be something we 'know' is a base pointer");
10701061
if (!State.isConflict())
10711062
continue;
10721063

1073-
ReverseMap[Base] = V;
1064+
ReverseMap[Base] = BDV;
10741065
if (auto *BaseI = dyn_cast<Instruction>(Base)) {
10751066
NewInsts.insert(BaseI);
10761067
Worklist.insert(BaseI);
@@ -1113,26 +1104,26 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
11131104
// Cache all of our results so we can cheaply reuse them
11141105
// NOTE: This is actually two caches: one of the base defining value
11151106
// relation and one of the base pointer relation! FIXME
1116-
for (auto item : states) {
1117-
Value *v = item.first;
1118-
Value *base = item.second.getBase();
1119-
assert(v && base);
1107+
for (auto Pair : states) {
1108+
auto *BDV = Pair.first;
1109+
Value *base = Pair.second.getBase();
1110+
assert(BDV && base);
11201111

11211112
std::string fromstr =
1122-
cache.count(v) ? (cache[v]->hasName() ? cache[v]->getName() : "")
1113+
cache.count(BDV) ? (cache[BDV]->hasName() ? cache[BDV]->getName() : "")
11231114
: "none";
11241115
DEBUG(dbgs() << "Updating base value cache"
1125-
<< " for: " << (v->hasName() ? v->getName() : "")
1116+
<< " for: " << (BDV->hasName() ? BDV->getName() : "")
11261117
<< " from: " << fromstr
11271118
<< " to: " << (base->hasName() ? base->getName() : "") << "\n");
11281119

1129-
if (cache.count(v)) {
1120+
if (cache.count(BDV)) {
11301121
// Once we transition from the BDV relation being store in the cache to
11311122
// the base relation being stored, it must be stable
1132-
assert((!isKnownBaseResult(cache[v]) || cache[v] == base) &&
1123+
assert((!isKnownBaseResult(cache[BDV]) || cache[BDV] == base) &&
11331124
"base relation should be stable");
11341125
}
1135-
cache[v] = base;
1126+
cache[BDV] = base;
11361127
}
11371128
assert(cache.find(def) != cache.end());
11381129
return cache[def];

0 commit comments

Comments
 (0)
Please sign in to comment.