@@ -384,6 +384,12 @@ struct TypeTreeLeafTypeRange {
384
384
endEltOffset >= range.endEltOffset ;
385
385
}
386
386
387
+ void setBits (SmallBitVector &bits) {
388
+ for (auto element : getRange ()) {
389
+ bits.set (element);
390
+ }
391
+ }
392
+
387
393
IntRange<unsigned > getRange () const {
388
394
return range (startEltOffset, endEltOffset);
389
395
}
@@ -692,17 +698,66 @@ class FieldSensitivePrunedLiveness {
692
698
FieldSensitivePrunedLiveBlocks liveBlocks;
693
699
694
700
public:
701
+ enum IsInterestingUser { NonUser, NonLifetimeEndingUse, LifetimeEndingUse };
702
+
695
703
struct InterestingUser {
696
- TypeTreeLeafTypeRange subEltSpan ;
697
- bool isConsuming ;
704
+ SmallBitVector liveBits ;
705
+ SmallBitVector consumingBits ;
698
706
699
- InterestingUser () : subEltSpan(), isConsuming(false ) {}
700
- InterestingUser (TypeTreeLeafTypeRange subEltSpan, bool isConsuming)
701
- : subEltSpan(subEltSpan), isConsuming(isConsuming) {}
707
+ // FIXME: FIXME_NOW: Where is this called from?
708
+ InterestingUser () {};
702
709
703
- InterestingUser &operator &=(bool otherValue) {
704
- isConsuming &= otherValue;
705
- return *this ;
710
+ InterestingUser (unsigned bitCount, TypeTreeLeafTypeRange range, bool lifetimeEnding) : liveBits(bitCount), consumingBits(bitCount) {
711
+ for (auto field : range.getRange ()) {
712
+ liveBits.set (field);
713
+ if (lifetimeEnding) {
714
+ consumingBits.set (field);
715
+ }
716
+ }
717
+ }
718
+
719
+ void getContiguousRanges (SmallVectorImpl<std::pair<TypeTreeLeafTypeRange, IsInterestingUser>> &ranges) const {
720
+ if (liveBits.size () == 0 )
721
+ return ;
722
+
723
+ assert (ranges.empty ());
724
+ Optional<std::pair<unsigned , IsInterestingUser>> current = llvm::None;
725
+ for (unsigned bit = 0 , size = liveBits.size (); bit < size; ++bit) {
726
+ auto interesting = isInterestingUser (bit);
727
+ if (!current) {
728
+ current = {bit, interesting};
729
+ continue ;
730
+ }
731
+ if (current->second != interesting) {
732
+ ranges.push_back ({TypeTreeLeafTypeRange (current->first , bit), current->second });
733
+ current = {bit, interesting};
734
+ }
735
+ }
736
+ ranges.push_back ({TypeTreeLeafTypeRange (current->first , liveBits.size ()), current->second });
737
+ }
738
+
739
+ // Optional<IsInterestingUser> isInterestingUserAtBits(SmallBitVector bits) const {
740
+ // if (bits.count() == 0)
741
+ // return NonUser;
742
+
743
+ // Optional<IsInterestingUser> retval = llvm::None;
744
+ // for (auto bit : bits.set_bits()) {
745
+ // auto interesting = isInterestingUser(bit);
746
+ // if (!retval) {
747
+ // retval = interesting;
748
+ // continue;
749
+ // }
750
+ // if (*retval != interesting)
751
+ // return llvm::None;
752
+ // }
753
+
754
+ // return retval;
755
+ // }
756
+
757
+ IsInterestingUser isInterestingUser (unsigned element) const {
758
+ if (!liveBits.test (element))
759
+ return NonUser;
760
+ return consumingBits.test (element) ? LifetimeEndingUse : NonLifetimeEndingUse;
706
761
}
707
762
};
708
763
@@ -788,37 +843,37 @@ class FieldSensitivePrunedLiveness {
788
843
UserRange,
789
844
function_ref<Optional<std::pair<SILInstruction *, TypeTreeLeafTypeRange>>(
790
845
const std::pair<SILInstruction *, InterestingUser> &)>>;
791
- LifetimeEndingUserRange getAllLifetimeEndingUses () const {
792
- assert (isInitialized ());
793
- function_ref<Optional<std::pair<SILInstruction *, TypeTreeLeafTypeRange>>(
794
- const std::pair<SILInstruction *, InterestingUser> &)>
795
- op;
796
- op = [](const std::pair<SILInstruction *, InterestingUser> &pair)
797
- -> Optional<std::pair<SILInstruction *, TypeTreeLeafTypeRange>> {
798
- if (pair.second .isConsuming )
799
- return {{pair.first , pair.second .subEltSpan }};
800
- return None;
801
- };
802
- return LifetimeEndingUserRange (getAllUsers (), op);
803
- }
846
+ // LifetimeEndingUserRange getAllLifetimeEndingUses() const {
847
+ // assert(isInitialized());
848
+ // function_ref<Optional<std::pair<SILInstruction *, TypeTreeLeafTypeRange>>(
849
+ // const std::pair<SILInstruction *, InterestingUser> &)>
850
+ // op;
851
+ // op = [](const std::pair<SILInstruction *, InterestingUser> &pair)
852
+ // -> Optional<std::pair<SILInstruction *, TypeTreeLeafTypeRange>> {
853
+ // if (pair.second.isConsuming)
854
+ // return {{pair.first, pair.second.subEltSpan}};
855
+ // return None;
856
+ // };
857
+ // return LifetimeEndingUserRange(getAllUsers(), op);
858
+ // }
804
859
805
860
using NonLifetimeEndingUserRange = OptionalTransformRange<
806
861
UserRange,
807
862
function_ref<Optional<std::pair<SILInstruction *, TypeTreeLeafTypeRange>>(
808
863
const std::pair<SILInstruction *, InterestingUser> &)>>;
809
- NonLifetimeEndingUserRange getAllNonLifetimeEndingUses () const {
810
- assert (isInitialized ());
811
- function_ref<Optional<std::pair<SILInstruction *, TypeTreeLeafTypeRange>>(
812
- const std::pair<SILInstruction *, InterestingUser> &)>
813
- op;
814
- op = [](const std::pair<SILInstruction *, InterestingUser> &pair)
815
- -> Optional<std::pair<SILInstruction *, TypeTreeLeafTypeRange>> {
816
- if (!pair.second .isConsuming )
817
- return {{pair.first , pair.second .subEltSpan }};
818
- return None;
819
- };
820
- return NonLifetimeEndingUserRange (getAllUsers (), op);
821
- }
864
+ // NonLifetimeEndingUserRange getAllNonLifetimeEndingUses() const {
865
+ // assert(isInitialized());
866
+ // function_ref<Optional<std::pair<SILInstruction *, TypeTreeLeafTypeRange>>(
867
+ // const std::pair<SILInstruction *, InterestingUser> &)>
868
+ // op;
869
+ // op = [](const std::pair<SILInstruction *, InterestingUser> &pair)
870
+ // -> Optional<std::pair<SILInstruction *, TypeTreeLeafTypeRange>> {
871
+ // if (!pair.second.isConsuming)
872
+ // return {{pair.first, pair.second.subEltSpan}};
873
+ // return None;
874
+ // };
875
+ // return NonLifetimeEndingUserRange(getAllUsers(), op);
876
+ // }
822
877
823
878
using UserBlockRange = TransformRange<
824
879
UserRange, function_ref<SILBasicBlock *(
@@ -874,19 +929,41 @@ class FieldSensitivePrunedLiveness {
874
929
SmallBitVector &liveOutBits,
875
930
SmallBitVector &deadBits) const ;
876
931
877
- enum IsInterestingUser { NonUser, NonLifetimeEndingUse, LifetimeEndingUse };
932
+ InterestingUser const *getInterestingUser (SILInstruction *user) const {
933
+ auto iter = users.find (user);
934
+ if (iter == users.end ())
935
+ return nullptr ;
936
+ return &iter->second ;
937
+ }
878
938
879
939
// / Return a result indicating whether the given user was identified as an
880
940
// / interesting use of the current def and whether it ends the lifetime.
881
- std::pair< IsInterestingUser, Optional<TypeTreeLeafTypeRange>>
882
- isInterestingUser (SILInstruction *user) const {
941
+ IsInterestingUser
942
+ isInterestingUser (SILInstruction *user, unsigned element ) const {
883
943
assert (isInitialized ());
884
944
auto useIter = users.find (user);
885
945
if (useIter == users.end ())
886
- return {NonUser, None};
887
- auto isInteresting =
888
- useIter->second .isConsuming ? LifetimeEndingUse : NonLifetimeEndingUse;
889
- return {isInteresting, useIter->second .subEltSpan };
946
+ return NonUser;
947
+ auto &record = useIter->second ;
948
+ return record.isInterestingUser (element);
949
+ }
950
+
951
+ bool isInterestingUserOfKindThroughoutRange (SILInstruction *user, IsInterestingUser kind, TypeTreeLeafTypeRange range) const {
952
+ assert (kind != NonUser);
953
+ bool wantsConsuming = (kind == LifetimeEndingUse);
954
+
955
+ auto iter = users.find (user);
956
+ if (iter == users.end ())
957
+ return false ;
958
+ auto &record = iter->second ;
959
+ for (auto element : range.getRange ()) {
960
+ if (!record.liveBits .test (element))
961
+ return false ;
962
+ auto consuming = record.consumingBits .test (element);
963
+ if (consuming != wantsConsuming)
964
+ return false ;
965
+ }
966
+ return true ;
890
967
}
891
968
892
969
unsigned getNumSubElements () const { return liveBlocks.getNumBitsToTrack (); }
@@ -912,11 +989,15 @@ class FieldSensitivePrunedLiveness {
912
989
// / argument must be copied.
913
990
void addInterestingUser (SILInstruction *user, TypeTreeLeafTypeRange range,
914
991
bool lifetimeEnding) {
915
- auto iterAndSuccess =
916
- users.insert ({user, InterestingUser (range, lifetimeEnding)});
917
- if (!iterAndSuccess.second ) {
918
- iterAndSuccess.first ->second .subEltSpan .extendThrough (range);
919
- iterAndSuccess.first ->second &= lifetimeEnding;
992
+ auto iter = users.find (user);
993
+ if (iter == users.end ()) {
994
+ iter = users.insert ({user, InterestingUser (getNumSubElements (), range, lifetimeEnding)}).first ;
995
+ }
996
+ for (auto element : range.getRange ()) {
997
+ iter->second .liveBits .set (element);
998
+ if (lifetimeEnding) {
999
+ iter->second .consumingBits .set (element);
1000
+ }
920
1001
}
921
1002
}
922
1003
};
0 commit comments