Skip to content

Commit c7a6f8a

Browse files
authored
Merge pull request swiftlang#23545 from gottesmm/pr-e3dcd860b815d66e87386753076de45eee6f5652
[closure-lifetime] Add a fix_lifetime to communicate the end of lifet…
2 parents 965953d + e11794b commit c7a6f8a

File tree

2 files changed

+22
-15
lines changed

2 files changed

+22
-15
lines changed

lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,6 @@ static void extendLifetimeToEndOfFunction(SILFunction &fn,
122122
auto optionalEscapingClosureTy = SILType::getOptionalType(escapingClosureTy);
123123
auto loc = RegularLocation::getAutoGeneratedLocation();
124124

125-
cvt->setLifetimeGuaranteed();
126-
127125
// If our Cvt is in the initial block, we do not need to use the SSA updater
128126
// since we know Cvt can not be in a loop and must dominate all exits
129127
// (*). Just insert a copy of the escaping closure at the Cvt and destroys at
@@ -133,6 +131,8 @@ static void extendLifetimeToEndOfFunction(SILFunction &fn,
133131
if (cvt->getParent() == cvt->getFunction()->getEntryBlock()) {
134132
auto *innerCVI =
135133
SILBuilderWithScope(cvt).createCopyValue(loc, escapingClosure);
134+
cvt->setLifetimeGuaranteed();
135+
cvt->setOperand(innerCVI);
136136
SmallVector<SILBasicBlock *, 4> exitingBlocks;
137137
fn.findExitingBlocks(exitingBlocks);
138138

@@ -167,8 +167,11 @@ static void extendLifetimeToEndOfFunction(SILFunction &fn,
167167
// block without extra work. So the fact that Cvt is not in the entry block
168168
// means that we don't have to worry about overwriting the .none value.
169169
auto *cvi = [&]() -> CopyValueInst * {
170-
SILBuilderWithScope b(cvt);
171-
auto *innerCVI = b.createCopyValue(loc, escapingClosure);
170+
auto *innerCVI =
171+
SILBuilderWithScope(cvt).createCopyValue(loc, escapingClosure);
172+
cvt->setLifetimeGuaranteed();
173+
cvt->setOperand(innerCVI);
174+
SILBuilderWithScope b(std::next(cvt->getIterator()));
172175
updater.AddAvailableValue(
173176
cvt->getParent(),
174177
b.createOptionalSome(loc, innerCVI, optionalEscapingClosureTy));
@@ -407,10 +410,10 @@ static bool tryExtendLifetimeToLastUse(
407410
// Insert a copy at the convert_escape_to_noescape [not_guaranteed] and
408411
// change the instruction to the guaranteed form.
409412
auto escapingClosure = cvt->getOperand();
410-
cvt->setLifetimeGuaranteed();
411-
412413
auto *closureCopy =
413414
SILBuilderWithScope(cvt).createCopyValue(loc, escapingClosure);
415+
cvt->setLifetimeGuaranteed();
416+
cvt->setOperand(closureCopy);
414417

415418
// Insert a destroy after the apply.
416419
if (auto *apply = dyn_cast<ApplyInst>(singleApplyUser.getInstruction())) {
@@ -492,14 +495,17 @@ static bool trySwitchEnumPeephole(ConvertEscapeToNoEscapeInst *cvt) {
492495
if (!onlyDestroy)
493496
return false;
494497

495-
cvt->setLifetimeGuaranteed();
496-
497498
// Extend the lifetime.
498-
SILBuilderWithScope b(switchEnum1);
499499
auto loc = RegularLocation::getAutoGeneratedLocation();
500-
auto copy = b.createCopyValue(loc, switchEnum1->getOperand());
501-
b.setInsertionPoint(onlyDestroy);
502-
b.createDestroyValue(loc, copy);
500+
auto *copy = SILBuilderWithScope(switchEnum1)
501+
.createCopyValue(loc, switchEnum1->getOperand());
502+
503+
cvt->setLifetimeGuaranteed();
504+
auto *mdi = SILBuilderWithScope(cvt).createMarkDependence(
505+
loc, cvt->getOperand(), copy);
506+
cvt->setOperand(mdi);
507+
508+
SILBuilderWithScope(onlyDestroy).createDestroyValue(loc, copy);
503509
return true;
504510
}
505511

test/SILOptimizer/definite-init-convert-to-escape.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ public func returnOptionalEscape() -> (() ->())?
4545
// CHECK: retain_value [[V1]]
4646
// CHECK: switch_enum [[V1]] : $Optional<{{.*}}>, case #Optional.some!enumelt.1: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]]
4747
//
48-
// CHECK: [[SOME_BB]]([[V2:%.*]]: $@callee_guaranteed () -> ()):
49-
// CHECK: [[CVT:%.*]] = convert_escape_to_noescape [[V2]]
48+
// CHECK: [[SOME_BB]]([[V2:%.*]] : $@callee_guaranteed () -> ()):
49+
// CHECK: [[CVT_MARK_DEP:%.*]] = mark_dependence [[V2]] : $@callee_guaranteed () -> () on [[V1]]
50+
// CHECK: [[CVT:%.*]] = convert_escape_to_noescape [[CVT_MARK_DEP]]
5051
// CHECK: [[SOME:%.*]] = enum $Optional<{{.*}}>, #Optional.some!enumelt.1, [[CVT]]
5152
// CHECK: strong_release [[V2]]
5253
// CHECK: br [[NEXT_BB:bb[0-9]+]]([[SOME]] :
@@ -89,8 +90,8 @@ public func returnOptionalEscape() -> (() ->())?
8990
//
9091
// NOPEEPHOLE: [[SOME_BB]]([[V2:%.*]]: $@callee_guaranteed () -> ()):
9192
// NOPEEPHOLE-NEXT: release_value [[NONE_2]]
92-
// NOPEEPHOLE-NEXT: [[SOME:%.*]] = enum $Optional<{{.*}}>, #Optional.some!enumelt.1, [[V2]]
9393
// NOPEEPHOLE-NEXT: [[CVT:%.*]] = convert_escape_to_noescape [[V2]]
94+
// NOPEEPHOLE-NEXT: [[SOME:%.*]] = enum $Optional<{{.*}}>, #Optional.some!enumelt.1, [[V2]]
9495
// NOPEEPHOLE-NEXT: [[NOESCAPE_SOME:%.*]] = enum $Optional<{{.*}}>, #Optional.some!enumelt.1, [[CVT]]
9596
// NOPEEPHOLE-NEXT: br bb2([[NOESCAPE_SOME]] : $Optional<{{.*}}>, [[SOME]] :
9697
//

0 commit comments

Comments
 (0)