@@ -511,7 +511,7 @@ void CanonicalizeOSSALifetime::extendUnconsumedLiveness(
511
511
// destroys.
512
512
BasicBlockWorklist worklist (currentDef->getFunction ());
513
513
for (auto *instruction : boundary.lastUsers ) {
514
- if (dynCastToDestroyOf (instruction, getCurrentDef () ))
514
+ if (destroys. contains (instruction))
515
515
continue ;
516
516
if (liveness->isInterestingUser (instruction)
517
517
!= PrunedLiveness::IsInterestingUser::LifetimeEndingUse)
@@ -576,17 +576,20 @@ namespace {
576
576
// / values with overlapping live ranges and failing to find a fixed point
577
577
// / because their destroys are repeatedly hoisted over one another.
578
578
class ExtendBoundaryToDestroys final {
579
+ using InstructionPredicate = llvm::function_ref<bool (SILInstruction *)>;
579
580
SSAPrunedLiveness &liveness;
580
581
PrunedLivenessBoundary const &originalBoundary;
581
582
SILValue currentDef;
582
583
BasicBlockSet seenMergePoints;
584
+ InstructionPredicate isDestroy;
583
585
584
586
public:
585
587
ExtendBoundaryToDestroys (SSAPrunedLiveness &liveness,
586
588
PrunedLivenessBoundary const &originalBoundary,
587
- SILValue currentDef)
589
+ SILValue currentDef, InstructionPredicate isDestroy )
588
590
: liveness(liveness), originalBoundary(originalBoundary),
589
- currentDef (currentDef), seenMergePoints(currentDef->getFunction ()){};
591
+ currentDef (currentDef), seenMergePoints(currentDef->getFunction ()),
592
+ isDestroy(isDestroy){};
590
593
ExtendBoundaryToDestroys (ExtendBoundaryToDestroys const &) = delete;
591
594
ExtendBoundaryToDestroys &
592
595
operator =(ExtendBoundaryToDestroys const &) = delete;
@@ -610,34 +613,37 @@ class ExtendBoundaryToDestroys final {
610
613
// / Look past ignoreable instructions to find the _last_ destroy after the
611
614
// / specified instruction that destroys \p def.
612
615
static DestroyValueInst *findDestroyAfter (SILInstruction *previous,
613
- SILValue def) {
616
+ SILValue def,
617
+ InstructionPredicate isDestroy) {
614
618
DestroyValueInst *retval = nullptr ;
615
619
for (auto *instruction = previous->getNextInstruction (); instruction;
616
620
instruction = instruction->getNextInstruction ()) {
617
621
if (!CanonicalizeOSSALifetime::ignoredByDestroyHoisting (
618
622
instruction->getKind ()))
619
623
break ;
620
- if (auto destroy = dynCastToDestroyOf (instruction, def ))
621
- retval = destroy ;
624
+ if (isDestroy (instruction))
625
+ retval = cast<DestroyValueInst>(instruction) ;
622
626
}
623
627
return retval;
624
628
}
625
629
626
630
// / Look past ignoreable instructions to find the _last_ destroy at or after
627
631
// / the specified instruction that destroys \p def.
628
- static DestroyValueInst *findDestroyAtOrAfter (SILInstruction *start,
629
- SILValue def) {
630
- if (auto *dvi = dynCastToDestroyOf (start, def))
631
- return dvi;
632
- return findDestroyAfter (start, def);
632
+ static DestroyValueInst *
633
+ findDestroyAtOrAfter (SILInstruction *start, SILValue def,
634
+ InstructionPredicate isDestroy) {
635
+ if (isDestroy (start))
636
+ return cast<DestroyValueInst>(start);
637
+ return findDestroyAfter (start, def, isDestroy);
633
638
}
634
639
635
640
// / Look past ignoreable instructions to find the _first_ destroy in \p
636
641
// / destination that destroys \p def and isn't separated from the beginning
637
642
// / by "interesting" instructions.
638
- static DestroyValueInst *findDestroyFromBlockBegin (SILBasicBlock *destination,
639
- SILValue def) {
640
- return findDestroyAtOrAfter (&*destination->begin (), def);
643
+ static DestroyValueInst *
644
+ findDestroyFromBlockBegin (SILBasicBlock *destination, SILValue def,
645
+ InstructionPredicate isDestroy) {
646
+ return findDestroyAtOrAfter (&*destination->begin (), def, isDestroy);
641
647
}
642
648
643
649
private:
@@ -651,12 +657,14 @@ class ExtendBoundaryToDestroys final {
651
657
// / stays in place and \p def remains a dead def.
652
658
void extendBoundaryFromDef (SILNode *def, PrunedLivenessBoundary &boundary) {
653
659
if (auto *arg = dyn_cast<SILArgument>(def)) {
654
- if (auto *dvi = findDestroyFromBlockBegin (arg->getParent (), currentDef)) {
660
+ if (auto *dvi = findDestroyFromBlockBegin (arg->getParent (), currentDef,
661
+ isDestroy)) {
655
662
boundary.lastUsers .push_back (dvi);
656
663
return ;
657
664
}
658
665
} else {
659
- if (auto *dvi = findDestroyAfter (cast<SILInstruction>(def), currentDef)) {
666
+ if (auto *dvi = findDestroyAfter (cast<SILInstruction>(def), currentDef,
667
+ isDestroy)) {
660
668
boundary.lastUsers .push_back (dvi);
661
669
return ;
662
670
}
@@ -673,7 +681,8 @@ class ExtendBoundaryToDestroys final {
673
681
// / stays in place and \p destination remains a boundary edge.
674
682
void extendBoundaryFromBoundaryEdge (SILBasicBlock *destination,
675
683
PrunedLivenessBoundary &boundary) {
676
- if (auto *dvi = findDestroyFromBlockBegin (destination, currentDef)) {
684
+ if (auto *dvi =
685
+ findDestroyFromBlockBegin (destination, currentDef, isDestroy)) {
677
686
boundary.lastUsers .push_back (dvi);
678
687
} else {
679
688
boundary.boundaryEdges .push_back (destination);
@@ -694,8 +703,9 @@ class ExtendBoundaryToDestroys final {
694
703
// / user remains a last user.
695
704
void extendBoundaryFromUser (SILInstruction *user,
696
705
PrunedLivenessBoundary &boundary) {
697
- if (auto *dvi = dynCastToDestroyOf (user, currentDef)) {
698
- auto *existingDestroy = findDestroyAtOrAfter (dvi, currentDef);
706
+ if (isDestroy (user)) {
707
+ auto *dvi = cast<DestroyValueInst>(user);
708
+ auto *existingDestroy = findDestroyAtOrAfter (dvi, currentDef, isDestroy);
699
709
assert (existingDestroy && " couldn't find a destroy at or after one!?" );
700
710
boundary.lastUsers .push_back (existingDestroy);
701
711
return ;
@@ -713,7 +723,8 @@ class ExtendBoundaryToDestroys final {
713
723
extendBoundaryFromTerminator (terminator, boundary);
714
724
return ;
715
725
}
716
- if (auto *existingDestroy = findDestroyAfter (user, currentDef)) {
726
+ if (auto *existingDestroy =
727
+ findDestroyAfter (user, currentDef, isDestroy)) {
717
728
boundary.lastUsers .push_back (existingDestroy);
718
729
return ;
719
730
}
@@ -745,7 +756,8 @@ class ExtendBoundaryToDestroys final {
745
756
assert (block->getSingleSuccessorBlock () == successor);
746
757
continue ;
747
758
}
748
- if (auto *dvi = findDestroyFromBlockBegin (successor, currentDef)) {
759
+ if (auto *dvi =
760
+ findDestroyFromBlockBegin (successor, currentDef, isDestroy)) {
749
761
boundary.lastUsers .push_back (dvi);
750
762
foundDestroy = true ;
751
763
} else {
@@ -770,8 +782,9 @@ void CanonicalizeOSSALifetime::findExtendedBoundary(
770
782
PrunedLivenessBoundary &boundary) {
771
783
assert (boundary.lastUsers .size () == 0 && boundary.boundaryEdges .size () == 0 &&
772
784
boundary.deadDefs .size () == 0 );
785
+ auto isDestroy = [&](auto *inst) { return destroys.contains (inst); };
773
786
ExtendBoundaryToDestroys extender (*liveness, originalBoundary,
774
- getCurrentDef ());
787
+ getCurrentDef (), isDestroy );
775
788
extender.extend (boundary);
776
789
}
777
790
@@ -806,8 +819,8 @@ void CanonicalizeOSSALifetime::insertDestroysOnBoundary(
806
819
PrunedLivenessBoundary const &boundary) {
807
820
BasicBlockSet seenMergePoints (getCurrentDef ()->getFunction ());
808
821
for (auto *instruction : boundary.lastUsers ) {
809
- if (auto *dvi = dynCastToDestroyOf (instruction, getCurrentDef () )) {
810
- consumes.recordFinalConsume (dvi );
822
+ if (destroys. contains (instruction)) {
823
+ consumes.recordFinalConsume (instruction );
811
824
continue ;
812
825
}
813
826
switch (liveness->isInterestingUser (instruction)) {
@@ -905,7 +918,8 @@ void CanonicalizeOSSALifetime::rewriteCopies() {
905
918
defUseWorklist.insert (copy);
906
919
return true ;
907
920
}
908
- if (auto *destroy = dynCastToDestroyOf (user, getCurrentDef ())) {
921
+ if (destroys.contains (user)) {
922
+ auto *destroy = cast<DestroyValueInst>(user);
909
923
// If this destroy was marked as a final destroy, ignore it; otherwise,
910
924
// delete it.
911
925
if (!consumes.claimConsume (destroy)) {
0 commit comments