Skip to content

Commit 22259a6

Browse files
committed
IRGen: Don't emit generic witness table if conformance doesn't need one
The condition for "needs a generic witness table" was wrong; any conformance with associated conformances would get one, even though its only necessary if the associated conformances are dependent. Fixing this also allows simplifying some code.
1 parent b9eb17c commit 22259a6

File tree

2 files changed

+34
-25
lines changed

2 files changed

+34
-25
lines changed

lib/IRGen/GenProto.cpp

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,7 +1284,6 @@ class AccessorConformanceInfo : public ConformanceInfo {
12841284
// offsets, with conditional conformances closest to 0.
12851285
unsigned NextPrivateDataIndex = 0;
12861286
bool ResilientConformance;
1287-
bool RequiresSpecialization = false;
12881287

12891288
const ProtocolInfo Π
12901289

@@ -1306,21 +1305,14 @@ class AccessorConformanceInfo : public ConformanceInfo {
13061305
PI(IGM.getProtocolInfo(SILWT->getConformance()->getProtocol(),
13071306
(ResilientConformance
13081307
? ProtocolInfoKind::RequirementSignature
1309-
: ProtocolInfoKind::Full))) {
1310-
// If the conformance is resilient, we require runtime instantiation.
1311-
if (ResilientConformance)
1312-
RequiresSpecialization = true;
1313-
}
1308+
: ProtocolInfoKind::Full))) {}
13141309

13151310
/// The number of entries in the witness table.
13161311
unsigned getTableSize() const { return TableSize; }
13171312

13181313
/// The number of private entries in the witness table.
13191314
unsigned getTablePrivateSize() const { return NextPrivateDataIndex; }
13201315

1321-
/// Whether this witness table must be specialized at runtime.
1322-
bool requiresSpecialization() const { return RequiresSpecialization; }
1323-
13241316
/// The top-level entry point.
13251317
void build();
13261318

@@ -1370,7 +1362,6 @@ class AccessorConformanceInfo : public ConformanceInfo {
13701362
}
13711363

