Skip to content

Commit 0b09ed6

Browse files
committed
NFC: CopyPropagation: Replaced copy walk with set.
Whenever attempting to determine whether a given instruction is a destroy of the def being canonicalized, just check for membership in the set of destroys that's already collected.
1 parent dfcc4fc commit 0b09ed6

File tree

1 file changed

+39
-25
lines changed

1 file changed

+39
-25
lines changed

lib/SILOptimizer/Utils/CanonicalizeOSSALifetime.cpp

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ void CanonicalizeOSSALifetime::extendUnconsumedLiveness(
511511
// destroys.
512512
BasicBlockWorklist worklist(currentDef->getFunction());
513513
for (auto *instruction : boundary.lastUsers) {
514-
if (dynCastToDestroyOf(instruction, getCurrentDef()))
514+
if (destroys.contains(instruction))
515515
continue;
516516
if (liveness->isInterestingUser(instruction)
517517
!= PrunedLiveness::IsInterestingUser::LifetimeEndingUse)
@@ -576,17 +576,20 @@ namespace {
576576
/// values with overlapping live ranges and failing to find a fixed point
577577
/// because their destroys are repeatedly hoisted over one another.
578578
class ExtendBoundaryToDestroys final {
579+
using InstructionPredicate = llvm::function_ref<bool(SILInstruction *)>;
579580
SSAPrunedLiveness &liveness;
580581
PrunedLivenessBoundary const &originalBoundary;
581582
SILValue currentDef;
582583
BasicBlockSet seenMergePoints;
584+
InstructionPredicate isDestroy;
583585

584586
public:
585587
ExtendBoundaryToDestroys(SSAPrunedLiveness &liveness,
586588
PrunedLivenessBoundary const &originalBoundary,
587-
SILValue currentDef)
589+
SILValue currentDef, InstructionPredicate isDestroy)
588590
: liveness(liveness), originalBoundary(originalBoundary),
589-
currentDef(currentDef), seenMergePoints(currentDef->getFunction()){};
591+
currentDef(currentDef), seenMergePoints(currentDef->getFunction()),
592+
isDestroy(isDestroy){};
590593
ExtendBoundaryToDestroys(ExtendBoundaryToDestroys const &) = delete;
591594
ExtendBoundaryToDestroys &
592595
operator=(ExtendBoundaryToDestroys const &) = delete;
@@ -610,34 +613,37 @@ class ExtendBoundaryToDestroys final {
610613
/// Look past ignoreable instructions to find the _last_ destroy after the
611614
/// specified instruction that destroys \p def.
612615
static DestroyValueInst *findDestroyAfter(SILInstruction *previous,
613-
SILValue def) {
616+
SILValue def,
617+
InstructionPredicate isDestroy) {
614618
DestroyValueInst *retval = nullptr;
615619
for (auto *instruction = previous->getNextInstruction(); instruction;
616620
instruction = instruction->getNextInstruction()) {
617621
if (!CanonicalizeOSSALifetime::ignoredByDestroyHoisting(
618622
instruction->getKind()))
619623
break;
620-
if (auto destroy = dynCastToDestroyOf(instruction, def))
621-
retval = destroy;
624+
if (isDestroy(instruction))
625+
retval = cast<DestroyValueInst>(instruction);
622626
}
623627
return retval;
624628
}
625629

626630
/// Look past ignoreable instructions to find the _last_ destroy at or after
627631
/// 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);
633638
}
634639

635640
/// Look past ignoreable instructions to find the _first_ destroy in \p
636641
/// destination that destroys \p def and isn't separated from the beginning
637642
/// 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);
641647
}
642648

643649
private:
@@ -651,12 +657,14 @@ class ExtendBoundaryToDestroys final {
651657
/// stays in place and \p def remains a dead def.
652658
void extendBoundaryFromDef(SILNode *def, PrunedLivenessBoundary &boundary) {
653659
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)) {
655662
boundary.lastUsers.push_back(dvi);
656663
return;
657664
}
658665
} else {
659-
if (auto *dvi = findDestroyAfter(cast<SILInstruction>(def), currentDef)) {
666+
if (auto *dvi = findDestroyAfter(cast<SILInstruction>(def), currentDef,
667+
isDestroy)) {
660668
boundary.lastUsers.push_back(dvi);
661669
return;
662670
}
@@ -673,7 +681,8 @@ class ExtendBoundaryToDestroys final {
673681
/// stays in place and \p destination remains a boundary edge.
674682
void extendBoundaryFromBoundaryEdge(SILBasicBlock *destination,
675683
PrunedLivenessBoundary &boundary) {
676-
if (auto *dvi = findDestroyFromBlockBegin(destination, currentDef)) {
684+
if (auto *dvi =
685+
findDestroyFromBlockBegin(destination, currentDef, isDestroy)) {
677686
boundary.lastUsers.push_back(dvi);
678687
} else {
679688
boundary.boundaryEdges.push_back(destination);
@@ -694,8 +703,9 @@ class ExtendBoundaryToDestroys final {
694703
/// user remains a last user.
695704
void extendBoundaryFromUser(SILInstruction *user,
696705
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);
699709
assert(existingDestroy && "couldn't find a destroy at or after one!?");
700710
boundary.lastUsers.push_back(existingDestroy);
701711
return;
@@ -713,7 +723,8 @@ class ExtendBoundaryToDestroys final {
713723
extendBoundaryFromTerminator(terminator, boundary);
714724
return;
715725
}
716-
if (auto *existingDestroy = findDestroyAfter(user, currentDef)) {
726+
if (auto *existingDestroy =
727+
findDestroyAfter(user, currentDef, isDestroy)) {
717728
boundary.lastUsers.push_back(existingDestroy);
718729
return;
719730
}
@@ -745,7 +756,8 @@ class ExtendBoundaryToDestroys final {
745756
assert(block->getSingleSuccessorBlock() == successor);
746757
continue;
747758
}
748-
if (auto *dvi = findDestroyFromBlockBegin(successor, currentDef)) {
759+
if (auto *dvi =
760+
findDestroyFromBlockBegin(successor, currentDef, isDestroy)) {
749761
boundary.lastUsers.push_back(dvi);
750762
foundDestroy = true;
751763
} else {
@@ -770,8 +782,9 @@ void CanonicalizeOSSALifetime::findExtendedBoundary(
770782
PrunedLivenessBoundary &boundary) {
771783
assert(boundary.lastUsers.size() == 0 && boundary.boundaryEdges.size() == 0 &&
772784
boundary.deadDefs.size() == 0);
785+
auto isDestroy = [&](auto *inst) { return destroys.contains(inst); };
773786
ExtendBoundaryToDestroys extender(*liveness, originalBoundary,
774-
getCurrentDef());
787+
getCurrentDef(), isDestroy);
775788
extender.extend(boundary);
776789
}
777790

@@ -806,8 +819,8 @@ void CanonicalizeOSSALifetime::insertDestroysOnBoundary(
806819
PrunedLivenessBoundary const &boundary) {
807820
BasicBlockSet seenMergePoints(getCurrentDef()->getFunction());
808821
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);
811824
continue;
812825
}
813826
switch (liveness->isInterestingUser(instruction)) {
@@ -905,7 +918,8 @@ void CanonicalizeOSSALifetime::rewriteCopies() {
905918
defUseWorklist.insert(copy);
906919
return true;
907920
}
908-
if (auto *destroy = dynCastToDestroyOf(user, getCurrentDef())) {
921+
if (destroys.contains(user)) {
922+
auto *destroy = cast<DestroyValueInst>(user);
909923
// If this destroy was marked as a final destroy, ignore it; otherwise,
910924
// delete it.
911925
if (!consumes.claimConsume(destroy)) {

0 commit comments

Comments
 (0)