@@ -443,38 +443,26 @@ class CopyPropagation : public SILFunctionTransform {
443443 // / The entry point to this function transformation.
444444 void run () override ;
445445
446+ void propagateCopies (CanonicalDefWorklist &defWorklist, bool &changed,
447+ NonLocalAccessBlockAnalysis *accessBlockAnalysis,
448+ InstructionDeleter &deleter);
449+
446450 void verifyOwnership ();
447451};
448452
449453} // end anonymous namespace
450454
451- // / Top-level pass driver.
452- void CopyPropagation::run () {
455+ void CopyPropagation::propagateCopies (
456+ CanonicalDefWorklist &defWorklist, bool &changed,
457+ NonLocalAccessBlockAnalysis *accessBlockAnalysis,
458+ InstructionDeleter &deleter) {
453459 auto *f = getFunction ();
454460 auto *postOrderAnalysis = getAnalysis<PostOrderAnalysis>();
455- auto *accessBlockAnalysis = getAnalysis<NonLocalAccessBlockAnalysis>();
456461 auto *deadEndBlocksAnalysis = getAnalysis<DeadEndBlocksAnalysis>();
457462 auto *dominanceAnalysis = getAnalysis<DominanceAnalysis>();
458463 auto *calleeAnalysis = getAnalysis<BasicCalleeAnalysis>();
459464 DominanceInfo *domTree = dominanceAnalysis->get (f);
460465
461- // Label for unit testing with debug output.
462- LLVM_DEBUG (llvm::dbgs () << " *** CopyPropagation: " << f->getName () << " \n " );
463-
464- // This algorithm fundamentally assumes ownership.
465- if (!f->hasOwnership ())
466- return ;
467-
468- CanonicalDefWorklist defWorklist (canonicalizeBorrows);
469- auto callbacks =
470- InstModCallbacks ().onDelete ([&](SILInstruction *instToDelete) {
471- defWorklist.erase (instToDelete);
472- instToDelete->eraseFromParent ();
473- });
474-
475- InstructionDeleter deleter (std::move (callbacks));
476- bool changed = false ;
477-
478466 StackList<BeginBorrowInst *> beginBorrowsToShrink (f);
479467 StackList<MoveValueInst *> moveValues (f);
480468
@@ -514,6 +502,8 @@ void CopyPropagation::run() {
514502 // at least once and then until each stops making changes.
515503 while (true ) {
516504 SmallVector<CopyValueInst *, 4 > modifiedCopyValueInsts;
505+ if (!continueWithNextSubpassRun (bbi))
506+ return ;
517507 auto shrunk = shrinkBorrowScope (*bbi, deleter, calleeAnalysis,
518508 modifiedCopyValueInsts);
519509 for (auto *cvi : modifiedCopyValueInsts)
@@ -528,25 +518,35 @@ void CopyPropagation::run() {
528518 if (borrowee->getOwnershipKind () != OwnershipKind::Owned)
529519 break ;
530520
521+ if (!continueWithNextSubpassRun (borrowee))
522+ return ;
531523 auto canonicalized = canonicalizer.canonicalizeValueLifetime (borrowee);
532524 if (!canonicalized && !firstRun)
533525 break ;
534526
527+ if (!continueWithNextSubpassRun (bbi))
528+ return ;
535529 auto folded = foldDestroysOfCopiedLexicalBorrow (bbi, *domTree, deleter);
536530 if (!folded)
537531 break ;
538532 auto hoisted = canonicalizer.canonicalizeValueLifetime (folded);
539533 // Keep running even if the new move's destroys can't be hoisted.
540534 (void )hoisted;
535+ if (!continueWithNextSubpassRun (folded))
536+ return ;
541537 eliminateRedundantMove (folded, deleter, defWorklist);
542538 firstRun = false ;
543539 }
544540 }
545541 for (auto *mvi : moveValues) {
542+ if (!continueWithNextSubpassRun (mvi))
543+ return ;
546544 eliminateRedundantMove (mvi, deleter, defWorklist);
547545 }
548546 for (auto *argument : f->getArguments ()) {
549547 if (argument->getOwnershipKind () == OwnershipKind::Owned) {
548+ if (!continueWithNextSubpassRun (argument))
549+ return ;
550550 canonicalizer.canonicalizeValueLifetime (argument);
551551 }
552552 }
@@ -584,8 +584,12 @@ void CopyPropagation::run() {
584584 // they may be chained, and CanonicalizeBorrowScopes pushes them
585585 // top-down.
586586 for (auto result : ownedForward->getResults ()) {
587+ if (!continueWithNextSubpassRun (result))
588+ return ;
587589 canonicalizer.canonicalizeValueLifetime (result);
588590 }
591+ if (!continueWithNextSubpassRun (ownedForward))
592+ return ;
589593 if (sinkOwnedForward (ownedForward, postOrderAnalysis, domTree)) {
590594 changed = true ;
591595 // Sinking 'ownedForward' may create an opportunity to sink its
@@ -607,6 +611,8 @@ void CopyPropagation::run() {
607611 BorrowedValue borrow (defWorklist.borrowedValues .pop_back_val ());
608612 assert (canonicalizeBorrows || !borrow.isLocalScope ());
609613
614+ if (!continueWithNextSubpassRun (borrow.value ))
615+ return ;
610616 borrowCanonicalizer.canonicalizeBorrowScope (borrow);
611617 for (CopyValueInst *copy : borrowCanonicalizer.getUpdatedCopies ()) {
612618 defWorklist.updateForCopy (copy);
@@ -623,13 +629,41 @@ void CopyPropagation::run() {
623629 // Canonicalize all owned defs.
624630 while (!defWorklist.ownedValues .empty ()) {
625631 SILValue def = defWorklist.ownedValues .pop_back_val ();
632+ if (!continueWithNextSubpassRun (def))
633+ return ;
626634 auto canonicalized = canonicalizer.canonicalizeValueLifetime (def);
627635 if (!canonicalized)
628636 continue ;
629637 // Copies of borrowed values may be dead.
630638 if (auto *inst = def->getDefiningInstruction ())
631639 deleter.trackIfDead (inst);
632640 }
641+ }
642+
643+ // / Top-level pass driver.
644+ void CopyPropagation::run () {
645+ auto *f = getFunction ();
646+ // This algorithm fundamentally assumes ownership.
647+ if (!f->hasOwnership ())
648+ return ;
649+
650+ // Label for unit testing with debug output.
651+ LLVM_DEBUG (llvm::dbgs () << " *** CopyPropagation: " << f->getName () << " \n " );
652+
653+ auto *accessBlockAnalysis = getAnalysis<NonLocalAccessBlockAnalysis>();
654+
655+ CanonicalDefWorklist defWorklist (canonicalizeBorrows);
656+
657+ auto callbacks =
658+ InstModCallbacks ().onDelete ([&](SILInstruction *instToDelete) {
659+ defWorklist.erase (instToDelete);
660+ instToDelete->eraseFromParent ();
661+ });
662+ InstructionDeleter deleter (std::move (callbacks));
663+
664+ bool changed = false ;
665+ propagateCopies (defWorklist, changed, accessBlockAnalysis, deleter);
666+
633667 // Recursively cleanup dead defs after removing uses.
634668 deleter.cleanupDeadInstructions ();
635669
0 commit comments