Skip to content

Commit 6fdb713

Browse files
committed
SwiftCompilerSources: implement WitnessTable.Entry as enum
1 parent 5502373 commit 6fdb713

File tree

7 files changed

+161
-44
lines changed

7 files changed

+161
-44
lines changed

SwiftCompilerSources/Sources/Optimizer/DataStructures/FunctionUses.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,16 +134,16 @@ struct FunctionUses {
134134

135135
for witnessTable in context.witnessTables {
136136
for entry in witnessTable.entries {
137-
if entry.kind == .method, let f = entry.methodFunction {
138-
markUnknown(f)
137+
if case .method(_, let witness) = entry, let witness {
138+
markUnknown(witness)
139139
}
140140
}
141141
}
142142

143143
for witnessTable in context.defaultWitnessTables {
144144
for entry in witnessTable.entries {
145-
if entry.kind == .method, let f = entry.methodFunction {
146-
markUnknown(f)
145+
if case .method(_, let witness) = entry, let witness {
146+
markUnknown(witness)
147147
}
148148
}
149149
}

SwiftCompilerSources/Sources/Optimizer/ModulePasses/MandatoryPerformanceOptimizations.swift

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -284,12 +284,12 @@ private func checkForGenericMethods(in witnessTable: WitnessTable,
284284
errorLocation: Location,
285285
_ context: ModulePassContext)
286286
{
287-
for entry in witnessTable.entries where entry.kind == .method {
288-
if let method = entry.methodFunction,
289-
method.isGeneric
287+
for entry in witnessTable.entries {
288+
if case .method(let requirement, let witness) = entry,
289+
let witness,
290+
witness.isGeneric
290291
{
291-
context.diagnosticEngine.diagnose(errorLocation.sourceLoc, .cannot_specialize_witness_method,
292-
entry.methodRequirement)
292+
context.diagnosticEngine.diagnose(errorLocation.sourceLoc, .cannot_specialize_witness_method, requirement)
293293
return
294294
}
295295
}
@@ -509,8 +509,9 @@ fileprivate struct FunctionWorklist {
509509
}
510510

511511
mutating func addWitnessMethods(of witnessTable: WitnessTable) {
512-
for entry in witnessTable.entries where entry.kind == .method {
513-
if let method = entry.methodFunction,
512+
for entry in witnessTable.entries {
513+
if case .method(_, let witness) = entry,
514+
let method = witness,
514515
// A new witness table can still contain a generic function if the method couldn't be specialized for
515516
// some reason and an error has been printed. Exclude generic functions to not run into an assert later.
516517
!method.isGeneric

SwiftCompilerSources/Sources/Optimizer/Utilities/GenericSpecialization.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,21 +87,20 @@ func specializeWitnessTable(forConformance conformance: Conformance,
8787
assert(witnessTable.isDefinition, "No witness table available")
8888

8989
let newEntries = witnessTable.entries.map { origEntry in
90-
switch origEntry.kind {
91-
case .method:
92-
guard let origMethod = origEntry.methodFunction else {
90+
switch origEntry {
91+
case .method(let requirement, let witness):
92+
guard let origMethod = witness else {
9393
return origEntry
9494
}
95-
let methodDecl = origEntry.methodRequirement
9695
let methodSubs = conformance.specializedSubstitutions.getMethodSubstitutions(for: origMethod)
9796

9897
guard !methodSubs.conformances.contains(where: {!$0.isValid}),
9998
let specializedMethod = context.specialize(function: origMethod, for: methodSubs) else
10099
{
101-
context.diagnosticEngine.diagnose(errorLocation.sourceLoc, .cannot_specialize_witness_method, methodDecl)
100+
context.diagnosticEngine.diagnose(errorLocation.sourceLoc, .cannot_specialize_witness_method, requirement)
102101
return origEntry
103102
}
104-
return WitnessTable.Entry(methodRequirement: methodDecl, methodFunction: specializedMethod)
103+
return .method(requirement: requirement, witness: specializedMethod)
105104
default:
106105
// TODO: handle other witness table entry kinds
107106
fatalError("unsupported witness table etnry")

SwiftCompilerSources/Sources/SIL/WitnessTable.swift

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,67 @@ public struct WitnessTable : CustomStringConvertible, NoReflectionChildren {
1818

1919
public init(bridged: BridgedWitnessTable) { self.bridged = bridged }
2020

21-
public struct Entry : CustomStringConvertible, NoReflectionChildren {
22-
public let bridged: BridgedWitnessTableEntry
21+
public enum Entry : CustomStringConvertible, NoReflectionChildren {
2322

24-
public typealias Kind = BridgedWitnessTableEntry.Kind
23+
case invalid
2524

26-
fileprivate init(bridged: BridgedWitnessTableEntry) {
27-
self.bridged = bridged
28-
}
25+
/// A witness table entry describing the witness for a method.
26+
/// The witness can be nil in case dead function elimination has removed the method
27+
/// or if the method was not serialized (for de-serialized witness tables).
28+
case method(requirement: DeclRef, witness: Function?)
2929

30-
public init(methodRequirement: DeclRef, methodFunction: Function) {
31-
self.bridged = BridgedWitnessTableEntry.createMethod(methodRequirement.bridged, methodFunction.bridged)
32-
}
30+
/// A witness table entry describing the witness for an associated type.
31+
case associatedType(requirement: AssociatedTypeDecl, witness: CanonicalType)
3332

34-
public var kind: Kind {
35-
return bridged.getKind()
36-
}
37-
38-
public var methodFunction: Function? {
39-
assert(kind == .method)
40-
return bridged.getMethodFunction().function
41-
}
33+
/// A witness table entry describing the witness for an associated type's protocol requirement.
34+
case associatedConformance(requirement: CanonicalType, protocol: ProtocolDecl, witness: Conformance)
35+
36+
/// A witness table entry referencing the protocol conformance for a refined base protocol.
37+
case baseProtocol(requirement: ProtocolDecl, witness: Conformance)
4238

43-
public var methodRequirement: DeclRef {
44-
assert(kind == .method)
45-
return DeclRef(bridged: bridged.getMethodRequirement())
39+
fileprivate init(bridged: BridgedWitnessTableEntry) {
40+
switch bridged.getKind() {
41+
case .invalid:
42+
self = .invalid
43+
case .method:
44+
self = .method(requirement: DeclRef(bridged: bridged.getMethodRequirement()),
45+
witness: bridged.getMethodWitness().function)
46+
case .associatedType:
47+
self = .associatedType(requirement: bridged.getAssociatedTypeRequirement().getAs(AssociatedTypeDecl.self),
48+
witness: CanonicalType(bridged: bridged.getAssociatedTypeWitness()))
49+
case .associatedConformance:
50+
self = .associatedConformance(requirement: CanonicalType(bridged: bridged.getAssociatedConformanceRequirement()),
51+
protocol: bridged.getAssociatedConformanceDecl().getAs(ProtocolDecl.self),
52+
witness: Conformance(bridged: bridged.getAssociatedConformanceWitness()))
53+
case .baseProtocol:
54+
self = .baseProtocol(requirement: bridged.getBaseProtocolRequirement().getAs(ProtocolDecl.self),
55+
witness: Conformance(bridged: bridged.getBaseProtocolWitness()))
56+
default:
57+
fatalError("invalid witness table entry")
58+
}
4659
}
4760

4861
public var description: String {
4962
return String(taking: bridged.getDebugDescription())
5063
}
64+
65+
public var bridged: BridgedWitnessTableEntry {
66+
switch self {
67+
case .invalid:
68+
return BridgedWitnessTableEntry.createInvalid()
69+
case .method(let requirement, let witness):
70+
return BridgedWitnessTableEntry.createMethod(requirement.bridged,
71+
OptionalBridgedFunction(obj: witness?.bridged.obj))
72+
case .associatedType(let requirement, let witness):
73+
return BridgedWitnessTableEntry.createAssociatedType(requirement.bridged, witness.bridged)
74+
case .associatedConformance(let requirement, let protocolDecl, let witness):
75+
return BridgedWitnessTableEntry.createAssociatedConformance(requirement.bridged,
76+
protocolDecl.bridged,
77+
witness.bridged)
78+
case .baseProtocol(let requirement, let witness):
79+
return BridgedWitnessTableEntry.createBaseProtocol(requirement.bridged, witness.bridged)
80+
}
81+
}
5182
}
5283

5384
public struct EntryArray : BridgedRandomAccessCollection {

docs/SIL.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1738,7 +1738,7 @@ the underlying normal conformance.
17381738
sil-witness-entry ::= 'base_protocol' identifier ':' protocol-conformance
17391739
sil-witness-entry ::= 'method' sil-decl-ref ':' sil-function-name
17401740
sil-witness-entry ::= 'associated_type' identifier
1741-
sil-witness-entry ::= 'associated_type_protocol'
1741+
sil-witness-entry ::= 'associated_conformance'
17421742
'(' identifier ':' identifier ')' ':' protocol-conformance
17431743

17441744
Witness tables consist of the following entries:

include/swift/SIL/SILBridging.h

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ struct BridgedType {
254254
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE EnumElementIterator getNext() const;
255255
};
256256

257+
BRIDGED_INLINE BridgedType(); // for Optional<Type>.nil
257258
BRIDGED_INLINE BridgedType(swift::SILType t);
258259
BRIDGED_INLINE swift::SILType unbridged() const;
259260
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedCanType getCanType() const;
@@ -591,6 +592,8 @@ struct BridgedFunction {
591592

592593
struct OptionalBridgedFunction {
593594
OptionalSwiftObject obj;
595+
596+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE swift::SILFunction * _Nullable getFunction() const;
594597
};
595598

596599
struct BridgedGlobalVar {
@@ -1097,9 +1100,30 @@ struct BridgedWitnessTableEntry {
10971100
BridgedOwnedString getDebugDescription() const;
10981101
BRIDGED_INLINE Kind getKind() const;
10991102
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedDeclRef getMethodRequirement() const;
1100-
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE OptionalBridgedFunction getMethodFunction() const;
1103+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE OptionalBridgedFunction getMethodWitness() const;
1104+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedDeclObj getAssociatedTypeRequirement() const;
1105+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedCanType getAssociatedTypeWitness() const;
1106+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedCanType getAssociatedConformanceRequirement() const;
1107+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedDeclObj getAssociatedConformanceDecl() const;
1108+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedConformance getAssociatedConformanceWitness() const;
1109+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedDeclObj getBaseProtocolRequirement() const;
1110+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedConformance getBaseProtocolWitness() const;
1111+
1112+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
1113+
static BridgedWitnessTableEntry createInvalid();
1114+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
1115+
static BridgedWitnessTableEntry createMethod(BridgedDeclRef requirement,
1116+
OptionalBridgedFunction witness);
1117+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
1118+
static BridgedWitnessTableEntry createAssociatedType(BridgedDeclObj requirement,
1119+
BridgedCanType witness);
1120+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
1121+
static BridgedWitnessTableEntry createAssociatedConformance(BridgedCanType requirement,
1122+
BridgedDeclObj protocolDecl,
1123+
BridgedConformance witness);
11011124
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
1102-
static BridgedWitnessTableEntry createMethod(BridgedDeclRef requirement, BridgedFunction function);
1125+
static BridgedWitnessTableEntry createBaseProtocol(BridgedDeclObj requirement,
1126+
BridgedConformance witness);
11031127
};
11041128

11051129
struct BridgedWitnessTable {

include/swift/SIL/SILBridgingImpl.h

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ SILFunctionType_getLifetimeDependencies(BridgedCanType funcTy) {
259259
// BridgedType
260260
//===----------------------------------------------------------------------===//
261261

262+
BridgedType::BridgedType() : opaqueValue(nullptr) {}
263+
262264
BridgedType::BridgedType(swift::SILType t) : opaqueValue(t.getOpaqueValue()) {}
263265

264266
swift::SILType BridgedType::unbridged() const {
@@ -884,6 +886,10 @@ BridgedType BridgedFunction::getLoweredType(BridgedType type) const {
884886
return BridgedType(getFunction()->getLoweredType(type.unbridged()));
885887
}
886888

889+
swift::SILFunction * _Nullable OptionalBridgedFunction::getFunction() const {
890+
return static_cast<swift::SILFunction *>(obj);
891+
}
892+
887893
//===----------------------------------------------------------------------===//
888894
// BridgedGlobalVar
889895
//===----------------------------------------------------------------------===//
@@ -1717,14 +1723,70 @@ BridgedDeclRef BridgedWitnessTableEntry::getMethodRequirement() const {
17171723
return unbridged().getMethodWitness().Requirement;
17181724
}
17191725

1720-
OptionalBridgedFunction BridgedWitnessTableEntry::getMethodFunction() const {
1726+
OptionalBridgedFunction BridgedWitnessTableEntry::getMethodWitness() const {
17211727
return {unbridged().getMethodWitness().Witness};
17221728
}
17231729

1730+
BridgedDeclObj BridgedWitnessTableEntry::getAssociatedTypeRequirement() const {
1731+
return {unbridged().getAssociatedTypeWitness().Requirement};
1732+
}
1733+
1734+
BridgedCanType BridgedWitnessTableEntry::getAssociatedTypeWitness() const {
1735+
return unbridged().getAssociatedTypeWitness().Witness;
1736+
}
1737+
1738+
BridgedCanType BridgedWitnessTableEntry::getAssociatedConformanceRequirement() const {
1739+
return unbridged().getAssociatedConformanceWitness().Requirement;
1740+
}
1741+
1742+
BridgedDeclObj BridgedWitnessTableEntry::getAssociatedConformanceDecl() const {
1743+
return {unbridged().getAssociatedConformanceWitness().Protocol};
1744+
}
1745+
1746+
BridgedConformance BridgedWitnessTableEntry::getAssociatedConformanceWitness() const {
1747+
return {unbridged().getAssociatedConformanceWitness().Witness};
1748+
}
1749+
1750+
BridgedDeclObj BridgedWitnessTableEntry::getBaseProtocolRequirement() const {
1751+
return {unbridged().getBaseProtocolWitness().Requirement};
1752+
}
1753+
1754+
BridgedConformance BridgedWitnessTableEntry::getBaseProtocolWitness() const {
1755+
return swift::ProtocolConformanceRef(unbridged().getBaseProtocolWitness().Witness);
1756+
}
1757+
1758+
1759+
BridgedWitnessTableEntry BridgedWitnessTableEntry::createInvalid() {
1760+
return swift::SILWitnessTable::Entry();
1761+
}
1762+
17241763
BridgedWitnessTableEntry BridgedWitnessTableEntry::createMethod(BridgedDeclRef requirement,
1725-
BridgedFunction function) {
1726-
return swift::SILWitnessTable::Entry(swift::SILWitnessTable::MethodWitness{requirement.unbridged(),
1727-
function.getFunction()});
1764+
OptionalBridgedFunction witness) {
1765+
return swift::SILWitnessTable::Entry(
1766+
swift::SILWitnessTable::MethodWitness{requirement.unbridged(), witness.getFunction()});
1767+
}
1768+
1769+
BridgedWitnessTableEntry BridgedWitnessTableEntry::createAssociatedType(BridgedDeclObj requirement,
1770+
BridgedCanType witness) {
1771+
return swift::SILWitnessTable::Entry(
1772+
swift::SILWitnessTable::AssociatedTypeWitness{requirement.getAs<swift::AssociatedTypeDecl>(),
1773+
witness.unbridged()});
1774+
}
1775+
1776+
BridgedWitnessTableEntry BridgedWitnessTableEntry::createAssociatedConformance(BridgedCanType requirement,
1777+
BridgedDeclObj protocolDecl,
1778+
BridgedConformance witness) {
1779+
return swift::SILWitnessTable::Entry(
1780+
swift::SILWitnessTable::AssociatedConformanceWitness{requirement.unbridged(),
1781+
protocolDecl.getAs<swift::ProtocolDecl>(),
1782+
witness.unbridged()});
1783+
}
1784+
1785+
BridgedWitnessTableEntry BridgedWitnessTableEntry::createBaseProtocol(BridgedDeclObj requirement,
1786+
BridgedConformance witness) {
1787+
return swift::SILWitnessTable::Entry(
1788+
swift::SILWitnessTable::BaseProtocolWitness{requirement.getAs<swift::ProtocolDecl>(),
1789+
witness.unbridged().getConcrete()});
17281790
}
17291791

17301792
SwiftInt BridgedWitnessTable::getNumEntries() const {

0 commit comments

Comments
 (0)