@@ -345,6 +345,16 @@ struct TypeTreeLeafTypeRange {
345345 return TypeTreeLeafTypeRange (start, end);
346346 }
347347
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+
348358 // / Is the given leaf type specified by \p singleLeafElementNumber apart of
349359 // / our \p range of leaf type values in the our larger type.
350360 bool contains (SubElementOffset singleLeafElementNumber) const {
@@ -359,7 +369,7 @@ struct TypeTreeLeafTypeRange {
359369 }
360370
361371 // / Sets each bit in \p bits corresponding to an element of this range.
362- void setBits (SmallBitVector &bits) {
372+ void setBits (SmallBitVector &bits) const {
363373 for (auto element : getRange ()) {
364374 bits.set (element);
365375 }
@@ -518,7 +528,7 @@ class FieldSensitivePrunedLiveBlocks {
518528 assert (!discoveredBlocks || discoveredBlocks->empty ());
519529 }
520530
521- bool isInitialized () const { return numBitsToTrack.hasValue (); }
531+ bool isInitialized () const { return numBitsToTrack.has_value (); }
522532
523533 unsigned getNumBitsToTrack () const { return *numBitsToTrack; }
524534
@@ -696,6 +706,14 @@ class FieldSensitivePrunedLiveness {
696706 }
697707 }
698708
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+
699717 // / Populates the provided vector with contiguous ranges of bits which are
700718 // / users of the same sort.
701719 void getContiguousRanges (
@@ -838,6 +856,9 @@ class FieldSensitivePrunedLiveness {
838856 void updateForUse (SILInstruction *user, TypeTreeLeafTypeRange span,
839857 bool lifetimeEnding);
840858
859+ void updateForUse (SILInstruction *user, SmallBitVector const &bits,
860+ bool lifetimeEnding);
861+
841862 void getBlockLiveness (SILBasicBlock *bb, TypeTreeLeafTypeRange span,
842863 SmallVectorImpl<FieldSensitivePrunedLiveBlocks::IsLive>
843864 &resultingFoundLiveness) const {
@@ -862,6 +883,14 @@ class FieldSensitivePrunedLiveness {
862883 SmallBitVector &liveOutBits,
863884 SmallBitVector &deadBits) const ;
864885
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+
865894 // / If \p user has had uses recored, return a pointer to the InterestingUser
866895 // / where they've been recorded.
867896 InterestingUser const *getInterestingUser (SILInstruction *user) const {
@@ -885,11 +914,12 @@ class FieldSensitivePrunedLiveness {
885914 bool isInterestingUserOfKind (SILInstruction *user, IsInterestingUser kind,
886915 TypeTreeLeafTypeRange range) const {
887916 auto *record = getInterestingUser (user);
888- if (!record)
917+ if (!record) {
889918 return kind == IsInterestingUser::NonUser;
919+ }
890920
891921 for (auto element : range.getRange ()) {
892- if (isInterestingUser (user, element) != kind)
922+ if (record-> isInterestingUser (element) != kind)
893923 return false ;
894924 }
895925 return true ;
@@ -918,11 +948,12 @@ class FieldSensitivePrunedLiveness {
918948 // / argument must be copied.
919949 void addInterestingUser (SILInstruction *user, TypeTreeLeafTypeRange range,
920950 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);
926957 }
927958};
928959
@@ -1036,6 +1067,11 @@ class FieldSensitivePrunedLiveRange : public FieldSensitivePrunedLiveness {
10361067 void updateForUse (SILInstruction *user, TypeTreeLeafTypeRange span,
10371068 bool lifetimeEnding);
10381069
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+
10391075 // / Compute the boundary from the blocks discovered during liveness analysis.
10401076 // /
10411077 // / Precondition: \p liveness.getDiscoveredBlocks() is a valid list of all
@@ -1107,6 +1143,14 @@ class FieldSensitiveSSAPrunedLiveRange
11071143 return inst == defInst.first && defInst.second ->contains (bit);
11081144 }
11091145
1146+ bool isDef (SILInstruction *inst, SmallBitVector const &bits) const {
1147+ if (inst != defInst.first )
1148+ return false ;
1149+ SmallBitVector defBits (bits.size ());
1150+ defInst.second ->setBits (defBits);
1151+ return (defBits & bits) == bits;
1152+ }
1153+
11101154 bool isDef (SILInstruction *inst, TypeTreeLeafTypeRange span) const {
11111155 return inst == defInst.first &&
11121156 defInst.second ->setIntersection (span).has_value ();
@@ -1217,6 +1261,30 @@ class FieldSensitiveMultiDefPrunedLiveRange
12171261 *iter, [&](TypeTreeLeafTypeRange span) { return span.contains (bit); });
12181262 }
12191263
1264+ bool isDef (SILValue value, SmallBitVector const &bits) const {
1265+ assert (isInitialized ());
1266+ auto iter = defs.find (cast<SILNode>(value));
1267+ if (!iter)
1268+ return false ;
1269+ SmallBitVector allBits (bits.size ());
1270+ for (auto range : *iter) {
1271+ range.setBits (allBits);
1272+ }
1273+ return (bits & allBits) == bits;
1274+ }
1275+
1276+ bool isDef (SILInstruction *inst, SmallBitVector const &bits) const {
1277+ assert (isInitialized ());
1278+ auto iter = defs.find (cast<SILNode>(inst));
1279+ if (!iter)
1280+ return false ;
1281+ SmallBitVector allBits (bits.size ());
1282+ for (auto range : *iter) {
1283+ range.setBits (allBits);
1284+ }
1285+ return (bits & allBits) == bits;
1286+ }
1287+
12201288 bool isDef (SILInstruction *inst, TypeTreeLeafTypeRange span) const {
12211289 assert (isInitialized ());
12221290 auto iter = defs.find (cast<SILNode>(inst));
0 commit comments