Skip to content

Commit 79f7b4a

Browse files
committed
[SILInliner] Only guaranteed args get lexical lifetimes.
Previously, when inlining, both owned and guaranteed arguments were wrapped in lexical lifetimes before using them to within inlined callees. That is redundant, however, because SILGen add lexical lifetimes for owned arguments within functions. Here, the redundancy is removed by only adding lexical lifetimes for guaranteed arguments that are passed to inlined callees.
1 parent 0ecd4ff commit 79f7b4a

File tree

2 files changed

+19
-129
lines changed

2 files changed

+19
-129
lines changed

lib/SILOptimizer/Utils/SILInliner.cpp

Lines changed: 13 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -428,41 +428,18 @@ SILInlineCloner::cloneInline(ArrayRef<SILValue> AppliedArgs) {
428428
entryArgs.reserve(AppliedArgs.size());
429429
SmallBitVector borrowedArgs(AppliedArgs.size());
430430
SmallBitVector copiedArgs(AppliedArgs.size());
431-
auto enableLexicalLifetimes =
432-
Apply.getFunction()
433-
->getModule()
434-
.getASTContext()
435-
.LangOpts.EnableExperimentalLexicalLifetimes;
436431

437432
auto calleeConv = getCalleeFunction()->getConventions();
438433
for (auto p : llvm::enumerate(AppliedArgs)) {
439434
SILValue callArg = p.value();
440435
unsigned idx = p.index();
441436
if (idx >= calleeConv.getSILArgIndexOfFirstParam()) {
442-
if (enableLexicalLifetimes) {
443-
if (Apply.getFunction()->hasOwnership() &&
444-
!callArg->getType().isTrivial(*Apply.getFunction()) &&
445-
!callArg->getType().isAddress()) {
446-
SILBuilderWithScope builder(Apply.getInstruction(), getBuilder());
447-
if (calleeConv.getParamInfoForSILArg(idx).isGuaranteed()) {
448-
callArg = builder.createBeginBorrow(Apply.getLoc(), callArg,
449-
/*isLexical*/ true);
450-
} else { /*owned*/
451-
auto *bbi = builder.createBeginBorrow(Apply.getLoc(), callArg,
452-
/*isLexical*/ true);
453-
callArg = builder.createCopyValue(Apply.getLoc(), bbi);
454-
copiedArgs[idx] = true;
455-
}
437+
// Insert begin/end borrow for guaranteed arguments.
438+
if (calleeConv.getParamInfoForSILArg(idx).isGuaranteed()) {
439+
if (SILValue newValue = borrowFunctionArgument(callArg, Apply)) {
440+
callArg = newValue;
456441
borrowedArgs[idx] = true;
457442
}
458-
} else {
459-
// Insert begin/end borrow for guaranteed arguments.
460-
if (calleeConv.getParamInfoForSILArg(idx).isGuaranteed()) {
461-
if (SILValue newValue = borrowFunctionArgument(callArg, Apply)) {
462-
callArg = newValue;
463-
borrowedArgs[idx] = true;
464-
}
465-
}
466443
}
467444
}
468445
entryArgs.push_back(callArg);
@@ -518,23 +495,7 @@ SILInlineCloner::cloneInline(ArrayRef<SILValue> AppliedArgs) {
518495

519496
for (auto *insertPt : endBorrowInsertPts) {
520497
SILBuilderWithScope returnBuilder(insertPt, getBuilder());
521-
SILValue original;
522-
SILValue borrow;
523-
if (copiedArgs.test(i)) {
524-
auto *cvi =
525-
cast<CopyValueInst>(entryArgs[i]->getDefiningInstruction());
526-
auto *bbi = cast<BeginBorrowInst>(
527-
cvi->getOperand()->getDefiningInstruction());
528-
borrow = bbi;
529-
original = bbi->getOperand();
530-
} else {
531-
original = SILValue();
532-
borrow = entryArgs[i];
533-
}
534-
returnBuilder.createEndBorrow(Apply.getLoc(), borrow);
535-
if (original) {
536-
returnBuilder.createDestroyValue(Apply.getLoc(), original);
537-
}
498+
returnBuilder.createEndBorrow(Apply.getLoc(), entryArgs[i]);
538499
}
539500
}
540501
}
@@ -636,13 +597,19 @@ void SILInlineCloner::postFixUp(SILFunction *calleeFunction) {
636597

637598
SILValue SILInlineCloner::borrowFunctionArgument(SILValue callArg,
638599
FullApplySite AI) {
600+
auto enableLexicalLifetimes = Apply.getFunction()
601+
->getModule()
602+
.getASTContext()
603+
.LangOpts.EnableExperimentalLexicalLifetimes;
639604
if (!AI.getFunction()->hasOwnership() ||
640-
callArg.getOwnershipKind() != OwnershipKind::Owned) {
605+
(callArg.getOwnershipKind() != OwnershipKind::Owned &&
606+
!enableLexicalLifetimes)) {
641607
return SILValue();
642608
}
643609

644610
SILBuilderWithScope beginBuilder(AI.getInstruction(), getBuilder());
645-
return beginBuilder.createBeginBorrow(AI.getLoc(), callArg);
611+
return beginBuilder.createBeginBorrow(AI.getLoc(), callArg,
612+
/*isLexical=*/enableLexicalLifetimes);
646613
}
647614

648615
void SILInlineCloner::visitDebugValueInst(DebugValueInst *Inst) {

test/SILOptimizer/inline_lifetime.sil

Lines changed: 6 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,7 @@ entry(%instance : $*S):
4040
// tests
4141

4242
// CHECK-LABEL: sil [ossa] @caller_owned_callee_owned : $@convention(thin) (@owned C) -> () {
43-
// CHECK: {{bb[^,]+}}([[INSTANCE:%[^,]+]] : @owned $C):
44-
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [lexical] [[INSTANCE]]
45-
// CHECK: [[COPY:%[^,]+]] = copy_value [[LIFETIME]]
46-
// CHECK: destroy_value [[COPY]]
47-
// CHECK: [[RETVAL:%[^,]+]] = tuple ()
48-
// CHECK: end_borrow [[LIFETIME]]
49-
// CHECK: destroy_value [[INSTANCE]]
50-
// CHECK: return [[RETVAL]]
43+
// CHECK-NOT: begin_borrow [lexical]
5144
// CHECK-LABEL: } // end sil function 'caller_owned_callee_owned'
5245
sil [ossa] @caller_owned_callee_owned : $@convention(thin) (@owned C) -> () {
5346
entry(%instance : @owned $C):
@@ -87,15 +80,7 @@ entry(%instance : @guaranteed $C):
8780
}
8881

8982
// CHECK-LABEL: sil [ossa] @caller_guaranteed_callee_owned : $@convention(thin) (@guaranteed C) -> () {
90-
// CHECK: {{bb[^,]+}}([[INSTANCE:%[^,]+]] : @guaranteed $C):
91-
// CHECK: [[COPY:%[^,]+]] = copy_value [[INSTANCE]]
92-
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [lexical] [[COPY]]
93-
// CHECK: [[LIFETIME_OWNED:%[^,]+]] = copy_value [[LIFETIME]]
94-
// CHECK: destroy_value [[LIFETIME_OWNED]]
95-
// CHECK: [[RETVAL:%[^,]+]] = tuple ()
96-
// CHECK: end_borrow [[LIFETIME]]
97-
// CHECK: destroy_value [[COPY]]
98-
// CHECK: return [[RETVAL]]
83+
// CHECK-NOT: begin_borrow [lexical]
9984
// CHECK-LABEL: } // end sil function 'caller_guaranteed_callee_owned'
10085
sil [ossa] @caller_guaranteed_callee_owned : $@convention(thin) (@guaranteed C) -> () {
10186
entry(%instance : @guaranteed $C):
@@ -195,22 +180,7 @@ bb2:
195180
// tests
196181

197182
// CHECK-LABEL: sil [ossa] @caller_owned_callee_coro_owned : $@convention(method) (@owned C) -> () {
198-
// CHECK: {{bb[^,]+}}([[INSTANCE:%[^,]+]] : @owned $C):
199-
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [lexical] [[INSTANCE]]
200-
// CHECK: [[LIFETIME_OWNED:%[^,]+]] = copy_value [[LIFETIME]]
201-
// CHECK: [[ADDR:%[^,]+]] = alloc_stack $C
202-
// CHECK: store [[LIFETIME_OWNED]] to [init] [[ADDR]]
203-
// CHECK: destroy_addr [[ADDR]]
204-
// CHECK: dealloc_stack [[ADDR]]
205-
// CHECK: [[ORIGINAL_RETVAL:%[^,]+]] = tuple ()
206-
// CHECK: end_borrow [[LIFETIME]]
207-
// CHECK: destroy_value [[INSTANCE]]
208-
// CHECK: [[RETVAL:%[^,]+]] = tuple ()
209-
// CHECK: return [[RETVAL]]
210-
// CHECK: bb1:
211-
// CHECK: destroy_addr [[ADDR]]
212-
// CHECK: dealloc_stack [[ADDR]]
213-
// CHECK: unreachable
183+
// CHECK-NOT: begin_borrow [lexical]
214184
// CHECK-LABEL: } // end sil function 'caller_owned_callee_coro_owned'
215185
sil [ossa] @caller_owned_callee_coro_owned : $@convention(method) (@owned C) -> () {
216186
bb0(%instance : @owned $C):
@@ -250,23 +220,7 @@ bb0(%instance : @owned $C):
250220
}
251221

252222
// CHECK-LABEL: sil [ossa] @caller_guaranteed_callee_coro_owned : $@convention(method) (@guaranteed C) -> () {
253-
// CHECK: {{bb[^,]+}}([[INSTANCE:%[^,]+]] : @guaranteed $C):
254-
// CHECK: [[COPY:%[^,]+]] = copy_value [[INSTANCE]]
255-
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [lexical] [[COPY]]
256-
// CHECK: [[LIFETIME_OWNED:%[^,]+]] = copy_value [[LIFETIME]]
257-
// CHECK: [[ADDR:%[^,]+]] = alloc_stack $C
258-
// CHECK: store [[LIFETIME_OWNED]] to [init] [[ADDR]]
259-
// CHECK: destroy_addr [[ADDR]]
260-
// CHECK: dealloc_stack [[ADDR]]
261-
// CHECK: [[ORIGINAL_RETVAL:%[^,]+]] = tuple ()
262-
// CHECK: end_borrow [[LIFETIME]]
263-
// CHECK: destroy_value [[COPY]]
264-
// CHECK: [[RETVAL:%[^,]+]] = tuple ()
265-
// CHECK: return [[RETVAL]]
266-
// CHECK: bb1:
267-
// CHECK: destroy_addr [[ADDR]]
268-
// CHECK: dealloc_stack [[ADDR]]
269-
// CHECK: unreachable
223+
// CHECK-NOT: begin_borrow [lexical]
270224
// CHECK-LABEL: } // end sil function 'caller_guaranteed_callee_coro_owned'
271225
sil [ossa] @caller_guaranteed_callee_coro_owned : $@convention(method) (@guaranteed C) -> () {
272226
bb0(%instance : @guaranteed $C):
@@ -393,22 +347,7 @@ bb2:
393347
// tests
394348

395349
// CHECK-LABEL: sil [ossa] @callee_owned_callee_error_owned : $@convention(thin) (@owned C) -> @error Error {
396-
// CHECK: {{bb[^,]+}}([[INSTANCE:%[^,]+]] : @owned $C):
397-
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [lexical] [[INSTANCE]]
398-
// CHECK: [[LIFETIME_OWNED:%[^,]+]] = copy_value [[LIFETIME]]
399-
// CHECK: cond_br undef, [[THROW_BLOCK:bb[^,]+]], [[REGULAR_BLOCK:bb[0-9]+]]
400-
// CHECK: [[THROW_BLOCK]]:
401-
// CHECK: destroy_value [[LIFETIME_OWNED]]
402-
// CHECK: end_borrow [[LIFETIME]]
403-
// CHECK: destroy_value [[INSTANCE]]
404-
// CHECK: throw undef
405-
// CHECK: [[REGULAR_BLOCK]]:
406-
// CHECK: destroy_value [[LIFETIME_OWNED]]
407-
// CHECK: [[ORIGINAL_RETVAL:%[^,]+]] = tuple ()
408-
// CHECK: end_borrow [[LIFETIME]]
409-
// CHECK: destroy_value [[INSTANCE]]
410-
// CHECK: [[RETVAL:%[^,]+]] = tuple ()
411-
// CHECK: return [[RETVAL]]
350+
// CHECK-NOT: begin_borrow [lexical]
412351
// CHECK-LABEL: } // end sil function 'callee_owned_callee_error_owned'
413352
sil [ossa] @callee_owned_callee_error_owned : $@convention(thin) (@owned C) -> @error Error {
414353
bb0(%instance : @owned $C):
@@ -451,23 +390,7 @@ bb2(%12 : @owned $Error):
451390
}
452391

453392
// CHECK-LABEL: sil [ossa] @callee_guaranteed_callee_error_owned : $@convention(thin) (@guaranteed C) -> @error Error {
454-
// CHECK: {{bb[^,]+}}([[INSTANCE:%[^,]+]] : @guaranteed $C):
455-
// CHECK: [[COPY:%[^,]+]] = copy_value [[INSTANCE]]
456-
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [lexical] [[COPY]]
457-
// CHECK: [[LIFETIME_OWNED:%[^,]+]] = copy_value [[LIFETIME]]
458-
// CHECK: cond_br undef, [[THROW_BLOCK:bb[^,]+]], [[REGULAR_BLOCK:bb[0-9]+]]
459-
// CHECK: [[THROW_BLOCK]]:
460-
// CHECK: destroy_value [[LIFETIME_OWNED]]
461-
// CHECK: end_borrow [[LIFETIME]]
462-
// CHECK: destroy_value [[COPY]]
463-
// CHECK: throw undef
464-
// CHECK: [[REGULAR_BLOCK]]:
465-
// CHECK: destroy_value [[LIFETIME_OWNED]]
466-
// CHECK: [[ORIGINAL_RETVAL:%[^,]+]] = tuple ()
467-
// CHECK: end_borrow [[LIFETIME]]
468-
// CHECK: destroy_value [[COPY]]
469-
// CHECK: [[RETVAL:%[^,]+]] = tuple ()
470-
// CHECK: return [[RETVAL]]
393+
// CHECK-NOT: begin_borrow [lexical]
471394
// CHECK-LABEL: } // end sil function 'callee_guaranteed_callee_error_owned'
472395
sil [ossa] @callee_guaranteed_callee_error_owned : $@convention(thin) (@guaranteed C) -> @error Error {
473396
bb0(%instance : @guaranteed $C):

0 commit comments

Comments
 (0)