@@ -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 bit : bits.set_bits ()) {
351
+ if (contains (bit)) {
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,16 @@ 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
890
+ .insert ({user, InterestingUser (getNumSubElements ())})
891
+ .first ;
892
+ }
893
+ return *&iter->second ;
894
+ }
895
+
865
896
// / If \p user has had uses recored, return a pointer to the InterestingUser
866
897
// / where they've been recorded.
867
898
InterestingUser const *getInterestingUser (SILInstruction *user) const {
@@ -918,11 +949,12 @@ class FieldSensitivePrunedLiveness {
918
949
// / argument must be copied.
919
950
void addInterestingUser (SILInstruction *user, TypeTreeLeafTypeRange range,
920
951
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);
952
+ getOrCreateInterestingUser (user).addUses (range, lifetimeEnding);
953
+ }
954
+
955
+ void addInterestingUser (SILInstruction *user, SmallBitVector const &bits,
956
+ bool lifetimeEnding) {
957
+ getOrCreateInterestingUser (user).addUses (bits, lifetimeEnding);
926
958
}
927
959
};
928
960
@@ -1036,6 +1068,11 @@ class FieldSensitivePrunedLiveRange : public FieldSensitivePrunedLiveness {
1036
1068
void updateForUse (SILInstruction *user, TypeTreeLeafTypeRange span,
1037
1069
bool lifetimeEnding);
1038
1070
1071
+ // / Customize updateForUse for FieldSensitivePrunedLiveness such that we check
1072
+ // / that we consider defs as stopping liveness from being propagated up.
1073
+ void updateForUse (SILInstruction *user, SmallBitVector const &bits,
1074
+ bool lifetimeEnding);
1075
+
1039
1076
// / Compute the boundary from the blocks discovered during liveness analysis.
1040
1077
// /
1041
1078
// / Precondition: \p liveness.getDiscoveredBlocks() is a valid list of all
@@ -1107,6 +1144,10 @@ class FieldSensitiveSSAPrunedLiveRange
1107
1144
return inst == defInst.first && defInst.second ->contains (bit);
1108
1145
}
1109
1146
1147
+ bool isDef (SILInstruction *inst, SmallBitVector const &bits) const {
1148
+ return inst == defInst.first && llvm::all_of (bits.set_bits (), [&](auto bit){ return defInst.second ->contains (bit); });
1149
+ }
1150
+
1110
1151
bool isDef (SILInstruction *inst, TypeTreeLeafTypeRange span) const {
1111
1152
return inst == defInst.first &&
1112
1153
defInst.second ->setIntersection (span).has_value ();
@@ -1217,6 +1258,30 @@ class FieldSensitiveMultiDefPrunedLiveRange
1217
1258
*iter, [&](TypeTreeLeafTypeRange span) { return span.contains (bit); });
1218
1259
}
1219
1260
1261
+ bool isDef (SILValue value, SmallBitVector const &bits) const {
1262
+ assert (isInitialized ());
1263
+ auto iter = defs.find (cast<SILNode>(value));
1264
+ if (!iter)
1265
+ return false ;
1266
+ SmallBitVector allBits (bits.size ());
1267
+ for (auto range : *iter) {
1268
+ range.setBits (allBits);
1269
+ }
1270
+ return (bits & allBits) == bits;
1271
+ }
1272
+
1273
+ bool isDef (SILInstruction *inst, SmallBitVector const &bits) const {
1274
+ assert (isInitialized ());
1275
+ auto iter = defs.find (cast<SILNode>(inst));
1276
+ if (!iter)
1277
+ return false ;
1278
+ SmallBitVector allBits (bits.size ());
1279
+ for (auto range : *iter) {
1280
+ range.setBits (allBits);
1281
+ }
1282
+ return (bits & allBits) == bits;
1283
+ }
1284
+
1220
1285
bool isDef (SILInstruction *inst, TypeTreeLeafTypeRange span) const {
1221
1286
assert (isInitialized ());
1222
1287
auto iter = defs.find (cast<SILNode>(inst));
0 commit comments