13721364
// Otherwise, we'll need to derive it at instantiation time.
1373-
RequiresSpecialization = true;
13741365
SpecializedBaseConformances.push_back({Table.size(), &conf});
13751366
Table.addNullPointer(IGM.Int8PtrTy);
13761367
}
@@ -1437,8 +1428,6 @@ class AccessorConformanceInfo : public ConformanceInfo {
14371428
auto associate =
14381429
Conformance.getTypeWitness(requirement.getAssociation(), nullptr)
14391430
->getCanonicalType();
1440-
if (associate->hasTypeParameter())
1441-
RequiresSpecialization = true;
14421431
llvm::Constant *witness =
14431432
IGM.getAssociatedTypeWitness(associate, /*inProtocolContext=*/false);
14441433
Table.addBitCast(witness, IGM.Int8PtrTy);
@@ -1463,9 +1452,6 @@ class AccessorConformanceInfo : public ConformanceInfo {
14631452
requirement.getAssociation(),
14641453
requirement.getAssociatedRequirement());
14651454

1466-
if (requirement.getAssociation()->hasTypeParameter())
1467-
RequiresSpecialization = true;
1468-
14691455
#ifndef NDEBUG
14701456
assert(entry.getKind() == SILWitnessTable::AssociatedTypeProtocol
14711457
&& "sil witness table does not match protocol");
@@ -1516,7 +1502,6 @@ class AccessorConformanceInfo : public ConformanceInfo {
15161502

15171503
/// Allocate another word of private data storage in the conformance table.
15181504
unsigned getNextPrivateDataIndex() {
1519-
RequiresSpecialization = true;
15201505
return NextPrivateDataIndex++;
15211506
}
15221507

@@ -2309,7 +2294,9 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
23092294
// descriptor.
23102295
ConformanceDescription description(conf, wt, global, tableSize,
23112296
wtableBuilder.getTablePrivateSize(),
2312-
wtableBuilder.requiresSpecialization(),
2297+
isDependentConformance(
2298+
conf,
2299+
/*considerResilience=*/true),
23132300
isDependentConformance(
23142301
conf,
23152302
/*considerResilience=*/false));

test/IRGen/protocol_conformance_records.swift

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ public protocol Runcible {
2222
// -- witness table
2323
// CHECK-SAME: @"$s28protocol_conformance_records15NativeValueTypeVAA8RuncibleAAWP"
2424
// -- flags
25-
// CHECK-SAME: i32 0
26-
// CHECK-SAME: },
25+
// CHECK-SAME: i32 0 },
2726
public struct NativeValueType: Runcible {
2827
public func runce() {}
2928
}
@@ -36,8 +35,7 @@ public struct NativeValueType: Runcible {
3635
// -- witness table
3736
// CHECK-SAME: @"$s28protocol_conformance_records15NativeClassTypeCAA8RuncibleAAWP"
3837
// -- flags
39-
// CHECK-SAME: i32 0
40-
// CHECK-SAME: },
38+
// CHECK-SAME: i32 0 },
4139
public class NativeClassType: Runcible {
4240
public func runce() {}
4341
}
@@ -50,8 +48,7 @@ public class NativeClassType: Runcible {
5048
// -- witness table
5149
// CHECK-SAME: @"$s28protocol_conformance_records17NativeGenericTypeVyxGAA8RuncibleAAWP"
5250
// -- flags
53-
// CHECK-SAME: i32 0
54-
// CHECK-SAME: },
51+
// CHECK-SAME: i32 0 },
5552
public struct NativeGenericType<T>: Runcible {
5653
public func runce() {}
5754
}
@@ -87,6 +84,30 @@ extension Size: Runcible {
8784
public func runce() {}
8885
}
8986

87+
// A non-dependent type conforming to a protocol with associated conformances
88+
// does not require a generic witness table.
89+
public protocol Simple {}
90+
91+
public protocol AssociateConformance {
92+
associatedtype X : Simple
93+
}
94+
95+
public struct Other : Simple {}
96+
97+
public struct Concrete : AssociateConformance {
98+
public typealias X = Other
99+
}
100+
101+
// CHECK-LABEL: @"$s28protocol_conformance_records8ConcreteVAA20AssociateConformanceAAMc" ={{ dllexport | protected | }}constant
102+
// -- protocol descriptor
103+
// CHECK-SAME: @"$s28protocol_conformance_records20AssociateConformanceMp"
104+
// -- nominal type descriptor
105+
// CHECK-SAME: @"$s28protocol_conformance_records8ConcreteVMn"
106+
// -- witness table
107+
// CHECK-SAME: @"$s28protocol_conformance_records8ConcreteVAA20AssociateConformanceAAWP"
108+
// -- no flags are set, and no generic witness table follows
109+
// CHECK-SAME: i32 0 }
110+
90111
// CHECK-LABEL: @"\01l_protocols"
91112
// CHECK-SAME: @"$s28protocol_conformance_records8RuncibleMp"
92113
// CHECK-SAME: @"$s28protocol_conformance_records5SpoonMp"
@@ -136,7 +157,7 @@ extension Int : OtherResilientProtocol { }
136157
// -- witness table pattern
137158
// CHECK-SAME: @"$s28protocol_conformance_records9DependentVyxGAA9AssociateAAWp"
138159
// -- flags
139-
// CHECK-SAME: i32 0
160+
// CHECK-SAME: i32 131072,
140161
// -- number of words in witness table
141162
// CHECK-SAME: i16 2,
142163
// -- number of private words in witness table + bit for "needs instantiation"
@@ -151,5 +172,6 @@ extension Dependent : Associate {
151172
// CHECK-SAME: @"$s28protocol_conformance_records15NativeClassTypeCAA8RuncibleAAMc"
152173
// CHECK-SAME: @"$s28protocol_conformance_records17NativeGenericTypeVyxGAA8RuncibleAAMc"
153174
// CHECK-SAME: @"$s16resilient_struct4SizeV28protocol_conformance_records8RuncibleADMc"
175+
// CHECK-SAME: @"$s28protocol_conformance_records8ConcreteVAA20AssociateConformanceAAMc"
154176
// CHECK-SAME: @"$s28protocol_conformance_records17NativeGenericTypeVyxGAA5SpoonA2aERzlMc"
155-
// CHECK-SAME: @"$sSi18resilient_protocol22OtherResilientProtocol0B20_conformance_recordsMc"
177+
// CHECK-SAME: @"$sSi18resilient_protocol22OtherResilientProtocol0B20_conformance_recordsMc"

0 commit comments

Comments
 (0)