Skip to content

Commit 7743741

Browse files
Merge pull request #74235 from nate-chandler/rdar127115078
[SILGen] Forward address-only self to borrowing accessors.
2 parents 09d025b + e3fbad5 commit 7743741

14 files changed

+110
-261
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6858,22 +6858,21 @@ bool AccessorBaseArgPreparer::shouldLoadBaseAddress() const {
68586858
ArgumentSource AccessorBaseArgPreparer::prepareAccessorAddressBaseArg() {
68596859
// If the base is currently an address, we may have to copy it.
68606860
if (shouldLoadBaseAddress()) {
6861-
if (selfParam.isConsumed() ||
6862-
(base.getType().isAddressOnly(SGF.F)
6863-
// If a move-only base is borrowed, then we have to try our best to
6864-
// borrow it in-place without copying.
6865-
// TODO: Can we avoid copying a non-move-only value too in this
6866-
// circumstance?
6867-
&& !base.getType().isMoveOnly())) {
6861+
if (selfParam.isConsumed() || base.getType().isAddressOnly(SGF.F)) {
68686862
// The load can only be a take if the base is a +1 rvalue.
68696863
auto shouldTake = IsTake_t(base.hasCleanup());
68706864

6865+
auto isGuaranteed = selfParam.isGuaranteed();
6866+
6867+
auto context =
6868+
isGuaranteed ? SGFContext::AllowImmediatePlusZero : SGFContext();
6869+
68716870
base = SGF.emitFormalAccessLoad(loc, base.forward(SGF),
68726871
SGF.getTypeLowering(baseLoweredType),
6873-
SGFContext(), shouldTake);
6872+
context, shouldTake, isGuaranteed);
68746873
return ArgumentSource(loc, RValue(SGF, loc, baseFormalType, base));
68756874
}
6876-
6875+
68776876
// If the type is address-only, we can borrow the memory location as is.
68786877
if (base.getType().isAddressOnly(SGF.F)) {
68796878
return ArgumentSource(loc, RValue(SGF, loc, baseFormalType, base));

test/SILGen/boxed_existentials.swift

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,10 @@ func test_property(_ x: Error) -> String {
6464
// CHECK-LABEL: sil hidden [ossa] @$s18boxed_existentials13test_propertyySSs5Error_pF
6565
// CHECK: bb0([[ARG:%.*]] : @guaranteed $any Error):
6666
// CHECK: [[VALUE:%.*]] = open_existential_box [[ARG]] : $any Error to $*[[VALUE_TYPE:@opened\(.*, any Error\) Self]]
67-
// FIXME: Extraneous copy here
68-
// CHECK-NEXT: [[COPY:%[0-9]+]] = alloc_stack $[[VALUE_TYPE]]
69-
// CHECK-NEXT: copy_addr [[VALUE]] to [init] [[COPY]] : $*[[VALUE_TYPE]]
7067
// CHECK: [[METHOD:%.*]] = witness_method $[[VALUE_TYPE]], #Error._domain!getter
7168
// -- self parameter of witness is @in_guaranteed; no need to copy since
7269
// value in box is immutable and box is guaranteed
73-
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]<[[VALUE_TYPE]]>([[COPY]])
70+
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]<[[VALUE_TYPE]]>([[VALUE]])
7471
// CHECK-NOT: destroy_value [[ARG]]
7572
// CHECK: return [[RESULT]]
7673

@@ -93,10 +90,8 @@ func test_property_of_lvalue(_ x: Error) -> String {
9390
// CHECK: [[COPY:%.*]] = alloc_stack $[[VALUE_TYPE]]
9491
// CHECK: copy_addr [[VALUE]] to [init] [[COPY]]
9592
// CHECK: destroy_value [[VALUE_BOX]]
96-
// CHECK: [[BORROW:%.*]] = alloc_stack $[[VALUE_TYPE]]
97-
// CHECK: copy_addr [[COPY]] to [init] [[BORROW]]
9893
// CHECK: [[METHOD:%.*]] = witness_method $[[VALUE_TYPE]], #Error._domain!getter
99-
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]<[[VALUE_TYPE]]>([[BORROW]])
94+
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]<[[VALUE_TYPE]]>([[COPY]])
10095
// CHECK: destroy_addr [[COPY]]
10196
// CHECK: dealloc_stack [[COPY]]
10297
// CHECK: end_borrow [[VAR_LIFETIME]]

test/SILGen/copy_expr.swift

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,8 @@ func testCallMethodOnLoadableGlobal() {
333333
// Calling computedK. It is borrowed.
334334
// CHECK: [[TEMP:%.*]] = alloc_stack $T
335335
// CHECK: explicit_copy_addr [[X]] to [init] [[TEMP]]
336-
// CHECK: [[TEMP2:%.*]] = alloc_stack $T
337-
// CHECK: copy_addr [[TEMP]] to [init] [[TEMP2]]
338336
// CHECK: [[FUNC:%.*]] = witness_method $T, #P.computedK!getter : <Self where Self : P> (Self) -> () -> Klass : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @owned Klass
339-
// CHECK: apply [[FUNC]]<(T)>([[TEMP2]])
337+
// CHECK: apply [[FUNC]]<(T)>([[TEMP]])
340338
//
341339
// Calling computed consuming getter.
342340
// CHECK: [[TEMP:%.*]] = alloc_stack $T
@@ -378,10 +376,8 @@ func testCallMethodOnAddressOnlyLetCopy<T : P>(_ t: T.Type) {
378376
// CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[PROJECT]]
379377
// CHECK: [[TEMP:%.*]] = alloc_stack $
380378
// CHECK: explicit_copy_addr [[ACCESS]] to [init] [[TEMP]]
381-
// CHECK: [[TEMP2:%.*]] = alloc_stack $
382-
// CHECK: copy_addr [[TEMP]] to [init] [[TEMP2]]
383379
// CHECK: [[FUNC:%.*]] = witness_method $T, #P.computedK!getter : <Self where Self : P> (Self) -> () -> Klass : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @owned Klass
384-
// CHECK: apply [[FUNC]]<(T)>([[TEMP2]])
380+
// CHECK: apply [[FUNC]]<(T)>([[TEMP]])
385381
//
386382
// Consuming computed getter.
387383
// CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[PROJECT]]
@@ -423,10 +419,8 @@ func testCallMethodOnAddressOnlyVarCopy<T : P>(_ t: T.Type) {
423419
// CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[ARG]]
424420
// CHECK: [[TEMP:%.*]] = alloc_stack $
425421
// CHECK: explicit_copy_addr [[ACCESS]] to [init] [[TEMP]]
426-
// CHECK: [[TEMP2:%.*]] = alloc_stack $
427-
// CHECK: copy_addr [[TEMP]] to [init] [[TEMP2]]
428422
// CHECK: [[FUNC:%.*]] = witness_method $T, #P.computedK!getter : <Self where Self : P> (Self) -> () -> Klass : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @owned Klass
429-
// CHECK: apply [[FUNC]]<(T)>([[TEMP2]])
423+
// CHECK: apply [[FUNC]]<(T)>([[TEMP]])
430424
//
431425
// Consuming computed getter.
432426
// CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[ARG]]

test/SILGen/dynamic_self.swift

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,27 +96,19 @@ func testExistentialDispatch(p: P) {
9696

9797
// CHECK: [[PCOPY_ADDR:%[0-9]+]] = open_existential_addr immutable_access [[P]] : $*any P to $*@opened([[N:".*"]], any P) Self
9898
// CHECK: [[P_RESULT:%[0-9]+]] = alloc_stack $any P
99-
// CHECK: [[PCOPY_ADDR_1:%[0-9]+]] = alloc_stack $@opened([[N]], any P) Self
100-
// CHECK: copy_addr [[PCOPY_ADDR]] to [init] [[PCOPY_ADDR_1]] : $*@opened([[N]], any P) Self
10199
// CHECK: [[P_P_GETTER:%[0-9]+]] = witness_method $@opened([[N]], any P) Self, #P.p!getter : {{.*}}, [[PCOPY_ADDR]]{{.*}} : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out τ_0_0
102100
// CHECK: [[P_RESULT_ADDR2:%[0-9]+]] = init_existential_addr [[P_RESULT]] : $*any P, $@opened([[N]], any P) Self
103-
// CHECK: apply [[P_P_GETTER]]<@opened([[N]], any P) Self>([[P_RESULT_ADDR2]], [[PCOPY_ADDR_1]]) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out τ_0_0
104-
// CHECK: destroy_addr [[PCOPY_ADDR_1]] : $*@opened([[N]], any P) Self
101+
// CHECK: apply [[P_P_GETTER]]<@opened([[N]], any P) Self>([[P_RESULT_ADDR2]], [[PCOPY_ADDR]]) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out τ_0_0
105102
// CHECK: destroy_addr [[P_RESULT]] : $*any P
106-
// CHECK: dealloc_stack [[PCOPY_ADDR_1]] : $*@opened([[N]], any P) Self
107103
// CHECK: dealloc_stack [[P_RESULT]] : $*any P
108104
_ = p.p
109105

110106
// CHECK: [[PCOPY_ADDR:%[0-9]+]] = open_existential_addr immutable_access [[P]] : $*any P to $*@opened([[N:".*"]], any P) Self
111107
// CHECK: [[P_RESULT:%[0-9]+]] = alloc_stack $any P
112-
// CHECK: [[PCOPY_ADDR_1:%[0-9]+]] = alloc_stack $@opened([[N]], any P) Self
113-
// CHECK: copy_addr [[PCOPY_ADDR]] to [init] [[PCOPY_ADDR_1]] : $*@opened([[N]], any P) Self
114108
// CHECK: [[P_SUBSCRIPT_GETTER:%[0-9]+]] = witness_method $@opened([[N]], any P) Self, #P.subscript!getter : {{.*}}, [[PCOPY_ADDR]]{{.*}} : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out τ_0_0
115109
// CHECK: [[P_RESULT_ADDR:%[0-9]+]] = init_existential_addr [[P_RESULT]] : $*any P, $@opened([[N]], any P) Self
116-
// CHECK: apply [[P_SUBSCRIPT_GETTER]]<@opened([[N]], any P) Self>([[P_RESULT_ADDR]], [[PCOPY_ADDR_1]]) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out τ_0_0
117-
// CHECK: destroy_addr [[PCOPY_ADDR_1]] : $*@opened([[N]], any P) Self
110+
// CHECK: apply [[P_SUBSCRIPT_GETTER]]<@opened([[N]], any P) Self>([[P_RESULT_ADDR]], [[PCOPY_ADDR]]) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out τ_0_0
118111
// CHECK: destroy_addr [[P_RESULT]] : $*any P
119-
// CHECK: dealloc_stack [[PCOPY_ADDR_1]] : $*@opened([[N]], any P) Self
120112
// CHECK: dealloc_stack [[P_RESULT]] : $*any P
121113
_ = p[]
122114
}

0 commit comments

Comments
 (0)