Skip to content

Commit 883d546

Browse files
authored
Merge pull request #30291 from gottesmm/pr-20d3a11a596c39f79b461a829ff03722b9755ec9
2 parents 11df7a8 + e9896fb commit 883d546

File tree

8 files changed

+58
-37
lines changed

8 files changed

+58
-37
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6192,7 +6192,7 @@ class InitExistentialValueInst final
61926192
class InitExistentialRefInst final
61936193
: public UnaryInstructionWithTypeDependentOperandsBase<
61946194
SILInstructionKind::InitExistentialRefInst, InitExistentialRefInst,
6195-
SingleValueInstruction> {
6195+
OwnershipForwardingSingleValueInst> {
61966196
friend SILBuilder;
61976197

61986198
CanType ConcreteType;
@@ -6203,7 +6203,8 @@ class InitExistentialRefInst final
62036203
ArrayRef<SILValue> TypeDependentOperands,
62046204
ArrayRef<ProtocolConformanceRef> Conformances)
62056205
: UnaryInstructionWithTypeDependentOperandsBase(
6206-
DebugLoc, Instance, TypeDependentOperands, ExistentialType),
6206+
DebugLoc, Instance, TypeDependentOperands, ExistentialType,
6207+
Instance.getOwnershipKind()),
62076208
ConcreteType(FormalConcreteType), Conformances(Conformances) {}
62086209

62096210
static InitExistentialRefInst *

lib/SIL/OperandOwnership.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,6 @@ CONSTANT_OWNERSHIP_INST(Owned, MustBeInvalidated, DeallocExistentialBox)
173173
CONSTANT_OWNERSHIP_INST(Owned, MustBeInvalidated, DeallocRef)
174174
CONSTANT_OWNERSHIP_INST(Owned, MustBeInvalidated, DestroyValue)
175175
CONSTANT_OWNERSHIP_INST(Owned, MustBeInvalidated, EndLifetime)
176-
CONSTANT_OWNERSHIP_INST(Owned, MustBeInvalidated, InitExistentialRef)
177176
CONSTANT_OWNERSHIP_INST(None, MustBeLive, AbortApply)
178177
CONSTANT_OWNERSHIP_INST(None, MustBeLive, AddressToPointer)
179178
CONSTANT_OWNERSHIP_INST(None, MustBeLive, BeginAccess)
@@ -348,6 +347,7 @@ FORWARD_ANY_OWNERSHIP_INST(UnconditionalCheckedCast)
348347
FORWARD_ANY_OWNERSHIP_INST(UncheckedEnumData)
349348
FORWARD_ANY_OWNERSHIP_INST(DestructureStruct)
350349
FORWARD_ANY_OWNERSHIP_INST(DestructureTuple)
350+
FORWARD_ANY_OWNERSHIP_INST(InitExistentialRef)
351351
#undef FORWARD_ANY_OWNERSHIP_INST
352352

353353
// An instruction that forwards a constant ownership or trivial ownership.

