21
21
#include " llvm/ADT/DenseSet.h"
22
22
#include " llvm/ADT/SetVector.h"
23
23
#include " llvm/ADT/StringRef.h"
24
+ #include " llvm/ADT/MapVector.h"
24
25
#include " llvm/IR/BasicBlock.h"
25
26
#include " llvm/IR/CallSite.h"
26
27
#include " llvm/IR/Dominators.h"
@@ -661,7 +662,6 @@ static raw_ostream &operator<<(raw_ostream &OS, const BDVState &State) {
661
662
#endif
662
663
663
664
namespace {
664
- typedef DenseMap<Value *, BDVState> ConflictStateMapTy;
665
665
// Values of type BDVState form a lattice, and this is a helper
666
666
// class that implementes the meet operation. The meat of the meet
667
667
// operation is implemented in MeetBDVStates::pureMeet
@@ -761,14 +761,17 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
761
761
762
762
// Once populated, will contain a mapping from each potentially non-base BDV
763
763
// 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
767
771
/* scope */ {
768
- DenseSet<Value *> Visited;
769
772
SmallVector<Value*, 16 > Worklist;
770
773
Worklist.push_back (def);
771
- Visited .insert (def);
774
+ states .insert (std::make_pair ( def, BDVState ()) );
772
775
while (!Worklist.empty ()) {
773
776
Value *Current = Worklist.pop_back_val ();
774
777
assert (!isKnownBaseResult (Current) && " why did it get added?" );
@@ -781,7 +784,7 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
781
784
return ;
782
785
assert (isExpectedBDVType (Base) && " the only non-base values "
783
786
" we see should be base defining values" );
784
- if (Visited .insert (Base).second )
787
+ if (states .insert (std::make_pair ( Base, BDVState ()) ).second )
785
788
Worklist.push_back (Base);
786
789
};
787
790
if (PHINode *Phi = dyn_cast<PHINode>(Current)) {
@@ -799,12 +802,6 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
799
802
llvm_unreachable (" unimplemented instruction case" );
800
803
}
801
804
}
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
- }
808
805
}
809
806
810
807
#ifndef NDEBUG
@@ -830,7 +827,10 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
830
827
size_t oldSize = states.size ();
831
828
#endif
832
829
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.
834
834
for (auto Pair : states) {
835
835
Value *v = Pair.first ;
836
836
assert (!isKnownBaseResult (v) && " why did it get added?" );
@@ -856,7 +856,6 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
856
856
calculateMeet.meetWith (getStateForInput (EE->getVectorOperand ()));
857
857
}
858
858
859
-
860
859
BDVState oldState = states[v];
861
860
BDVState newState = calculateMeet.getResult ();
862
861
if (oldState != newState) {
@@ -877,20 +876,10 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
877
876
#endif
878
877
879
878
// 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);
890
879
// 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 ;
894
883
assert (!isKnownBaseResult (I) && " why did it get added?" );
895
884
assert (!State.isUnknown () && " Optimistic algorithm didn't complete!" );
896
885
@@ -974,7 +963,9 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
974
963
return Base;
975
964
};
976
965
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.
978
969
for (auto Pair : states) {
979
970
Instruction *v = cast<Instruction>(Pair.first );
980
971
BDVState state = Pair.second ;
@@ -1059,18 +1050,18 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
1059
1050
// Keys we sorted above for this purpose. Note that we are papering over a
1060
1051
// bigger problem with the algorithm above - it's visit order is not
1061
1052
// 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 ;
1065
1056
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?" );
1068
1059
assert (isKnownBaseResult (Base) &&
1069
1060
" must be something we 'know' is a base pointer" );
1070
1061
if (!State.isConflict ())
1071
1062
continue ;
1072
1063
1073
- ReverseMap[Base] = V ;
1064
+ ReverseMap[Base] = BDV ;
1074
1065
if (auto *BaseI = dyn_cast<Instruction>(Base)) {
1075
1066
NewInsts.insert (BaseI);
1076
1067
Worklist.insert (BaseI);
@@ -1113,26 +1104,26 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
1113
1104
// Cache all of our results so we can cheaply reuse them
1114
1105
// NOTE: This is actually two caches: one of the base defining value
1115
1106
// 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);
1120
1111
1121
1112
std::string fromstr =
1122
- cache.count (v ) ? (cache[v ]->hasName () ? cache[v ]->getName () : " " )
1113
+ cache.count (BDV ) ? (cache[BDV ]->hasName () ? cache[BDV ]->getName () : " " )
1123
1114
: " none" ;
1124
1115
DEBUG (dbgs () << " Updating base value cache"
1125
- << " for: " << (v ->hasName () ? v ->getName () : " " )
1116
+ << " for: " << (BDV ->hasName () ? BDV ->getName () : " " )
1126
1117
<< " from: " << fromstr
1127
1118
<< " to: " << (base->hasName () ? base->getName () : " " ) << " \n " );
1128
1119
1129
- if (cache.count (v )) {
1120
+ if (cache.count (BDV )) {
1130
1121
// Once we transition from the BDV relation being store in the cache to
1131
1122
// 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) &&
1133
1124
" base relation should be stable" );
1134
1125
}
1135
- cache[v ] = base;
1126
+ cache[BDV ] = base;
1136
1127
}
1137
1128
assert (cache.find (def) != cache.end ());
1138
1129
return cache[def];
0 commit comments