@@ -345,6 +345,16 @@ struct TypeTreeLeafTypeRange {
345
345
return TypeTreeLeafTypeRange (start, end);
346
346
}
347
347
348
+ // / Whether \p bits contains any of the in-range bits.
349
+ bool intersects (SmallBitVector const &bits) const {
350
+ for (auto element : getRange ()) {
351
+ if (bits.test (element)) {
352
+ return true ;
353
+ }
354
+ }
355
+ return false ;
356
+ }
357
+
348
358
// / Is the given leaf type specified by \p singleLeafElementNumber apart of
349
359
// / our \p range of leaf type values in the our larger type.
350
360
bool contains (SubElementOffset singleLeafElementNumber) const {
@@ -696,6 +706,14 @@ class FieldSensitivePrunedLiveness {
696
706
}
697
707
}
698
708
709
+ // / Record that the instruction uses the bits in \p bits.
710
+ void addUses (SmallBitVector const &bits, bool lifetimeEnding) {
711
+ liveBits |= bits;
712
+ if (lifetimeEnding) {
713
+ consumingBits |= bits;
714
+ }
715
+ }
716
+
699
717
// / Populates the provided vector with contiguous ranges of bits which are
700
718
// / users of the same sort.
701
719
void getContiguousRanges (
@@ -838,6 +856,9 @@ class FieldSensitivePrunedLiveness {
838
856
void updateForUse (SILInstruction *user, TypeTreeLeafTypeRange span,
839
857
bool lifetimeEnding);
840
858
859
+ void updateForUse (SILInstruction *user, SmallBitVector const &bits,
860
+ bool lifetimeEnding);
861
+
841
862
void getBlockLiveness (SILBasicBlock *bb, TypeTreeLeafTypeRange span,
842
863
SmallVectorImpl<FieldSensitivePrunedLiveBlocks::IsLive>
843
864
&resultingFoundLiveness) const {
@@ -862,6 +883,14 @@ class FieldSensitivePrunedLiveness {
862
883
SmallBitVector &liveOutBits,
863
884
SmallBitVector &deadBits) const ;
864
885
886
+ InterestingUser &getOrCreateInterestingUser (SILInstruction *user) {
887
+ auto iter = users.find (user);
888
+ if (iter == users.end ()) {
889
+ iter = users.insert ({user, InterestingUser (getNumSubElements ())}).first ;
890
+ }
891
+ return *&iter->second ;
892
+ }
893
+
865
894
// / If \p user has had uses recored, return a pointer to the InterestingUser
866
895
// / where they've been recorded.
867
896
InterestingUser const *getInterestingUser (SILInstruction *user) const {
@@ -885,11 +914,12 @@ class FieldSensitivePrunedLiveness {
885
914
bool isInterestingUserOfKind (SILInstruction *user, IsInterestingUser kind,
886
915
TypeTreeLeafTypeRange range) const {
887
916
auto *record = getInterestingUser (user);
888
- if (!record)
917
+ if (!record) {
889
918
return kind == IsInterestingUser::NonUser;
919
+ }
890
920
891
921
for (auto element : range.getRange ()) {
892
- if (isInterestingUser (user, element) != kind)
922
+ if (record-> isInterestingUser (element) != kind)
893
923
return false ;
894
924
}
895
925
return true ;
@@ -918,11 +948,12 @@ class FieldSensitivePrunedLiveness {
918
948
// / argument must be copied.
919
949
void addInterestingUser (SILInstruction *user, TypeTreeLeafTypeRange range,
920
950
bool lifetimeEnding) {
921
- auto iter = users.find (user);
922
- if (iter == users.end ()) {
923
- iter = users.insert ({user, InterestingUser (getNumSubElements ())}).first ;
924
- }
925
- iter->second .addUses (range, lifetimeEnding);
951
+ getOrCreateInterestingUser (user).addUses (range, lifetimeEnding);
952
+ }
953
+
954
+ void addInterestingUser (SILInstruction *user, SmallBitVector const &bits,
955
+ bool lifetimeEnding) {
956
+ getOrCreateInterestingUser (user).addUses (bits, lifetimeEnding);
926
957
}
927
958
};
928
959
@@ -1036,6 +1067,11 @@ class FieldSensitivePrunedLiveRange : public FieldSensitivePrunedLiveness {
1036
1067
void updateForUse (SILInstruction *user, TypeTreeLeafTypeRange span,
1037
1068
bool lifetimeEnding);
1038
1069
1070
+ // / Customize updateForUse for FieldSensitivePrunedLiveness such that we check
1071
+ // / that we consider defs as stopping liveness from being propagated up.
1072
+ void updateForUse (SILInstruction *user, SmallBitVector const &bits,
1073
+ bool lifetimeEnding);
1074
+
1039
1075
// / Compute the boundary from the blocks discovered during liveness analysis.
1040
1076
// /
1041
1077
// / Precondition: \p liveness.getDiscoveredBlocks() is a valid list of all
@@ -1107,6 +1143,16 @@ class FieldSensitiveSSAPrunedLiveRange
1107
1143
return inst == defInst.first && defInst.second ->contains (bit);
1108
1144
}
1109
1145
1146
+ bool isDef (SILInstruction *inst, SmallBitVector const &bits) const {
1147
+ if (inst != defInst.first )
1148
+ return false ;
1149
+ for (auto bit : bits.set_bits ()) {
1150
+ if (!defInst.second ->contains (bit))
1151
+ return false ;
1152
+ }
1153
+ return true ;
1154
+ }
1155
+
1110
1156
bool isDef (SILInstruction *inst, TypeTreeLeafTypeRange span) const {
1111
1157
return inst == defInst.first &&
1112
1158
defInst.second ->setIntersection (span).has_value ();
@@ -1217,6 +1263,30 @@ class FieldSensitiveMultiDefPrunedLiveRange
1217
1263
*iter, [&](TypeTreeLeafTypeRange span) { return span.contains (bit); });
1218
1264
}
1219
1265
1266
+ bool isDef (SILValue value, SmallBitVector const &bits) const {
1267
+ assert (isInitialized ());
1268
+ auto iter = defs.find (cast<SILNode>(value));
1269
+ if (!iter)
1270
+ return false ;
1271
+ SmallBitVector allBits (bits.size ());
1272
+ for (auto range : *iter) {
1273
+ range.setBits (allBits);
1274
+ }
1275
+ return (bits & allBits) == bits;
1276
+ }
1277
+
1278
+ bool isDef (SILInstruction *inst, SmallBitVector const &bits) const {
1279
+ assert (isInitialized ());
1280
+ auto iter = defs.find (cast<SILNode>(inst));
1281
+ if (!iter)
1282
+ return false ;
1283
+ SmallBitVector allBits (bits.size ());
1284
+ for (auto range : *iter) {
1285
+ range.setBits (allBits);
1286
+ }
1287
+ return (bits & allBits) == bits;
1288
+ }
1289
+
1220
1290
bool isDef (SILInstruction *inst, TypeTreeLeafTypeRange span) const {
1221
1291
assert (isInitialized ());
1222
1292
auto iter = defs.find (cast<SILNode>(inst));
0 commit comments