@@ -967,6 +967,44 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &Cache,
967
967
return BDVState (BaseValue, BDVState::Base, BaseValue);
968
968
};
969
969
970
+ // Even though we have identified a concrete base (or a conflict) for all live
971
+ // pointers at this point, there are cases where the base is of an
972
+ // incompatible type compared to the original instruction. We conservatively
973
+ // mark those as conflicts to ensure that corresponding BDVs will be generated
974
+ // in the next steps.
975
+
976
+ // this is a rather explicit check for all cases where we should mark the
977
+ // state as a conflict to force the latter stages of the algorithm to emit
978
+ // the BDVs.
979
+ // TODO: in many cases the instructions emited for the conflicting states
980
+ // will be identical to the I itself (if the I's operate on their BDVs
981
+ // themselves). We should exploit this, but can't do it here since it would
982
+ // break the invariant about the BDVs not being known to be a base.
983
+ // TODO: the code also does not handle constants at all - the algorithm relies
984
+ // on all constants having the same BDV and therefore constant-only insns
985
+ // will never be in conflict, but this check is ignored here. If the
986
+ // constant conflicts will be to BDVs themselves, they will be identical
987
+ // instructions and will get optimized away (as in the above TODO)
988
+ auto MarkConflict = [&](Instruction *I, Value *BaseValue) {
989
+ // II and EE mixes vector & scalar so is always a conflict
990
+ if (isa<InsertElementInst>(I) || isa<ExtractElementInst>(I))
991
+ return true ;
992
+ // Shuffle vector is always a conflict as it creates new vector from
993
+ // existing ones.
994
+ if (isa<ShuffleVectorInst>(I))
995
+ return true ;
996
+ // Any instructions where the computed base type differs from the
997
+ // instruction type. An example is where an extract instruction is used by a
998
+ // select. Here the select's BDV is a vector (because of extract's BDV),
999
+ // while the select itself is a scalar type. Note that the IE and EE
1000
+ // instruction check is not fully subsumed by the vector<->scalar check at
1001
+ // the end, this is due to the BDV algorithm being ignorant of BDV types at
1002
+ // this junction.
1003
+ if (!areBothVectorOrScalar (BaseValue, I))
1004
+ return true ;
1005
+ return false ;
1006
+ };
1007
+
970
1008
bool Progress = true ;
971
1009
while (Progress) {
972
1010
#ifndef NDEBUG
@@ -993,6 +1031,14 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &Cache,
993
1031
NewState.meet (OpState);
994
1032
});
995
1033
1034
+ // if the instruction has known base, but should in fact be marked as
1035
+ // conflict because of incompatible in/out types, we mark it as such
1036
+ // ensuring that it will propagate through the fixpoint iteration
1037
+ auto I = cast<Instruction>(BDV);
1038
+ auto BV = NewState.getBaseValue ();
1039
+ if (BV && MarkConflict (I, BV))
1040
+ NewState = BDVState (I, BDVState::Conflict);
1041
+
996
1042
BDVState OldState = Pair.second ;
997
1043
if (OldState != NewState) {
998
1044
Progress = true ;
@@ -1012,44 +1058,8 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &Cache,
1012
1058
}
1013
1059
#endif
1014
1060
1015
- // Even though we have identified a concrete base (or a conflict) for all live
1016
- // pointers at this point, there are cases where the base is of an
1017
- // incompatible type compared to the original instruction. We conservatively
1018
- // mark those as conflicts to ensure that corresponding BDVs will be generated
1019
- // in the next steps.
1020
-
1021
- // this is a rather explicit check for all cases where we should mark the
1022
- // state as a conflict to force the latter stages of the algorithm to emit
1023
- // the BDVs.
1024
- // TODO: in many cases the instructions emited for the conflicting states
1025
- // will be identical to the I itself (if the I's operate on their BDVs
1026
- // themselves). We should expoit this, but can't do it here since it would
1027
- // break the invariant about the BDVs not being known to be a base.
1028
- // TODO: the code also does not handle constants at all - the algorithm relies
1029
- // on all constants having the same BDV and therefore constant-only insns
1030
- // will never be in conflict, but this check is ignored here. If the
1031
- // constant conflicts will be to BDVs themselves, they will be identical
1032
- // instructions and will get optimized away (as in the above TODO)
1033
- auto MarkConflict = [&](Instruction *I, Value *BaseValue) {
1034
- // II and EE mixes vector & scalar so is always a conflict
1035
- if (isa<InsertElementInst>(I) || isa<ExtractElementInst>(I))
1036
- return true ;
1037
- // Shuffle vector is always a conflict as it creates new vector from
1038
- // existing ones.
1039
- if (isa<ShuffleVectorInst>(I))
1040
- return true ;
1041
- // Any instructions where the computed base type differs from the
1042
- // instruction type. An example is where an extract instruction is used by a
1043
- // select. Here the select's BDV is a vector (because of extract's BDV),
1044
- // while the select itself is a scalar type. Note that the IE and EE
1045
- // instruction check is not fully subsumed by the vector<->scalar check at
1046
- // the end, this is due to the BDV algorithm being ignorant of BDV types at
1047
- // this junction.
1048
- if (!areBothVectorOrScalar (BaseValue, I))
1049
- return true ;
1050
- return false ;
1051
- };
1052
-
1061
+ // since we do the conflict marking as part of the fixpoint iteration this
1062
+ // loop only asserts that invariants are met
1053
1063
for (auto Pair : States) {
1054
1064
Instruction *I = cast<Instruction>(Pair.first );
1055
1065
BDVState State = Pair.second ;
@@ -1061,14 +1071,6 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &Cache,
1061
1071
(!isKnownBase (I, KnownBases) || !areBothVectorOrScalar (I, BaseValue)) &&
1062
1072
" why did it get added?" );
1063
1073
assert (!State.isUnknown () && " Optimistic algorithm didn't complete!" );
1064
-
1065
- // since we only mark vec-scalar insns as conflicts in the pass, our work is
1066
- // done if the instruction already conflicts
1067
- if (State.isConflict ())
1068
- continue ;
1069
-
1070
- if (MarkConflict (I, BaseValue))
1071
- States[I] = BDVState (I, BDVState::Conflict);
1072
1074
}
1073
1075
1074
1076
#ifndef NDEBUG
0 commit comments