Skip to content

Commit dac39b1

Browse files
committed
[metadata prespecialization] Direct refs to enums.
When a specialized usage of a generic enum occurs in the same module where the enum was defined, directly reference the prespecialized metadata. rdar://problem/56994321
1 parent 7e35c64 commit dac39b1

File tree

27 files changed

+1869
-19
lines changed

27 files changed

+1869
-19
lines changed

lib/IRGen/MetadataRequest.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -684,11 +684,6 @@ bool irgen::isNominalGenericContextTypeMetadataAccessTrivial(
684684
return false;
685685
}
686686

687-
if (isa<EnumType>(type) || isa<BoundGenericEnumType>(type)) {
688-
// TODO: Support enums.
689-
return false;
690-
}
691-
692687
if (isa<ClassType>(type) || isa<BoundGenericClassType>(type)) {
693688
// TODO: Support classes.
694689
return false;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
public protocol P {
2+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@frozen
2+
public struct Integer {
3+
public let value: Int
4+
5+
public init(_ value: Int) {
6+
self.value = value
7+
}
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
public struct Integer {
2+
public let value: Int
3+
4+
public init(_ value: Int) {
5+
self.value = value
6+
}
7+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// RUN: %swift -target %module-target-future -emit-ir -prespecialize-generic-metadata %s | %FileCheck %s -DINT=i%target-ptrsize -DALIGNMENT=%target-alignment
2+
3+
// UNSUPPORTED: CPU=i386 && OS=ios
4+
// UNSUPPORTED: CPU=armv7 && OS=ios
5+
// UNSUPPORTED: CPU=armv7s && OS=ios
6+
7+
// CHECK: @"$s4main5Value[[UNIQUE_ID_1:[0-9A-Z_]+]]OySiGMf" = internal constant <{
8+
// CHECK-SAME: i8**,
9+
// CHECK-SAME: [[INT]],
10+
// CHECK-SAME: %swift.type_descriptor*,
11+
// CHECK-SAME: %swift.type*,
12+
// CHECK-SAME: i64
13+
// CHECK-SAME: }> <{
14+
// i8** getelementptr inbounds (%swift.enum_vwtable, %swift.enum_vwtable* @"$s4main5Value[[UNIQUE_ID_1]]OySiGWV", i32 0, i32 0),
15+
// CHECK-SAME: [[INT]] 513,
16+
// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5Value[[UNIQUE_ID_1]]OMn" to %swift.type_descriptor*),
17+
// CHECK-SAME: %swift.type* @"$sSiN",
18+
// CHECK-SAME: i64 3
19+
// CHECK-SAME: }>, align [[ALIGNMENT]]
20+
21+
fileprivate enum Value<First> {
22+
case first(First)
23+
}
24+
25+
@inline(never)
26+
func consume<T>(_ t: T) {
27+
withExtendedLifetime(t) { t in
28+
}
29+
}
30+
31+
// CHECK: define hidden swiftcc void @"$s4main4doityyF"() #{{[0-9]+}} {
32+
// CHECK: call swiftcc void @"$s4main7consumeyyxlF"(
33+
// CHECK-SAME: %swift.opaque* noalias nocapture %{{[0-9]+}},
34+
// CHECK-SAME: %swift.type* getelementptr inbounds (
35+
// CHECK-SAME: %swift.full_type,
36+
// CHECK-SAME: %swift.full_type* bitcast (
37+
// CHECK-SAME: <{
38+
// CHECK-SAME: i8**,
39+
// CHECK-SAME: [[INT]],
40+
// CHECK-SAME: %swift.type_descriptor*,
41+
// CHECK-SAME: %swift.type*,
42+
// CHECK-SAME: i64
43+
// CHECK-SAME: }>* @"$s4main5Value[[UNIQUE_ID_1]]OySiGMf"
44+
// CHECK-SAME: to %swift.full_type*
45+
// CHECK-SAME: ),
46+
// CHECK-SAME: i32 0,
47+
// CHECK-SAME: i32 1
48+
// CHECK-SAME: )
49+
// CHECK-SAME: )
50+
// CHECK: }
51+
func doit() {
52+
consume( Value.first(13) )
53+
}
54+
doit()
55+
56+
// CHECK: ; Function Attrs: noinline nounwind readnone
57+
// CHECK: define internal swiftcc %swift.metadata_response @"$s4main5Value[[UNIQUE_ID_1]]OMa"([[INT]], %swift.type*) #{{[0-9]+}} {
58+
// CHECK: entry:
59+
// CHECK: [[ERASED_TYPE:%[0-9]+]] = bitcast %swift.type* %1 to i8*
60+
// CHECK: br label %[[TYPE_COMPARISON_LABEL:[0-9]+]]
61+
// CHECK: [[TYPE_COMPARISON_LABEL]]:
62+
// CHECK: [[EQUAL_TYPE:%[0-9]+]] = icmp eq i8* bitcast (%swift.type* @"$sSiN" to i8*), [[ERASED_TYPE]]
63+
// CHECK: [[EQUAL_TYPES:%[0-9]+]] = and i1 true, [[EQUAL_TYPE]]
64+
// CHECK: br i1 [[EQUAL_TYPES]], label %[[EXIT_PRESPECIALIZED:[0-9]+]], label %[[EXIT_NORMAL:[0-9]+]]
65+
// CHECK: [[EXIT_PRESPECIALIZED]]:
66+
// CHECK: ret %swift.metadata_response {
67+
// CHECK-SAME: %swift.type* getelementptr inbounds (
68+
// CHECK-SAME: %swift.full_type,
69+
// CHECK-SAME: %swift.full_type* bitcast (
70+
// CHECK-SAME: <{
71+
// CHECK-SAME: i8**,
72+
// CHECK-SAME: [[INT]],
73+
// CHECK-SAME: %swift.type_descriptor*,
74+
// CHECK-SAME: %swift.type*,
75+
// CHECK-SAME: i64
76+
// CHECK-SAME: }>* @"$s4main5Value[[UNIQUE_ID_1]]OySiGMf"
77+
// CHECK-SAME: to %swift.full_type*
78+
// CHECK-SAME: ),
79+
// CHECK-SAME: i32 0,
80+
// CHECK-SAME: i32 1
81+
// CHECK-SAME: ),
82+
// CHECK-SAME: [[INT]] 0
83+
// CHECK-SAME: }
84+
// CHECK: [[EXIT_NORMAL]]:
85+
// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* undef, i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main5Value[[UNIQUE_ID_1]]OMn" to %swift.type_descriptor*)) #{{[0-9]+}}
86+
// CHECK: ret %swift.metadata_response {{%[0-9]+}}
87+
// CHECK: }
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// RUN: %swift -target %module-target-future -emit-ir -prespecialize-generic-metadata %s | %FileCheck %s -DINT=i%target-ptrsize -DALIGNMENT=%target-alignment
2+
3+
// UNSUPPORTED: CPU=i386 && OS=ios
4+
// UNSUPPORTED: CPU=armv7 && OS=ios
5+
// UNSUPPORTED: CPU=armv7s && OS=ios
6+
7+
// CHECK: @"$s4main9NamespaceC5ValueOySi_GMf" = internal constant <{
8+
// CHECk-SAME: i8**,
9+
// CHECK-SAME: [[INT]],
10+
// CHECK-SAME: %swift.type_descriptor*,
11+
// CHECK-SAME: %swift.type*,
12+
// CHECK-SAME: }> <{
13+
// i8** getelementptr inbounds (
14+
// %swift.enum_vwtable,
15+
// %swift.enum_vwtable* @"$s4main9NamespaceC5ValueOySi_GWV",
16+
// i32 0,
17+
// i32 0
18+
// ),
19+
// CHECK-SAME: [[INT]] 513,
20+
// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main9NamespaceC5ValueOMn" to %swift.type_descriptor*),
21+
// CHECK-SAME: %swift.type* @"$sSiN",
22+
// CHECK-SAME: i64 3
23+
// CHECK-SAME: }>, align [[ALIGNMENT]]
24+
25+
26+
final class Namespace<First> {
27+
enum Value {
28+
case first(First)
29+
}
30+
}
31+
32+
@inline(never)
33+
func consume<T>(_ t: T) {
34+
withExtendedLifetime(t) { t in
35+
}
36+
}
37+
38+
// CHECK: define hidden swiftcc void @"$s4main4doityyF"() #{{[0-9]+}} {
39+
// CHECK: call swiftcc void @"$s4main7consumeyyxlF"(
40+
// CHECK-SAME: %swift.opaque* noalias nocapture %{{[0-9]+}},
41+
// CHECK-SAME: %swift.type* getelementptr inbounds (
42+
// CHECK-SAME: %swift.full_type,
43+
// CHECK-SAME: %swift.full_type* bitcast (
44+
// CHECK-SAME: <{
45+
// CHECK-SAME: i8**,
46+
// CHECK-SAME: [[INT]],
47+
// CHECK-SAME: %swift.type_descriptor*,
48+
// CHECK-SAME: %swift.type*,
49+
// CHECK-SAME: i64
50+
// CHECK-SAME: }>* @"$s4main9NamespaceC5ValueOySi_GMf"
51+
// CHECK-SAME: to %swift.full_type*
52+
// CHECK-SAME: ),
53+
// CHECK-SAME: i32 0,
54+
// CHECK-SAME: i32 1
55+
// CHECK-SAME: )
56+
// CHECK-SAME: )
57+
// CHECK: }
58+
func doit() {
59+
consume( Namespace.Value.first(13) )
60+
}
61+
doit()
62+
63+
// CHECK: ; Function Attrs: noinline nounwind readnone
64+
// CHECK: define hidden swiftcc %swift.metadata_response @"$s4main9NamespaceC5ValueOMa"([[INT]], %swift.type*) #{{[0-9]+}} {
65+
// CHECK: entry:
66+
// CHECK: [[ERASED_TYPE_1:%[0-9]+]] = bitcast %swift.type* %1 to i8*
67+
// CHECK: br label %[[TYPE_COMPARISON_1:[0-9]+]]
68+
// CHECK: [[TYPE_COMPARISON_1]]:
69+
// CHECK: [[EQUAL_TYPE_1_1:%[0-9]+]] = icmp eq i8* bitcast (%swift.type* @"$sSiN" to i8*), [[ERASED_TYPE_1]]
70+
// CHECK: [[EQUAL_TYPES_1_1:%[0-9]+]] = and i1 true, [[EQUAL_TYPE_1_1]]
71+
// CHECK: br i1 [[EQUAL_TYPES_1_1]], label %[[EXIT_PRESPECIALIZED_1:[0-9]+]], label %[[EXIT_NORMAL:[0-9]+]]
72+
// CHECK: [[EXIT_PRESPECIALIZED_1]]:
73+
// CHECK: ret %swift.metadata_response {
74+
// CHECK-SAME: %swift.type* getelementptr inbounds (
75+
// CHECK-SAME: %swift.full_type,
76+
// CHECK-SAME: %swift.full_type* bitcast (
77+
// CHECK-SAME: <{
78+
// CHECK-SAME: i8**,
79+
// CHECK-SAME: [[INT]],
80+
// CHECK-SAME: %swift.type_descriptor*,
81+
// CHECK-SAME: %swift.type*,
82+
// CHECK-SAME: i64
83+
// CHECK-SAME: }>* @"$s4main9NamespaceC5ValueOySi_GMf"
84+
// CHECK-SAME: to %swift.full_type*
85+
// CHECK-SAME: ),
86+
// CHECK-SAME: i32 0,
87+
// CHECK-SAME: i32 1
88+
// CHECK-SAME: ),
89+
// CHECK-SAME: [[INT]] 0
90+
// CHECK-SAME: }
91+
// CHECK: [[EXIT_NORMAL]]:
92+
// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE_1]], i8* undef, i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>* @"$s4main9NamespaceC5ValueOMn" to %swift.type_descriptor*)) #{{[0-9]+}}
93+
// CHECK: ret %swift.metadata_response {{%[0-9]+}}
94+
// CHECK: }
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// RUN: %swift -target %module-target-future -emit-ir -prespecialize-generic-metadata %s | %FileCheck %s -DINT=i%target-ptrsize -DALIGNMENT=%target-alignment
2+
3+
// UNSUPPORTED: CPU=i386 && OS=ios
4+
// UNSUPPORTED: CPU=armv7 && OS=ios
5+
// UNSUPPORTED: CPU=armv7s && OS=ios
6+
7+
enum Value<First> {
8+
case first(First)
9+
}
10+
11+
@inline(never)
12+
func consume<T>(_ t: T) {
13+
withExtendedLifetime(t) { t in
14+
}
15+
}
16+
17+
// CHECK: define hidden swiftcc void @"$s4main4doityyF"() #{{[0-9]+}} {
18+
// CHECK: }
19+
func doit() {
20+
}
21+
doit()
22+
23+
// CHECK: ; Function Attrs: noinline nounwind readnone
24+
// CHECK: define hidden swiftcc %swift.metadata_response @"$s4main5ValueOMa"([[INT]], %swift.type*) #{{[0-9]+}} {
25+
// CHECK: entry:
26+
// CHECK: [[ERASED_TYPE:%[0-9]+]] = bitcast %swift.type* %1 to i8*
27+
// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata(
28+
// CHECK-SAME: [[INT]] %0,
29+
// CHECK-SAME: i8* [[ERASED_TYPE]],
30+
// CHECK-SAME: i8* undef,
31+
// CHECK-SAME: i8* undef,
32+
// CHECK-SAME: %swift.type_descriptor* bitcast (
33+
// CHECK-SAME: <{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8 }>*
34+
// CHECK-SAME: @"$s4main5ValueOMn"
35+
// CHECK-SAME: to %swift.type_descriptor*
36+
// CHECK-SAME: )
37+
// CHECK-SAME: ) #{{[0-9]+}}
38+
// CHECK: ret %swift.metadata_response {{%[0-9]+}}
39+
// CHECK: }
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// RUN: %swift -target %module-target-future -emit-ir -prespecialize-generic-metadata %s | %FileCheck %s -DINT=i%target-ptrsize -DALIGNMENT=%target-alignment
2+
3+
// UNSUPPORTED: CPU=i386 && OS=ios
4+
// UNSUPPORTED: CPU=armv7 && OS=ios
5+
// UNSUPPORTED: CPU=armv7s && OS=ios
6+
7+
// CHECK: @"$sytN" = external{{( dllimport)?}} global %swift.full_type
8+
9+
// CHECK: @"$s4main5ValueOySiGMf" = internal constant <{
10+
// CHECK-SAME: i8**,
11+
// CHECK-SAME: [[INT]],
12+
// CHECK-SAME: %swift.type_descriptor*,
13+
// CHECK-SAME: %swift.type*,
14+
// CHECK-SAME: i8**,
15+
// CHECK-SAME: i64
16+
// CHECK-SAME: }> <{
17+
// CHECK-SAME: i8** getelementptr inbounds (%swift.enum_vwtable, %swift.enum_vwtable* @"$s4main5ValueOySiGWV", i32 0, i32 0),
18+
// CHECK-SAME: [[INT]] 513,
19+
// CHECK-SAME: %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*),
20+
// CHECK-SAME: %swift.type* @"$sSiN",
21+
// CHECK-SAME: i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"$sSi4main1PAAWP", i32 0, i32 0),
22+
// CHECK-SAME: i64 3
23+
// CHECK-SAME: }>, align [[ALIGNMENT]]
24+
25+
protocol P {}
26+
extension Int : P {}
27+
enum Value<First : P> {
28+
case first(First)
29+
}
30+
31+
@inline(never)
32+
func consume<T>(_ t: T) {
33+
withExtendedLifetime(t) { t in
34+
}
35+
}
36+
37+
// CHECK: define hidden swiftcc void @"$s4main4doityyF"() #{{[0-9]+}} {
38+
// CHECK: call swiftcc void @"$s4main7consumeyyxlF"(
39+
// CHECK-SAME: %swift.opaque* noalias nocapture %{{[0-9]+}},
40+
// CHECK-SAME: %swift.type* getelementptr inbounds (
41+
// CHECK-SAME: %swift.full_type,
42+
// CHECK-SAME: %swift.full_type* bitcast (
43+
// CHECK-SAME: <{
44+
// CHECK-SAME: i8**,
45+
// CHECK-SAME: [[INT]],
46+
// CHECK-SAME: %swift.type_descriptor*,
47+
// CHECK-SAME: %swift.type*,
48+
// CHECK-SAME: i8**,
49+
// CHECK-SAME: i64
50+
// CHECK-SAME: }>* @"$s4main5ValueOySiGMf"
51+
// CHECK-SAME: to %swift.full_type*
52+
// CHECK-SAME: ),
53+
// CHECK-SAME: i32 0,
54+
// CHECK-SAME: i32 1
55+
// CHECK-SAME: )
56+
// CHECK-SAME: )
57+
// CHECK: }
58+
func doit() {
59+
consume( Value.first(13) )
60+
}
61+
doit()
62+
63+
// CHECK: ; Function Attrs: noinline nounwind readnone
64+
// CHECK: define hidden swiftcc %swift.metadata_response @"$s4main5ValueOMa"([[INT]], %swift.type*, i8**) #{{[0-9]+}} {
65+
// CHECK: entry:
66+
// CHECK: [[ERASED_TYPE:%[0-9]+]] = bitcast %swift.type* %1 to i8*
67+
// CHECK: [[ERASED_TABLE:%[0-9]+]] = bitcast i8** %2 to i8*
68+
// CHECK: br label %[[TYPE_COMPARISON_LABEL:[0-9]+]]
69+
// CHECK: [[TYPE_COMPARISON_LABEL]]:
70+
// CHECK: [[EQUAL_TYPE:%[0-9]+]] = icmp eq i8* bitcast (%swift.type* @"$sSiN" to i8*), [[ERASED_TYPE]]
71+
// CHECK: [[EQUAL_TYPES:%[0-9]+]] = and i1 true, [[EQUAL_TYPE]]
72+
// CHECK: br i1 [[EQUAL_TYPES]], label %[[EXIT_PRESPECIALIZED:[0-9]+]], label %[[EXIT_NORMAL:[0-9]+]]
73+
// CHECK: [[EXIT_PRESPECIALIZED]]:
74+
// CHECK: ret %swift.metadata_response {
75+
// CHECK-SAME: %swift.type* getelementptr inbounds (
76+
// CHECK-SAME: %swift.full_type,
77+
// CHECK-SAME: %swift.full_type* bitcast (
78+
// CHECK-SAME: <{
79+
// CHECK-SAME: i8**,
80+
// CHECK-SAME: [[INT]],
81+
// CHECK-SAME: %swift.type_descriptor*,
82+
// CHECK-SAME: %swift.type*,
83+
// CHECK-SAME: i8**,
84+
// CHECK-SAME: i64
85+
// CHECK-SAME: }>* @"$s4main5ValueOySiGMf"
86+
// CHECK-SAME: to %swift.full_type*
87+
// CHECK-SAME: ),
88+
// CHECK-SAME: i32 0,
89+
// CHECK-SAME: i32 1
90+
// CHECK-SAME: ),
91+
// CHECK-SAME: [[INT]] 0
92+
// CHECK-SAME: }
93+
// CHECK: [[EXIT_NORMAL]]:
94+
// CHECK: {{%[0-9]+}} = call swiftcc %swift.metadata_response @__swift_instantiateGenericMetadata([[INT]] %0, i8* [[ERASED_TYPE]], i8* [[ERASED_TABLE]], i8* undef, %swift.type_descriptor* bitcast (<{ i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, i16, i16, i16, i8, i8, i8, i8, i32, i32, i32 }>* @"$s4main5ValueOMn" to %swift.type_descriptor*))
95+
// CHECK: ret %swift.metadata_response {{%[0-9]+}}
96+
// CHECK: }

0 commit comments

Comments
 (0)