Skip to content

Commit 9e5e935

Browse files
committed
[CopyPropagation] Run LexicalDestroyFolding.
1 parent 313f0e2 commit 9e5e935

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

lib/SILOptimizer/Transforms/CopyPropagation.cpp

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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) {

test/SILOptimizer/shrink_borrow_scope.sil

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -777,13 +777,14 @@ bad(%15 : @owned $Error):
777777
// CHECK: [[LEFT]]:
778778
// CHECK: [[REGISTER_3:%[^,]+]] = apply undef()
779779
// CHECK: end_borrow [[LIFETIME]]
780+
// CHECK: destroy_value [[INSTANCE]]
780781
// CHECK: br [[EXIT:bb[0-9]+]]
781782
// CHECK: [[RIGHT]]:
782783
// CHECK: [[REGISTER_6:%[^,]+]] = apply undef()
783784
// CHECK: end_borrow [[LIFETIME]]
785+
// CHECK: destroy_value [[INSTANCE]]
784786
// CHECK: br [[EXIT]]
785787
// CHECK: [[EXIT]]:
786-
// CHECK: destroy_value [[INSTANCE]]
787788
// CHECK-LABEL: } // end sil function 'hoist_up_to_two_barrier_applies'
788789
sil [ossa] @hoist_up_to_two_barrier_applies : $@convention(thin) (@owned C) -> () {
789790
entry(%instance : @owned $C):

0 commit comments

Comments
 (0)