Skip to content

Commit fa3140e

Browse files
committed
Merge pull request #2699 from eeckstein/conformance-linkage
IRGen: Don't emit externally available witness tables.
2 parents 15816fc + 48b9ab0 commit fa3140e

File tree

3 files changed

+13
-17
lines changed

3 files changed

+13
-17
lines changed

lib/IRGen/GenProto.cpp

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1586,12 +1586,11 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
15861586
if (wt->isDeclaration())
15871587
return;
15881588

1589-
bool mustEmitDefinition = !isAvailableExternally(wt->getLinkage());
1590-
1591-
// Don't emit a witness table that is available externally if we are emitting
1592-
// code for the JIT. We do not do any optimization for the JIT and it has
1593-
// problems with external symbols that get merged with non-external symbols.
1594-
if (IRGen.Opts.UseJIT && !mustEmitDefinition)
1589+
// Don't emit a witness table that is available externally.
1590+
// It can end up in having duplicate sumbols for generated associated type
1591+
// metadata access functions.
1592+
// Also, it is not a big benefit for LLVM to emit such witness tables.
1593+
if (isAvailableExternally(wt->getLinkage()))
15951594
return;
15961595

15971596
// Build the witnesses.
@@ -1614,13 +1613,7 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
16141613
global->setAlignment(getWitnessTableAlignment().getValue());
16151614

16161615
// FIXME: resilience; this should use the conformance's publishing scope.
1617-
if (mustEmitDefinition) {
1618-
wtableBuilder.buildAccessFunction(global);
1619-
}
1620-
1621-
// Build the conformance record, if it lives in this TU.
1622-
if (!mustEmitDefinition)
1623-
return;
1616+
wtableBuilder.buildAccessFunction(global);
16241617

16251618
// Behavior conformances can't be reflected.
16261619
if (wt->getConformance()->isBehaviorConformance())

test/IRGen/existential_metatypes.sil

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ extension Float : Kindable {
1919
public var kind: Int { get }
2020
}
2121

22+
// CHECK: @_TWPSi21existential_metatypes8KindableS_ = external global i8*, align 8
23+
// CHECK: @_TWPSf21existential_metatypes8KindableS_ = external global i8*, align 8
24+
2225
sil @int_kind_getter : $@convention(method) (Int) -> Int {
2326
bb0(%0 : $Int):
2427
%2 = integer_literal $Builtin.Int64, 0
@@ -62,15 +65,15 @@ bb0:
6265
%1 = metatype $@thin Int.Type
6366
%2 = metatype $@thick Int.Type
6467
%3 = init_existential_metatype %2 : $@thick Int.Type, $@thick Kindable.Type
65-
// CHECK-NEXT: store i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @_TWPSi21existential_metatypes8KindableS_, i32 0, i32 0), i8*** [[T0]], align 8
68+
// CHECK-NEXT: store i8** @_TWPSi21existential_metatypes8KindableS_, i8*** [[T0]], align 8
6669
store %3 to %0 : $*@thick Kindable.Type
6770
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { %swift.type*, i8** }, { %swift.type*, i8** }* [[V]], i32 0, i32 0
6871
// CHECK-NEXT: store %swift.type* @_TMSf, %swift.type** [[T0]], align 8
6972
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { %swift.type*, i8** }, { %swift.type*, i8** }* [[V]], i32 0, i32 1
7073
%5 = metatype $@thin Float.Type
7174
%6 = metatype $@thick Float.Type
7275
%7 = init_existential_metatype %6 : $@thick Float.Type, $@thick Kindable.Type
73-
// CHECK-NEXT: store i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @_TWPSf21existential_metatypes8KindableS_, i32 0, i32 0), i8*** [[T0]], align 8
76+
// CHECK-NEXT: store i8** @_TWPSf21existential_metatypes8KindableS_, i8*** [[T0]], align 8
7477
store %7 to %0 : $*@thick Kindable.Type
7578
%9 = tuple ()
7679
// CHECK-NEXT: bitcast

test/IRGen/sil_witness_tables.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ struct Conformer: Q, QQ {
3636
func qMethod() {}
3737
}
3838

39+
// CHECK: [[EXTERNAL_CONFORMER_EXTERNAL_P_WITNESS_TABLE:@_TWPV39sil_witness_tables_external_conformance17ExternalConformerS_9ExternalPS_]] = external global i8*, align 8
3940
// CHECK: [[CONFORMER_Q_WITNESS_TABLE:@_TWPV18sil_witness_tables9ConformerS_1QS_]] = hidden constant [2 x i8*] [
4041
// CHECK: i8* bitcast ([4 x i8*]* [[CONFORMER_P_WITNESS_TABLE:@_TWPV18sil_witness_tables9ConformerS_1PS_]] to i8*),
4142
// CHECK: i8* bitcast (void (%V18sil_witness_tables9Conformer*, %swift.type*, i8**)* @_TTWV18sil_witness_tables9ConformerS_1QS_FS1_7qMethod{{.*}} to i8*)
@@ -47,7 +48,6 @@ struct Conformer: Q, QQ {
4748
// CHECK: i8* bitcast (void (%V18sil_witness_tables9Conformer*, %swift.type*, i8**)* @_TTWV18sil_witness_tables9ConformerS_1PS_FS1_14instanceMethod{{.*}} to i8*)
4849
// CHECK: ]
4950
// CHECK: [[CONFORMER2_P_WITNESS_TABLE:@_TWPV18sil_witness_tables10Conformer2S_1PS_]] = hidden constant [4 x i8*]
50-
// CHECK: [[EXTERNAL_CONFORMER_EXTERNAL_P_WITNESS_TABLE:@_TWPV39sil_witness_tables_external_conformance17ExternalConformerS_9ExternalPS_]] = available_externally constant [0 x i8*]
5151

5252
struct Conformer2: Q {
5353
typealias Assoc = AssocConformer
@@ -66,7 +66,7 @@ func erasure(c c: Conformer) -> QQ {
6666

6767
// CHECK-LABEL: define hidden void @_TF18sil_witness_tables15externalErasureFT1cV39sil_witness_tables_external_conformance17ExternalConformer_PS0_9ExternalP_(%P39sil_witness_tables_external_conformance9ExternalP_* noalias nocapture sret)
6868
// CHECK: [[WITNESS_TABLE_ADDR:%.*]] = getelementptr inbounds %P39sil_witness_tables_external_conformance9ExternalP_, %P39sil_witness_tables_external_conformance9ExternalP_* %0, i32 0, i32 2
69-
// CHECK-NEXT: store i8** getelementptr inbounds ([0 x i8*], [0 x i8*]* [[EXTERNAL_CONFORMER_EXTERNAL_P_WITNESS_TABLE]], i32 0, i32 0), i8*** %2, align 8
69+
// CHECK-NEXT: store i8** [[EXTERNAL_CONFORMER_EXTERNAL_P_WITNESS_TABLE]], i8*** %2, align 8
7070
func externalErasure(c c: ExternalConformer) -> ExternalP {
7171
return c
7272
}

0 commit comments

Comments
 (0)