@@ -505,6 +505,7 @@ void FieldSensitivePrunedLiveBlocks::computeScalarUseBlockLiveness(
505
505
// / Terminators are not live out of the block.
506
506
void FieldSensitivePrunedLiveBlocks::updateForUse (
507
507
SILInstruction *user, unsigned startBitNo, unsigned endBitNo,
508
+ SmallBitVector const &useBeforeDefBits,
508
509
SmallVectorImpl<IsLive> &resultingLivenessInfo) {
509
510
assert (isInitialized ());
510
511
resultingLivenessInfo.clear ();
@@ -517,10 +518,15 @@ void FieldSensitivePrunedLiveBlocks::updateForUse(
517
518
518
519
for (unsigned index : indices (resultingLivenessInfo)) {
519
520
unsigned specificBitNo = startBitNo + index;
521
+ auto isUseBeforeDef = useBeforeDefBits.test (specificBitNo);
520
522
switch (resultingLivenessInfo[index]) {
521
523
case LiveOut:
522
524
case LiveWithin:
523
- continue ;
525
+ if (!isUseBeforeDef) {
526
+ continue ;
527
+ } else {
528
+ LLVM_FALLTHROUGH;
529
+ }
524
530
case Dead: {
525
531
// This use block has not yet been marked live. Mark it and its
526
532
// predecessor blocks live.
@@ -599,21 +605,21 @@ void FieldSensitivePrunedLivenessBoundary::dump() const {
599
605
// MARK: FieldSensitiveLiveness
600
606
// ===----------------------------------------------------------------------===//
601
607
602
- void FieldSensitivePrunedLiveness::updateForUse (SILInstruction *user,
603
- TypeTreeLeafTypeRange range,
604
- bool lifetimeEnding ) {
608
+ void FieldSensitivePrunedLiveness::updateForUse (
609
+ SILInstruction *user, TypeTreeLeafTypeRange range, bool lifetimeEnding ,
610
+ SmallBitVector const &useBeforeDefBits ) {
605
611
SmallVector<FieldSensitivePrunedLiveBlocks::IsLive, 8 > resultingLiveness;
606
612
liveBlocks.updateForUse (user, range.startEltOffset , range.endEltOffset ,
607
- resultingLiveness);
613
+ useBeforeDefBits, resultingLiveness);
608
614
609
615
addInterestingUser (user, range, lifetimeEnding);
610
616
}
611
617
612
- void FieldSensitivePrunedLiveness::updateForUse (SILInstruction *user,
613
- SmallBitVector const &bits,
614
- bool lifetimeEnding ) {
618
+ void FieldSensitivePrunedLiveness::updateForUse (
619
+ SILInstruction *user, SmallBitVector const &bits, bool lifetimeEnding ,
620
+ SmallBitVector const &useBeforeDefBits ) {
615
621
for (auto bit : bits.set_bits ()) {
616
- liveBlocks.updateForUse (user, bit);
622
+ liveBlocks.updateForUse (user, bit, useBeforeDefBits. test (bit) );
617
623
}
618
624
619
625
addInterestingUser (user, bits, lifetimeEnding);
@@ -798,74 +804,46 @@ void FieldSensitivePrunedLiveRange<LivenessWithDefs>::computeBoundary(
798
804
}
799
805
}
800
806
807
+ bool FieldSensitiveMultiDefPrunedLiveRange::isUserBeforeDef (
808
+ SILInstruction *user, unsigned element) const {
809
+ auto *block = user->getParent ();
810
+ if (!isDefBlock (block, element))
811
+ return false ;
812
+
813
+ if (llvm::any_of (block->getArguments (), [this , element](SILArgument *arg) {
814
+ return isDef (arg, element);
815
+ })) {
816
+ return false ;
817
+ }
818
+
819
+ auto *current = user;
820
+ while (true ) {
821
+ // If user is also a def, then the use is considered before the def.
822
+ current = current->getPreviousInstruction ();
823
+ if (!current)
824
+ return true ;
825
+
826
+ if (isDef (current, element))
827
+ return false ;
828
+ }
829
+ }
830
+
801
831
template <typename LivenessWithDefs>
802
832
void FieldSensitivePrunedLiveRange<LivenessWithDefs>::updateForUse(
803
833
SILInstruction *user, TypeTreeLeafTypeRange range, bool lifetimeEnding) {
804
- PRUNED_LIVENESS_LOG (
805
- llvm::dbgs ()
806
- << " Begin FieldSensitivePrunedLiveRange<LivenessWithDefs>::updateForUse "
807
- " for: "
808
- << *user);
809
- PRUNED_LIVENESS_LOG (
810
- llvm::dbgs () << " Looking for def instruction earlier in the block!\n " );
811
-
812
- auto *parentBlock = user->getParent ();
813
- for (auto ii = std::next (user->getReverseIterator ()),
814
- ie = parentBlock->rend ();
815
- ii != ie; ++ii) {
816
- // If we find the def, just mark this instruction as being an interesting
817
- // instruction.
818
- if (asImpl ().isDef (&*ii, range)) {
819
- PRUNED_LIVENESS_LOG (llvm::dbgs () << " Found def: " << *ii);
820
- PRUNED_LIVENESS_LOG (llvm::dbgs ()
821
- << " Marking inst as interesting user and returning!\n " );
822
- addInterestingUser (user, range, lifetimeEnding);
823
- return ;
824
- }
825
- }
826
-
827
- // Otherwise, just delegate to our parent class's update for use. This will
828
- // update liveness for our predecessor blocks and add this instruction as an
829
- // interesting user.
830
- PRUNED_LIVENESS_LOG (llvm::dbgs () << " No defs found! Delegating to "
831
- " FieldSensitivePrunedLiveness::updateForUse.\n " );
832
- FieldSensitivePrunedLiveness::updateForUse (user, range, lifetimeEnding);
834
+ SmallBitVector useBeforeDefBits (getNumSubElements ());
835
+ asImpl ().isUserBeforeDef (user, range.getRange (), useBeforeDefBits);
836
+ FieldSensitivePrunedLiveness::updateForUse (user, range, lifetimeEnding,
837
+ useBeforeDefBits);
833
838
}
834
839
835
840
template <typename LivenessWithDefs>
836
841
void FieldSensitivePrunedLiveRange<LivenessWithDefs>::updateForUse(
837
842
SILInstruction *user, SmallBitVector const &bits, bool lifetimeEnding) {
838
- PRUNED_LIVENESS_LOG (
839
- llvm::dbgs ()
840
- << " Begin FieldSensitivePrunedLiveRange<LivenessWithDefs>::updateForUse "
841
- " for: "
842
- << *user);
843
- PRUNED_LIVENESS_LOG (llvm::dbgs ()
844
- << " Looking for def instruction earlier in the block!\n " );
845
-
846
- auto *parentBlock = user->getParent ();
847
- for (auto ii = std::next (user->getReverseIterator ()),
848
- ie = parentBlock->rend ();
849
- ii != ie; ++ii) {
850
- // If we find the def, just mark this instruction as being an interesting
851
- // instruction.
852
- if (asImpl ().isDef (&*ii, bits)) {
853
- PRUNED_LIVENESS_LOG (llvm::dbgs () << " Found def: " << *ii);
854
- PRUNED_LIVENESS_LOG (
855
- llvm::dbgs ()
856
- << " Marking inst as interesting user and returning!\n " );
857
- addInterestingUser (user, bits, lifetimeEnding);
858
- return ;
859
- }
860
- }
861
-
862
- // Otherwise, just delegate to our parent class's update for use. This will
863
- // update liveness for our predecessor blocks and add this instruction as an
864
- // interesting user.
865
- PRUNED_LIVENESS_LOG (llvm::dbgs ()
866
- << " No defs found! Delegating to "
867
- " FieldSensitivePrunedLiveness::updateForUse.\n " );
868
- FieldSensitivePrunedLiveness::updateForUse (user, bits, lifetimeEnding);
843
+ SmallBitVector useBeforeDefBits (getNumSubElements ());
844
+ asImpl ().isUserBeforeDef (user, bits.set_bits (), useBeforeDefBits);
845
+ FieldSensitivePrunedLiveness::updateForUse (user, bits, lifetimeEnding,
846
+ useBeforeDefBits);
869
847
}
870
848
871
849
// ===----------------------------------------------------------------------===//
0 commit comments