lib/SIL/OwnershipUtils.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ bool swift::isOwnershipForwardingValueKind(SILNodeKind kind) {
4646
case SILNodeKind::DestructureStructInst:
4747
case SILNodeKind::DestructureTupleInst:
4848
case SILNodeKind::MarkDependenceInst:
49+
case SILNodeKind::InitExistentialRefInst:
4950
return true;
5051
default:
5152
return false;

lib/SIL/ValueOwnership.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,6 @@ CONSTANT_OWNERSHIP_INST(Owned, KeyPath)
7878
CONSTANT_OWNERSHIP_INST(Owned, InitExistentialValue)
7979
CONSTANT_OWNERSHIP_INST(Owned, GlobalValue) // TODO: is this correct?
8080

81-
// NOTE: Even though init_existential_ref from a reference counting perspective
82-
// is not considered to be "owned" since it doesn't affect reference counts,
83-
// conceptually we want to treat it as an owned value that produces owned
84-
// things, rather than a forwarding thing since initialization is generally a
85-
// consuming operation.
86-
CONSTANT_OWNERSHIP_INST(Owned, InitExistentialRef)
87-
8881
// One would think that these /should/ be unowned. In truth they are owned since
8982
// objc metatypes do not go through the retain/release fast path. In their
9083
// implementations of retain/release nothing happens, so this is safe.
@@ -260,6 +253,16 @@ FORWARDING_OWNERSHIP_INST(Upcast)
260253
FORWARDING_OWNERSHIP_INST(UncheckedEnumData)
261254
FORWARDING_OWNERSHIP_INST(SelectEnum)
262255
FORWARDING_OWNERSHIP_INST(Enum)
256+
// NOTE: init_existential_ref from a reference counting perspective is not
257+
// considered to be "owned" since it doesn't affect reference counts. That being
258+
// said in the past, we wanted to conceptually treat it as an owned value that
259+
// produces owned things, rather than a forwarding thing since initialization is
260+
// generally a consuming operation. That being said, there are often cases in
261+
// class based code where we are propagating around a plus zero version of a
262+
// value and need to wrap the class in an existential wrapper in an intermediate
263+
// frame from usage. In such cases, we have been creating unnecessary ref count
264+
// traffic in code.
265+
FORWARDING_OWNERSHIP_INST(InitExistentialRef)
263266
#undef FORWARDING_OWNERSHIP_INST
264267

265268
ValueOwnershipKind

lib/SILOptimizer/Transforms/SemanticARCOpts.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ struct SemanticARCOptVisitor
593593
FORWARDING_INST(OpenExistentialValue)
594594
FORWARDING_INST(OpenExistentialBoxValue)
595595
FORWARDING_INST(MarkDependence)
596+
FORWARDING_INST(InitExistentialRef)
596597
#undef FORWARDING_INST
597598

598599
#define FORWARDING_TERM(NAME) \

test/SIL/ownership-verifier/over_consume.sil

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -460,32 +460,6 @@ bb0(%0 : @owned $Klass):
460460
return %9999 : $()
461461
}
462462

463-
// CHECK-LABEL: Function: 'init_existential_ref_not_forwarding'
464-
// CHECK: Have operand with incompatible ownership?!
465-
// CHECK: Value: %0 = argument of bb0 : $ClassProtConformingRef
466-
// CHECK: User: %2 = init_existential_ref %0 : $ClassProtConformingRef : $ClassProtConformingRef, $ClassProt
467-
// CHECK: Operand Number: 0
468-
// CHECK: Conv: guaranteed
469-
// CHECK: OwnershipMap:
470-
// CHECK: -- OperandOwnershipKindMap --
471-
// CHECK: unowned: No.
472-
// CHECK: owned: Yes. Liveness: MustBeInvalidated
473-
// CHECK: guaranteed: No.
474-
// CHECK: any: Yes. Liveness: MustBeLive
475-
// CHECK-NOT: init_existential_ref %1
476-
// CHECK: Function: 'init_existential_ref_not_forwarding'
477-
// CHECK: Error! Found a leaked owned value that was never consumed.
478-
// CHECK: Value: %2 = init_existential_ref %0 : $ClassProtConformingRef : $ClassProtConformingRef, $ClassProt
479-
// CHECK-NOT: init_existential_ref %1
480-
sil [ossa] @init_existential_ref_not_forwarding : $@convention(thin) (@guaranteed ClassProtConformingRef, @owned ClassProtConformingRef) -> @owned (ClassProt, ClassProt) {
481-
bb0(%0 : @guaranteed $ClassProtConformingRef, %1 : @owned $ClassProtConformingRef):
482-
%2 = init_existential_ref %0 : $ClassProtConformingRef : $ClassProtConformingRef, $ClassProt
483-
%3 = copy_value %2 : $ClassProt
484-
%4 = init_existential_ref %1 : $ClassProtConformingRef : $ClassProtConformingRef, $ClassProt
485-
%5 = tuple(%3 : $ClassProt, %4 : $ClassProt)
486-
return %5 : $(ClassProt, ClassProt)
487-
}
488-
489463
sil [ossa] @eliminate_copy_try_apple_callee : $@convention(thin) (@owned Builtin.NativeObject) -> @error Error {
490464
entry(%0 : @owned $Builtin.NativeObject):
491465
%9999 = tuple()

test/SIL/ownership-verifier/use_verifier.sil

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ class UnsafeUnownedFieldKlass {
109109
unowned(safe) var x: @sil_unowned Builtin.NativeObject
110110
}
111111

112+
class ClassProtConformingRef {}
113+
protocol ClassProt : AnyObject {}
114+
extension ClassProtConformingRef : ClassProt {}
115+
112116
////////////////
113117
// Test Cases //
114118
////////////////
@@ -1292,3 +1296,12 @@ bb4:
12921296
destroy_value %1 : $Builtin.NativeObject
12931297
return %9999 : $()
12941298
}
1299+
1300+
sil [ossa] @init_existential_ref_forwarding : $@convention(thin) (@guaranteed ClassProtConformingRef, @owned ClassProtConformingRef) -> @owned (ClassProt, ClassProt) {
1301+
bb0(%0 : @guaranteed $ClassProtConformingRef, %1 : @owned $ClassProtConformingRef):
1302+
%2 = init_existential_ref %0 : $ClassProtConformingRef : $ClassProtConformingRef, $ClassProt
1303+
%3 = copy_value %2 : $ClassProt
1304+
%4 = init_existential_ref %1 : $ClassProtConformingRef : $ClassProtConformingRef, $ClassProt
1305+
%5 = tuple(%3 : $ClassProt, %4 : $ClassProt)
1306+
return %5 : $(ClassProt, ClassProt)
1307+
}

