Skip to content

Commit 6205344

Browse files
authored
Merge pull request #6920 from gottesmm/begin_borrow_store_borrow_when_materializing_guaranteed_temporary
[semantic-sil] Use a begin_borrow/store_borrow combination when materializing a guaranteed temporary.
2 parents de6582a + ce4c9da commit 6205344

File tree

3 files changed

+21
-17
lines changed

3 files changed

+21
-17
lines changed

lib/SILGen/ManagedValue.h

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -116,33 +116,30 @@ class ManagedValue {
116116

117117
/// Create a managed value for a +0 borrowed non-trivial rvalue object.
118118
static ManagedValue
119-
forBorrowedObjectRValue(SILValue value,
120-
CleanupHandle cleanup = CleanupHandle::invalid()) {
119+
forBorrowedObjectRValue(SILValue value) {
121120
assert(value && "No value specified");
122121
assert(value->getType().isObject() &&
123122
"Expected borrowed rvalues to be objects");
124123
assert(value.getOwnershipKind() != ValueOwnershipKind::Trivial);
125-
return ManagedValue(value, false, cleanup);
124+
return ManagedValue(value, false, CleanupHandle::invalid());
126125
}
127126

128127
/// Create a managed value for a +0 borrowed non-trivial rvalue address.
129128
static ManagedValue
130-
forBorrowedAddressRValue(SILValue value,
131-
CleanupHandle cleanup = CleanupHandle::invalid()) {
129+
forBorrowedAddressRValue(SILValue value) {
132130
assert(value && "No value specified");
133131
assert(value->getType().isAddress() && "Expected value to be an address");
134132
assert(value.getOwnershipKind() == ValueOwnershipKind::Trivial &&
135133
"Addresses always have trivial ownership");
136-
return ManagedValue(value, false, cleanup);
134+
return ManagedValue(value, false, CleanupHandle::invalid());
137135
}
138136

139137
/// Create a managed value for a +0 guaranteed rvalue.
140138
static ManagedValue
141-
forBorrowedRValue(SILValue value,
142-
CleanupHandle cleanup = CleanupHandle::invalid()) {
139+
forBorrowedRValue(SILValue value) {
143140
if (value->getType().isAddress())
144-
return ManagedValue::forBorrowedAddressRValue(value, cleanup);
145-
return ManagedValue::forBorrowedObjectRValue(value, cleanup);
141+
return ManagedValue::forBorrowedAddressRValue(value);
142+
return ManagedValue::forBorrowedObjectRValue(value);
146143
}
147144

148145
/// Create a managed value for a +0 trivial object rvalue.

lib/SILGen/SILGenApply.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2580,14 +2580,19 @@ static ManagedValue emitMaterializeIntoTemporary(SILGenFunction &gen,
25802580
ManagedValue object) {
25812581
auto temporary = gen.emitTemporaryAllocation(loc, object.getType());
25822582
bool hadCleanup = object.hasCleanup();
2583-
gen.B.emitStoreValueOperation(loc, object.forward(gen), temporary,
2584-
StoreOwnershipQualifier::Init);
25852583

25862584
// The temporary memory is +0 if the value was.
25872585
if (hadCleanup) {
2588-
return ManagedValue(temporary, gen.enterDestroyCleanup(temporary));
2586+
gen.B.emitStoreValueOperation(loc, object.forward(gen), temporary,
2587+
StoreOwnershipQualifier::Init);
2588+
2589+
// SEMANTIC SIL TODO: This should really be called a temporary LValue.
2590+
return ManagedValue::forOwnedAddressRValue(temporary,
2591+
gen.enterDestroyCleanup(temporary));
25892592
} else {
2590-
return ManagedValue::forUnmanaged(temporary);
2593+
object = gen.emitManagedBeginBorrow(loc, object.getValue());
2594+
gen.emitManagedStoreBorrow(loc, object.getValue(), temporary);
2595+
return ManagedValue::forBorrowedAddressRValue(temporary);
25912596
}
25922597
}
25932598

test/SILGen/protocol_extensions.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,11 @@ func testD(_ m: MetaHolder, dd: D.Type, d: D) {
101101
// CHECK: [[D2:%[0-9]+]] = alloc_box ${ var D }
102102
// CHECK: [[RESULT:%.*]] = project_box [[D2]]
103103
// CHECK: [[FN:%[0-9]+]] = function_ref @_TFE19protocol_extensionsPS_2P111returnsSelf{{.*}}
104-
// CHECK: [[DCOPY:%[0-9]+]] = alloc_stack $D
105-
// CHECK: store [[D]] to [init] [[DCOPY]] : $*D
106-
// CHECK: apply [[FN]]<D>([[RESULT]], [[DCOPY]]) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (@in_guaranteed τ_0_0) -> @out τ_0_0
104+
// CHECK: [[MATERIALIZED_BORROWED_D:%[0-9]+]] = alloc_stack $D
105+
// CHECK: [[BORROWED_D:%.*]] = begin_borrow [[D]]
106+
// CHECK: store_borrow [[BORROWED_D]] to [[MATERIALIZED_BORROWED_D]]
107+
// CHECK: apply [[FN]]<D>([[RESULT]], [[MATERIALIZED_BORROWED_D]]) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (@in_guaranteed τ_0_0) -> @out τ_0_0
108+
// CHECK-NEXT: end_borrow [[BORROWED_D]] from [[D]]
107109
var d2: D = d.returnsSelf()
108110

109111
// CHECK: metatype $@thick D.Type

0 commit comments

Comments
 (0)