@@ -434,21 +434,50 @@ void CopyPropagation::run() {
434434 }
435435 }
436436
437+ // canonicalizer performs all modifications through deleter's callbacks, so we
438+ // don't need to explicitly check for changes.
439+ CanonicalizeOSSALifetime canonicalizer (pruneDebug, poisonRefs,
440+ accessBlockAnalysis, domTree, deleter);
441+
437442 // NOTE: We assume that the function is in reverse post order so visiting the
438443 // blocks and pushing begin_borrows as we see them and then popping them
439444 // off the end will result in shrinking inner borrow scopes first.
440445 while (auto *bbi = beginBorrowsToShrink.pop ()) {
441- SmallVector<CopyValueInst *, 4 > modifiedCopyValueInsts;
442- changed |= shrinkBorrowScope (bbi, deleter, modifiedCopyValueInsts);
443- for (auto *cvi : modifiedCopyValueInsts)
444- defWorklist.updateForCopy (cvi);
446+ bool firstRun = true ;
447+ // Run the sequence of utilities:
448+ // - ShrinkBorrowScope
449+ // - CanonicalizeOSSALifetime
450+ // - LexicalDestroyFolder
451+ // at least once and then until each stops making changes.
452+ while (true ) {
453+ SmallVector<CopyValueInst *, 4 > modifiedCopyValueInsts;
454+ auto shrunk = shrinkBorrowScope (bbi, deleter, modifiedCopyValueInsts);
455+ for (auto *cvi : modifiedCopyValueInsts)
456+ defWorklist.updateForCopy (cvi);
457+ changed |= shrunk;
458+ if (!shrunk && !firstRun)
459+ break ;
460+
461+ // If borrowed value is not owned, neither CanonicalizeOSSALifetime nor
462+ // LexicalDestroyFolding will do anything with it. Just bail out now.
463+ auto borrowee = bbi->getOperand ();
464+ if (borrowee.getOwnershipKind () != OwnershipKind::Owned)
465+ break ;
466+
467+ auto canonicalized = canonicalizer.canonicalizeValueLifetime (borrowee);
468+ if (!canonicalized && !firstRun)
469+ break ;
470+
471+ auto folded = foldDestroysOfCopiedLexicalBorrow (bbi, *domTree, deleter);
472+ if (!folded)
473+ break ;
474+ // We don't add the produced move_value instruction to the worklist
475+ // because it can't handle propagation.
476+ firstRun = false ;
477+ }
445478 }
446479 deleter.cleanupDeadInstructions ();
447480
448- // canonicalizer performs all modifications through deleter's callbacks, so we
449- // don't need to explicitly check for changes.
450- CanonicalizeOSSALifetime canonicalizer (pruneDebug, poisonRefs,
451- accessBlockAnalysis, domTree, deleter);
452481 // For now, only modify forwarding instructions
453482 // At -Onone, we do nothing but rewrite copies of owned values.
454483 if (canonicalizeBorrows) {
0 commit comments