test/SILOptimizer/semantic-arc-opts.sil

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import Builtin
88
// Declarations //
99
//////////////////
1010

11+
typealias AnyObject = Builtin.AnyObject
12+
1113
enum MyNever {}
1214
enum FakeOptional<T> {
1315
case none
@@ -26,7 +28,14 @@ struct NativeObjectPair {
2628

2729
sil @get_nativeobject_pair : $@convention(thin) () -> @owned NativeObjectPair
2830

29-
class Klass {}
31+
protocol MyFakeAnyObject : Klass {
32+
func myFakeMethod()
33+
}
34+
35+
final class Klass {}
36+
extension Klass : MyFakeAnyObject {
37+
func myFakeMethod()
38+
}
3039
sil @guaranteed_klass_user : $@convention(thin) (@guaranteed Klass) -> ()
3140
sil @guaranteed_fakeoptional_klass_user : $@convention(thin) (@guaranteed FakeOptional<Klass>) -> ()
3241
sil @guaranteed_fakeoptional_classlet_user : $@convention(thin) (@guaranteed FakeOptional<ClassLet>) -> ()
@@ -1781,3 +1790,22 @@ bb0(%0 : @guaranteed $ClassLet):
17811790
%9999 = tuple()
17821791
return %9999 : $()
17831792
}
1793+
1794+
// Make sure we can chew through this and get rid of all ARC traffic.
1795+
// CHECK-LABEL: sil [ossa] @init_existential_ref_forwarding_test : $@convention(thin) (@guaranteed Klass) -> () {
1796+
// CHECK-NOT: copy_value
1797+
// CHECK-NOT: begin_borrow
1798+
// CHECK: } // end sil function 'init_existential_ref_forwarding_test'
1799+
sil [ossa] @init_existential_ref_forwarding_test : $@convention(thin) (@guaranteed Klass) -> () {
1800+
bb0(%0 : @guaranteed $Klass):
1801+
%0a = copy_value %0 : $Klass
1802+
%1 = init_existential_ref %0a : $Klass : $Klass, $MyFakeAnyObject
1803+
%1a = begin_borrow %1 : $MyFakeAnyObject
1804+
%2 = open_existential_ref %1a : $MyFakeAnyObject to $@opened("A2E21C52-6089-11E4-9866-3C0754723233") MyFakeAnyObject
1805+
%3 = witness_method $@opened("A2E21C52-6089-11E4-9866-3C0754723233") MyFakeAnyObject, #MyFakeAnyObject.myFakeMethod!1, %2 : $@opened("A2E21C52-6089-11E4-9866-3C0754723233") MyFakeAnyObject : $@convention(witness_method: MyFakeAnyObject) <τ_0_0 where τ_0_0 : MyFakeAnyObject> (@guaranteed τ_0_0) -> ()
1806+
apply %3<@opened("A2E21C52-6089-11E4-9866-3C0754723233") MyFakeAnyObject>(%2) : $@convention(witness_method: MyFakeAnyObject) <τ_0_0 where τ_0_0 : MyFakeAnyObject> (@guaranteed τ_0_0) -> ()
1807+
end_borrow %1a : $MyFakeAnyObject
1808+
destroy_value %1 : $MyFakeAnyObject
1809+
%9999 = tuple()
1810+
return %9999 : $()
1811+
}

0 commit comments

Comments
 (0)