Skip to content

Commit 60742fc

Browse files
committed
ClosureLifetimeFixup : Ensure borrow scope is inserted on both none/some
path for an optional type.
1 parent bbb6516 commit 60742fc

File tree

2 files changed

+13
-10
lines changed

2 files changed

+13
-10
lines changed

lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,8 @@ cleanupDeadTrivialPhiArgs(SILValue initialValue,
195195
// Then RAUW the phi with the entryBlockOptionalNone and erase the
196196
// argument.
197197
phi->replaceAllUsesWith(initialValue);
198-
erasePhiArgument(phi->getParent(), phi->getIndex());
198+
erasePhiArgument(phi->getParent(), phi->getIndex(),
199+
/*cleanupDeadPhiOp*/ false);
199200
}
200201
}
201202

@@ -286,17 +287,13 @@ static void extendLifetimeToEndOfFunction(SILFunction &fn,
286287
cvtUser->setOperand(cvtUse->getOperandNumber(), mdi);
287288
}
288289

289-
auto fixupSILForLifetimeExtension = [&](SILValue value) {
290+
auto fixupSILForLifetimeExtension = [&](SILValue value, SILValue entryValue) {
290291
// Use SSAUpdater to find insertion points for lifetime ends.
291292
updater.initialize(optionalEscapingClosureTy, value->getOwnershipKind());
292293
SmallVector<SILPhiArgument *, 8> insertedPhis;
293294
updater.setInsertedPhis(&insertedPhis);
294295

295-
// Create an optional none at the function entry.
296-
auto *optionalNone =
297-
SILBuilderWithScope(fn.getEntryBlock()->begin())
298-
.createOptionalNone(loc, optionalEscapingClosureTy);
299-
updater.addAvailableValue(fn.getEntryBlock(), optionalNone);
296+
updater.addAvailableValue(fn.getEntryBlock(), entryValue);
300297
updater.addAvailableValue(value->getParentBlock(), value);
301298
{
302299
// Since value maybe in a loop, insert an extra lifetime end. Since we
@@ -316,12 +313,17 @@ static void extendLifetimeToEndOfFunction(SILFunction &fn,
316313
// TODO: Should we sort inserted phis before or after we initialize
317314
// the worklist or maybe backwards? We should investigate how the
318315
// SSA updater adds phi nodes to this list to resolve this question.
319-
cleanupDeadTrivialPhiArgs(optionalNone, insertedPhis);
316+
cleanupDeadTrivialPhiArgs(entryValue, insertedPhis);
320317
};
321318

319+
// Create an optional none at the function entry.
320+
auto *optionalNone = SILBuilderWithScope(fn.getEntryBlock()->begin())
321+
.createOptionalNone(loc, optionalEscapingClosureTy);
322+
auto *borrowNone = SILBuilderWithScope(optionalNone->getNextInstruction())
323+
.createBeginBorrow(loc, optionalNone);
322324
// Use the SSAUpdater to create lifetime ends for the copy and the borrow.
323-
fixupSILForLifetimeExtension(borrow);
324-
fixupSILForLifetimeExtension(optionalSome);
325+
fixupSILForLifetimeExtension(borrow, borrowNone);
326+
fixupSILForLifetimeExtension(optionalSome, optionalNone);
325327
}
326328

327329
static SILInstruction *lookThroughRebastractionUsers(

test/SILOptimizer/closure-lifetime-fixup.sil

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ bb3(%13 : $@noescape @callee_guaranteed () -> ()):
211211
// CHECK-LABEL: sil [ossa] @test_lifetime_extension_until_function_exit :
212212
// CHECK: [[NONE1:%.*]] = enum $Optional<@callee_guaranteed () -> ()>, #Optional.none!enumelt
213213
// CHECK: [[NONE2:%.*]] = enum $Optional<@callee_guaranteed () -> ()>, #Optional.none!enumelt
214+
// CHECK: [[BORROWNONE:%.*]] = begin_borrow [[NONE2]] : $Optional<@callee_guaranteed () -> ()>
214215
// CHECK: cond_br undef, bb1, bb2
215216
// CHECK: bb1:
216217
// CHECK: [[ORIG:%.*]] = function_ref @originalClosure : $@convention(thin) () -> ()

0 commit comments

Comments
 (0)