Skip to content

Commit 90df66a

Browse files
authored
Merge pull request #65341 from slavapestov/extended-existential-metadata-5.9
Try harder not to emit calls to swift_getExtendedExistentialTypeMetadata() [5.9]
2 parents 22bfaef + 44dba8f commit 90df66a

File tree

7 files changed

+62
-99
lines changed

7 files changed

+62
-99
lines changed

include/swift/SIL/SILType.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,12 @@ class SILType {
419419
bool hasLocalArchetype() const {
420420
return getASTType()->hasLocalArchetype();
421421
}
422+
423+
/// Returns true if the referenced type is expressed in terms of one
424+
/// or more parameterized protocol types.
425+
bool hasParameterizedExistential() const {
426+
return getASTType()->hasParameterizedExistential();
427+
}
422428

423429
/// Returns the representation used by an existential type. If the concrete
424430
/// type is provided, this may return a specialized representation kind that

lib/IRGen/GenEnum.cpp

Lines changed: 16 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -279,62 +279,6 @@ EnumImplStrategy::emitResilientTagIndices(IRGenModule &IGM) const {
279279
}
280280
}
281281

282-
void EnumImplStrategy::callOutlinedCopy(IRGenFunction &IGF,
283-
Address dest, Address src, SILType T,
284-
IsInitialization_t isInit,
285-
IsTake_t isTake) const {
286-
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling) {
287-
OutliningMetadataCollector collector(IGF);
288-
if (T.hasArchetype()) {
289-
collectMetadataForOutlining(collector, T);
290-
}
291-
collector.emitCallToOutlinedCopy(dest, src, T, *TI, isInit, isTake);
292-
return;
293-
}
294-
295-
if (!T.hasArchetype()) {
296-
// Call the outlined copy function (the implementation will call vwt in this
297-
// case).
298-
OutliningMetadataCollector collector(IGF);
299-
collector.emitCallToOutlinedCopy(dest, src, T, *TI, isInit, isTake);
300-
return;
301-
}
302-
303-
if (isInit == IsInitialization && isTake == IsTake) {
304-
return emitInitializeWithTakeCall(IGF, T, dest, src);
305-
} else if (isInit == IsInitialization && isTake == IsNotTake) {
306-
return emitInitializeWithCopyCall(IGF, T, dest, src);
307-
} else if (isInit == IsNotInitialization && isTake == IsTake) {
308-
return emitAssignWithTakeCall(IGF, T, dest, src);
309-
} else if (isInit == IsNotInitialization && isTake == IsNotTake) {
310-
return emitAssignWithCopyCall(IGF, T, dest, src);
311-
}
312-
llvm_unreachable("unknown case");
313-
}
314-
315-
void EnumImplStrategy::callOutlinedDestroy(IRGenFunction &IGF,
316-
Address addr, SILType T) const {
317-
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling) {
318-
OutliningMetadataCollector collector(IGF);
319-
if (T.hasArchetype()) {
320-
collectMetadataForOutlining(collector, T);
321-
}
322-
collector.emitCallToOutlinedDestroy(addr, T, *TI);
323-
return;
324-
}
325-
326-
if (!T.hasArchetype()) {
327-
// Call the outlined copy function (the implementation will call vwt in this
328-
// case).
329-
OutliningMetadataCollector collector(IGF);
330-
collector.emitCallToOutlinedDestroy(addr, T, *TI);
331-
return;
332-
}
333-
334-
emitDestroyCall(IGF, T, addr);
335-
return;
336-
}
337-
338282
namespace {
339283
/// Implementation strategy for singleton enums, with zero or one cases.
340284
class SingletonEnumImplStrategy final : public EnumImplStrategy {
@@ -549,7 +493,7 @@ namespace {
549493
if (!getSingleton()) return;
550494
if (!ElementsAreABIAccessible) {
551495
emitAssignWithCopyCall(IGF, T, dest, src);
552-
} else if (isOutlined || T.hasLocalArchetype()) {
496+
} else if (isOutlined || T.hasParameterizedExistential()) {
553497
dest = getSingletonAddress(IGF, dest);
554498
src = getSingletonAddress(IGF, src);
555499
getSingleton()->assignWithCopy(
@@ -564,7 +508,7 @@ namespace {
564508
if (!getSingleton()) return;
565509
if (!ElementsAreABIAccessible) {
566510
emitAssignWithTakeCall(IGF, T, dest, src);
567-
} else if (isOutlined || T.hasLocalArchetype()) {
511+
} else if (isOutlined || T.hasParameterizedExistential()) {
568512
dest = getSingletonAddress(IGF, dest);
569513
src = getSingletonAddress(IGF, src);
570514
getSingleton()->assignWithTake(
@@ -586,7 +530,7 @@ namespace {
586530
if (!getSingleton()) return;
587531
if (!ElementsAreABIAccessible) {
588532
emitInitializeWithCopyCall(IGF, T, dest, src);
589-
} else if (isOutlined || T.hasLocalArchetype()) {
533+
} else if (isOutlined || T.hasParameterizedExistential()) {
590534
dest = getSingletonAddress(IGF, dest);
591535
src = getSingletonAddress(IGF, src);
592536
getSingleton()->initializeWithCopy(
@@ -601,7 +545,7 @@ namespace {
601545
if (!getSingleton()) return;
602546
if (!ElementsAreABIAccessible) {
603547
emitInitializeWithTakeCall(IGF, T, dest, src);
604-
} else if (isOutlined || T.hasLocalArchetype()) {
548+
} else if (isOutlined || T.hasParameterizedExistential()) {
605549
dest = getSingletonAddress(IGF, dest);
606550
src = getSingletonAddress(IGF, src);
607551
getSingleton()->initializeWithTake(
@@ -657,7 +601,7 @@ namespace {
657601
!getSingleton()->isTriviallyDestroyable(ResilienceExpansion::Maximal)) {
658602
if (!ElementsAreABIAccessible) {
659603
emitDestroyCall(IGF, T, addr);
660-
} else if (isOutlined || T.hasLocalArchetype()) {
604+
} else if (isOutlined || T.hasParameterizedExistential()) {
661605
getSingleton()->destroy(IGF, getSingletonAddress(IGF, addr),
662606
getSingletonType(IGF.IGM, T), isOutlined);
663607
} else {
@@ -2810,7 +2754,7 @@ namespace {
28102754
}
28112755
if (!ElementsAreABIAccessible) {
28122756
return emitDestroyCall(IGF, T, addr);
2813-
} else if (isOutlined || T.hasLocalArchetype()) {
2757+
} else if (isOutlined || T.hasParameterizedExistential()) {
28142758
switch (CopyDestroyKind) {
28152759
case TriviallyDestroyable:
28162760
return;
@@ -2854,24 +2798,7 @@ namespace {
28542798
}
28552799
}
28562800
} else {
2857-
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling) {
2858-
OutliningMetadataCollector collector(IGF);
2859-
if (T.hasArchetype()) {
2860-
collectMetadataForOutlining(collector, T);
2861-
}
2862-
collector.emitCallToOutlinedDestroy(addr, T, *TI);
2863-
return;
2864-
}
2865-
2866-
if (!T.hasArchetype()) {
2867-
// Call the outlined copy function (the implementation will call vwt
2868-
// in this case).
2869-
OutliningMetadataCollector collector(IGF);
2870-
collector.emitCallToOutlinedDestroy(addr, T, *TI);
2871-
return;
2872-
}
2873-
2874-
emitDestroyCall(IGF, T, addr);
2801+
callOutlinedDestroy(IGF, addr, T);
28752802
return;
28762803
}
28772804
}
@@ -3114,7 +3041,7 @@ namespace {
31143041
SILType T, bool isOutlined) const override {
31153042
if (!ElementsAreABIAccessible) {
31163043
emitAssignWithCopyCall(IGF, T, dest, src);
3117-
} else if (isOutlined || T.hasLocalArchetype()) {
3044+
} else if (isOutlined || T.hasParameterizedExistential()) {
31183045
emitIndirectAssign(IGF, dest, src, T, IsNotTake, isOutlined);
31193046
} else {
31203047
callOutlinedCopy(IGF, dest, src, T, IsNotInitialization, IsNotTake);
@@ -3125,7 +3052,7 @@ namespace {
31253052
SILType T, bool isOutlined) const override {
31263053
if (!ElementsAreABIAccessible) {
31273054
emitAssignWithTakeCall(IGF, T, dest, src);
3128-
} else if (isOutlined || T.hasLocalArchetype()) {
3055+
} else if (isOutlined || T.hasParameterizedExistential()) {
31293056
emitIndirectAssign(IGF, dest, src, T, IsTake, isOutlined);
31303057
} else {
31313058
callOutlinedCopy(IGF, dest, src, T, IsNotInitialization, IsTake);
@@ -3136,7 +3063,7 @@ namespace {
31363063
SILType T, bool isOutlined) const override {
31373064
if (!ElementsAreABIAccessible) {
31383065
emitInitializeWithCopyCall(IGF, T, dest, src);
3139-
} else if (isOutlined || T.hasLocalArchetype()) {
3066+
} else if (isOutlined || T.hasParameterizedExistential()) {
31403067
emitIndirectInitialize(IGF, dest, src, T, IsNotTake, isOutlined);
31413068
} else {
31423069
callOutlinedCopy(IGF, dest, src, T, IsInitialization, IsNotTake);
@@ -3147,7 +3074,7 @@ namespace {
31473074
SILType T, bool isOutlined) const override {
31483075
if (!ElementsAreABIAccessible) {
31493076
emitInitializeWithTakeCall(IGF, T, dest, src);
3150-
} else if (isOutlined || T.hasLocalArchetype()) {
3077+
} else if (isOutlined || T.hasParameterizedExistential()) {
31513078
emitIndirectInitialize(IGF, dest, src, T, IsTake, isOutlined);
31523079
} else {
31533080
callOutlinedCopy(IGF, dest, src, T, IsInitialization, IsTake);
@@ -4972,7 +4899,7 @@ namespace {
49724899
SILType T, bool isOutlined) const override {
49734900
if (!ElementsAreABIAccessible) {
49744901
emitAssignWithCopyCall(IGF, T, dest, src);
4975-
} else if (isOutlined || T.hasLocalArchetype()) {
4902+
} else if (isOutlined || T.hasParameterizedExistential()) {
49764903
emitIndirectAssign(IGF, dest, src, T, IsNotTake, isOutlined);
49774904
} else {
49784905
callOutlinedCopy(IGF, dest, src, T, IsNotInitialization, IsNotTake);
@@ -4983,7 +4910,7 @@ namespace {
49834910
SILType T, bool isOutlined) const override {
49844911
if (!ElementsAreABIAccessible) {
49854912
emitAssignWithTakeCall(IGF, T, dest, src);
4986-
} else if (isOutlined || T.hasLocalArchetype()) {
4913+
} else if (isOutlined || T.hasParameterizedExistential()) {
49874914
emitIndirectAssign(IGF, dest, src, T, IsTake, isOutlined);
49884915
} else {
49894916
callOutlinedCopy(IGF, dest, src, T, IsNotInitialization, IsTake);
@@ -4994,7 +4921,7 @@ namespace {
49944921
SILType T, bool isOutlined) const override {
49954922
if (!ElementsAreABIAccessible) {
49964923
emitInitializeWithCopyCall(IGF, T, dest, src);
4997-
} else if (isOutlined || T.hasLocalArchetype()) {
4924+
} else if (isOutlined || T.hasParameterizedExistential()) {
49984925
emitIndirectInitialize(IGF, dest, src, T, IsNotTake, isOutlined);
49994926
} else {
50004927
callOutlinedCopy(IGF, dest, src, T, IsInitialization, IsNotTake);
@@ -5005,7 +4932,7 @@ namespace {
50054932
SILType T, bool isOutlined) const override {
50064933
if (!ElementsAreABIAccessible) {
50074934
emitInitializeWithTakeCall(IGF, T, dest, src);
5008-
} else if (isOutlined || T.hasLocalArchetype()) {
4935+
} else if (isOutlined || T.hasParameterizedExistential()) {
50094936
emitIndirectInitialize(IGF, dest, src, T, IsTake, isOutlined);
50104937
} else {
50114938
callOutlinedCopy(IGF, dest, src, T, IsInitialization, IsTake);
@@ -5039,7 +4966,7 @@ namespace {
50394966
}
50404967
if (!ElementsAreABIAccessible) {
50414968
emitDestroyCall(IGF, T, addr);
5042-
} else if (isOutlined || T.hasLocalArchetype()) {
4969+
} else if (isOutlined || T.hasParameterizedExistential()) {
50434970
switch (CopyDestroyKind) {
50444971
case TriviallyDestroyable:
50454972
return;

lib/IRGen/GenEnum.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,9 +449,13 @@ class EnumImplStrategy {
449449

450450
void callOutlinedCopy(IRGenFunction &IGF, Address dest, Address src,
451451
SILType T, IsInitialization_t isInit,
452-
IsTake_t isTake) const;
452+
IsTake_t isTake) const {
453+
TI->callOutlinedCopy(IGF, dest, src, T, isInit, isTake);
454+
}
453455

454-
void callOutlinedDestroy(IRGenFunction &IGF, Address addr, SILType T) const;
456+
void callOutlinedDestroy(IRGenFunction &IGF, Address addr, SILType T) const {
457+
TI->callOutlinedDestroy(IGF, addr, T);
458+
}
455459

456460
virtual void collectMetadataForOutlining(OutliningMetadataCollector &collector,
457461
SILType T) const = 0;

lib/IRGen/GenRecord.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ class RecordTypeInfoImpl : public Base,
170170
return emitAssignWithCopyCall(IGF, T, dest, src);
171171
}
172172

173-
if (isOutlined || T.hasLocalArchetype()) {
173+
if (isOutlined || T.hasParameterizedExistential()) {
174174
auto offsets = asImpl().getNonFixedOffsets(IGF, T);
175175
for (auto &field : getFields()) {
176176
if (field.isEmpty())
@@ -193,7 +193,7 @@ class RecordTypeInfoImpl : public Base,
193193
return emitAssignWithTakeCall(IGF, T, dest, src);
194194
}
195195

196-
if (isOutlined || T.hasLocalArchetype()) {
196+
if (isOutlined || T.hasParameterizedExistential()) {
197197
auto offsets = asImpl().getNonFixedOffsets(IGF, T);
198198
for (auto &field : getFields()) {
199199
if (field.isEmpty())
@@ -223,7 +223,7 @@ class RecordTypeInfoImpl : public Base,
223223
return emitInitializeWithCopyCall(IGF, T, dest, src);
224224
}
225225

226-
if (isOutlined || T.hasLocalArchetype()) {
226+
if (isOutlined || T.hasParameterizedExistential()) {
227227
auto offsets = asImpl().getNonFixedOffsets(IGF, T);
228228
for (auto &field : getFields()) {
229229
if (field.isEmpty())
@@ -255,7 +255,7 @@ class RecordTypeInfoImpl : public Base,
255255
return emitInitializeWithTakeCall(IGF, T, dest, src);
256256
}
257257

258-
if (isOutlined || T.hasLocalArchetype()) {
258+
if (isOutlined || T.hasParameterizedExistential()) {
259259
auto offsets = asImpl().getNonFixedOffsets(IGF, T);
260260
for (auto &field : getFields()) {
261261
if (field.isEmpty())
@@ -278,7 +278,7 @@ class RecordTypeInfoImpl : public Base,
278278
return emitDestroyCall(IGF, T, addr);
279279
}
280280

281-
if (isOutlined || T.hasLocalArchetype()) {
281+
if (isOutlined || T.hasParameterizedExistential()) {
282282
auto offsets = asImpl().getNonFixedOffsets(IGF, T);
283283
for (auto &field : getFields()) {
284284
if (field.isTriviallyDestroyable())

lib/IRGen/Outlining.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ irgen::getTypeAndGenericSignatureForManglingOutlineFunction(SILType type) {
138138
void TypeInfo::callOutlinedCopy(IRGenFunction &IGF, Address dest, Address src,
139139
SILType T, IsInitialization_t isInit,
140140
IsTake_t isTake) const {
141-
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling) {
141+
if (!T.hasLocalArchetype() &&
142+
!IGF.IGM.getOptions().UseTypeLayoutValueHandling) {
142143
OutliningMetadataCollector collector(IGF);
143144
if (T.hasArchetype()) {
144145
collectMetadataForOutlining(collector, T);
@@ -340,7 +341,8 @@ void TypeInfo::callOutlinedDestroy(IRGenFunction &IGF,
340341
if (IGF.IGM.getTypeLowering(T).isTrivial())
341342
return;
342343

343-
if (!IGF.IGM.getOptions().UseTypeLayoutValueHandling) {
344+
if (!T.hasLocalArchetype() &&
345+
!IGF.IGM.getOptions().UseTypeLayoutValueHandling) {
344346
OutliningMetadataCollector collector(IGF);
345347
if (T.hasArchetype()) {
346348
collectMetadataForOutlining(collector, T);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %s
2+
// RUN: %target-swift-frontend -emit-ir -O %s | %FileCheck %s
3+
4+
protocol Foo<T> {
5+
associatedtype T
6+
func acceptEvent<T>(event: T)
7+
}
8+
9+
protocol FooFactory<T> {
10+
associatedtype T
11+
func makeFoo() -> any Foo<T>
12+
}
13+
14+
class Bar<T> {
15+
private var foo: (any Foo<T>)
16+
17+
init(fooFactory: any FooFactory<T>) {
18+
self.foo = fooFactory.makeFoo()
19+
}
20+
}
21+
22+
// CHECK-NOT: swift_getExtendedExistentialTypeMetadata

test/IRGen/variadic_generic_outlining.sil

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ struct Wrapper<Value> {
1616
// CHECK-NEXT: [[PACK:%.*]] = inttoptr [[INT]] [[PACK_ADDR2]] to %swift.type**
1717
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[PACK]], [[INT]]
1818
// CHECK-NEXT: [[ELT_TYPE:%.*]] = load %swift.type*, %swift.type** [[T0]], align
19+
// CHECK: [[WRAPPER_RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$s26variadic_generic_outlining7WrapperVMa"
20+
// CHECK-NEXT: [[WRAPPER_TYPE:%.*]] = extractvalue %swift.metadata_response [[WRAPPER_RESPONSE]]
1921
// Test that we do the copy through the VWT for the element type.
20-
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[ELT_TYPE]] to i8***
22+
// CHECK-NEXT: [[T0:%.*]] = bitcast %swift.type* [[WRAPPER_TYPE]] to i8***
2123
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], [[INT]] -1
2224
sil hidden @test_outlining : $@convention(thin) <each T> (@pack_guaranteed Pack{repeat Wrapper<each T>}) -> @pack_out Pack{repeat Wrapper<each T>} {
2325
bb0(%0 : $*Pack{repeat Wrapper<each T>}, %1 : $*Pack{repeat Wrapper<each T>}):

0 commit comments

Comments
 (0)