Skip to content

Commit 46d3909

Browse files
committed
SIL: improve VTable and WitnessTable
* add missing APIs * bridge the entries as values and not as pointers * add lookup functions in `Context` * make WitnessTable.Entry.Kind enum cases lower case
1 parent c6f384c commit 46d3909

File tree

11 files changed

+289
-88
lines changed

11 files changed

+289
-88
lines changed

SwiftCompilerSources/Sources/Optimizer/DataStructures/FunctionUses.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,21 +128,21 @@ struct FunctionUses {
128128

129129
for vTable in context.vTables {
130130
for entry in vTable.entries {
131-
markUnknown(entry.function)
131+
markUnknown(entry.implementation)
132132
}
133133
}
134134

135135
for witnessTable in context.witnessTables {
136136
for entry in witnessTable.entries {
137-
if entry.kind == .Method, let f = entry.methodFunction {
137+
if entry.kind == .method, let f = entry.methodFunction {
138138
markUnknown(f)
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 {
145+
if entry.kind == .method, let f = entry.methodFunction {
146146
markUnknown(f)
147147
}
148148
}

SwiftCompilerSources/Sources/Optimizer/ModulePasses/MandatoryPerformanceOptimizations.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ private func specializeVTableAndAddEntriesToWorklist(for type: Type, in function
156156
let vTables = moduleContext.vTables
157157
for i in vTablesCountBefore ..< vTables.count {
158158
for entry in vTables[i].entries {
159-
worklist.pushIfNotVisited(entry.function)
159+
worklist.pushIfNotVisited(entry.implementation)
160160
}
161161
}
162162
}

SwiftCompilerSources/Sources/Optimizer/PassManager/Context.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@ extension Context {
6161
}
6262
}
6363

64+
func lookupWitnessTable(for conformance: ProtocolConformance) -> WitnessTable? {
65+
return _bridged.lookupWitnessTable(conformance.bridged).witnessTable
66+
}
67+
68+
func lookupVTable(for classDecl: NominalTypeDecl) -> VTable? {
69+
return _bridged.lookupVTable(classDecl.bridged).vTable
70+
}
71+
72+
func lookupSpecializedVTable(for classType: Type) -> VTable? {
73+
return _bridged.lookupSpecializedVTable(classType.bridged).vTable
74+
}
75+
6476
func notifyNewFunction(function: Function, derivedFrom: Function) {
6577
_bridged.addFunctionToPassManagerWorklist(function.bridged, derivedFrom.bridged)
6678
}

SwiftCompilerSources/Sources/Optimizer/PassManager/ModulePassContext.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,14 @@ struct ModulePassContext : Context, CustomStringConvertible {
5454
}
5555

5656
struct VTableArray : BridgedRandomAccessCollection {
57-
fileprivate let bridged: BridgedPassContext.VTableArray
57+
fileprivate let bridgedCtxt: BridgedPassContext
5858

5959
var startIndex: Int { return 0 }
60-
var endIndex: Int { return bridged.count }
60+
var endIndex: Int { return bridgedCtxt.getNumVTables() }
6161

6262
subscript(_ index: Int) -> VTable {
6363
assert(index >= startIndex && index < endIndex)
64-
return VTable(bridged: BridgedVTable(vTable: bridged.base![index]))
64+
return VTable(bridged: bridgedCtxt.getVTable(index))
6565
}
6666
}
6767

@@ -101,9 +101,7 @@ struct ModulePassContext : Context, CustomStringConvertible {
101101
GlobalVariableList(first: _bridged.getFirstGlobalInModule().globalVar)
102102
}
103103

104-
var vTables: VTableArray {
105-
VTableArray(bridged: _bridged.getVTables())
106-
}
104+
var vTables: VTableArray { VTableArray(bridgedCtxt: _bridged) }
107105

108106
var witnessTables: WitnessTableList {
109107
WitnessTableList(first: _bridged.getFirstWitnessTableInModule().witnessTable)

SwiftCompilerSources/Sources/SIL/VTable.swift

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,88 @@ public struct VTable : CustomStringConvertible, NoReflectionChildren {
1818
public init(bridged: BridgedVTable) { self.bridged = bridged }
1919

2020
public struct Entry : CustomStringConvertible, NoReflectionChildren {
21-
fileprivate let bridged: BridgedVTableEntry
22-
23-
public var function: Function { bridged.getImplementation().function }
21+
public let bridged: BridgedVTableEntry
22+
23+
public enum Kind {
24+
/// The vtable entry is for a method defined directly in this class.
25+
case normal
26+
/// The vtable entry is inherited from the superclass.
27+
case inherited
28+
/// The vtable entry is inherited from the superclass, and overridden in this class.
29+
case overridden
30+
}
31+
32+
fileprivate init(bridged: BridgedVTableEntry) {
33+
self.bridged = bridged
34+
}
35+
36+
public init(kind: Kind, isNonOverridden: Bool, methodDecl: DeclRef, implementation: Function) {
37+
let bridgedKind: BridgedVTableEntry.Kind
38+
switch kind {
39+
case .normal: bridgedKind = .Normal
40+
case .inherited: bridgedKind = .Inherited
41+
case .overridden: bridgedKind = .Override
42+
}
43+
self.bridged = BridgedVTableEntry.create(bridgedKind, isNonOverridden,
44+
methodDecl.bridged, implementation.bridged)
45+
}
46+
47+
public var kind: Kind {
48+
switch bridged.getKind() {
49+
case .Normal: return .normal
50+
case .Inherited: return .inherited
51+
case .Override: return .overridden
52+
default: fatalError()
53+
}
54+
}
55+
56+
public var isNonOverridden: Bool { bridged.isNonOverridden() }
57+
58+
public var methodDecl: DeclRef { DeclRef(bridged: bridged.getMethodDecl()) }
59+
60+
public var implementation: Function { bridged.getImplementation().function }
2461

2562
public var description: String {
2663
return String(taking: bridged.getDebugDescription())
2764
}
2865
}
2966

3067
public struct EntryArray : BridgedRandomAccessCollection {
31-
fileprivate let base: BridgedVTableEntry
68+
fileprivate let bridgedTable: BridgedVTable
3269
public let count: Int
3370

71+
init(vTable: VTable) {
72+
self.bridgedTable = vTable.bridged
73+
self.count = vTable.bridged.getNumEntries()
74+
}
75+
3476
public var startIndex: Int { return 0 }
3577
public var endIndex: Int { return count }
3678

3779
public subscript(_ index: Int) -> Entry {
3880
assert(index >= startIndex && index < endIndex)
39-
return Entry(bridged: base.advanceBy(index))
81+
return Entry(bridged: bridgedTable.getEntry(index))
4082
}
4183
}
4284

43-
public var entries: EntryArray {
44-
let entries = bridged.getEntries()
45-
return EntryArray(base: entries.base, count: entries.count)
46-
}
85+
public var entries: EntryArray { EntryArray(vTable: self) }
86+
87+
public var `class`: NominalTypeDecl { NominalTypeDecl(_bridged: bridged.getClass()) }
88+
89+
public var specializedClassType: Type? { bridged.getSpecializedClassType().typeOrNil }
90+
91+
public var isSpecialized: Bool { specializedClassType != nil }
4792

4893
public var description: String {
4994
return String(taking: bridged.getDebugDescription())
5095
}
5196
}
97+
98+
extension OptionalBridgedVTable {
99+
public var vTable: VTable? {
100+
if let table {
101+
return VTable(bridged: BridgedVTable(vTable: table))
102+
}
103+
return nil
104+
}
105+
}

SwiftCompilerSources/Sources/SIL/WitnessTable.swift

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,41 +18,58 @@ public struct WitnessTable : CustomStringConvertible, NoReflectionChildren {
1818
public init(bridged: BridgedWitnessTable) { self.bridged = bridged }
1919

2020
public struct Entry : CustomStringConvertible, NoReflectionChildren {
21-
fileprivate let bridged: BridgedWitnessTableEntry
22-
21+
public let bridged: BridgedWitnessTableEntry
22+
2323
public typealias Kind = BridgedWitnessTableEntry.Kind
2424

25+
fileprivate init(bridged: BridgedWitnessTableEntry) {
26+
self.bridged = bridged
27+
}
28+
29+
public init(methodRequirement: DeclRef, methodFunction: Function) {
30+
self.bridged = BridgedWitnessTableEntry.createMethod(methodRequirement.bridged, methodFunction.bridged)
31+
}
32+
2533
public var kind: Kind {
2634
return bridged.getKind()
2735
}
2836

2937
public var methodFunction: Function? {
30-
assert(kind == .Method)
38+
assert(kind == .method)
3139
return bridged.getMethodFunction().function
3240
}
3341

42+
public var methodRequirement: DeclRef {
43+
assert(kind == .method)
44+
return DeclRef(bridged: bridged.getMethodRequirement())
45+
}
46+
3447
public var description: String {
3548
return String(taking: bridged.getDebugDescription())
3649
}
3750
}
3851

3952
public struct EntryArray : BridgedRandomAccessCollection {
40-
fileprivate let base: BridgedWitnessTableEntry
53+
fileprivate let bridgedTable: BridgedWitnessTable
4154
public let count: Int
4255

43-
public var startIndex: Int { return 0 }
44-
public var endIndex: Int { return count }
45-
56+
init(witnessTable: WitnessTable) {
57+
self.bridgedTable = witnessTable.bridged
58+
self.count = witnessTable.bridged.getNumEntries()
59+
}
60+
61+
public var startIndex: Int { 0 }
62+
public var endIndex: Int { count }
63+
4664
public subscript(_ index: Int) -> Entry {
47-
assert(index >= startIndex && index < endIndex)
48-
return Entry(bridged: base.advanceBy(index))
65+
precondition(index >= startIndex && index < endIndex)
66+
return Entry(bridged: bridgedTable.getEntry(index))
4967
}
5068
}
5169

52-
public var entries: EntryArray {
53-
let entries = bridged.getEntries()
54-
return EntryArray(base: entries.base, count: entries.count)
55-
}
70+
public var entries: EntryArray { EntryArray(witnessTable: self) }
71+
72+
public var isDefinition: Bool { !bridged.isDeclaration() }
5673

5774
public var description: String {
5875
return String(taking: bridged.getDebugDescription())
@@ -65,13 +82,27 @@ public struct DefaultWitnessTable : CustomStringConvertible, NoReflectionChildre
6582
public init(bridged: BridgedDefaultWitnessTable) { self.bridged = bridged }
6683

6784
public typealias Entry = WitnessTable.Entry
68-
public typealias EntryArray = WitnessTable.EntryArray
6985

70-
public var entries: EntryArray {
71-
let entries = bridged.getEntries()
72-
return EntryArray(base: entries.base, count: entries.count)
86+
public struct EntryArray : BridgedRandomAccessCollection {
87+
fileprivate let bridgedTable: BridgedDefaultWitnessTable
88+
public let count: Int
89+
90+
init(witnessTable: DefaultWitnessTable) {
91+
self.bridgedTable = witnessTable.bridged
92+
self.count = witnessTable.bridged.getNumEntries()
93+
}
94+
95+
public var startIndex: Int { 0 }
96+
public var endIndex: Int { count }
97+
98+
public subscript(_ index: Int) -> Entry {
99+
precondition(index >= startIndex && index < endIndex)
100+
return Entry(bridged: bridgedTable.getEntry(index))
101+
}
73102
}
74103

104+
public var entries: EntryArray { EntryArray(witnessTable: self) }
105+
75106
public var description: String {
76107
return String(taking: bridged.getDebugDescription())
77108
}

include/swift/SIL/SILBridging.h

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,11 +1097,32 @@ struct BridgedDeclRef {
10971097
};
10981098

10991099
struct BridgedVTableEntry {
1100-
const swift::SILVTableEntry * _Nonnull entry;
1100+
uint64_t storage[5];
1101+
1102+
enum class Kind {
1103+
Normal,
1104+
Inherited,
1105+
Override
1106+
};
1107+
1108+
#ifdef USED_IN_CPP_SOURCE
1109+
BridgedVTableEntry(const swift::SILVTableEntry &entry) {
1110+
*reinterpret_cast<swift::SILVTableEntry *>(&storage) = entry;
1111+
}
1112+
1113+
const swift::SILVTableEntry &unbridged() const {
1114+
return *reinterpret_cast<const swift::SILVTableEntry *>(&storage);
1115+
}
1116+
#endif
11011117

11021118
BridgedOwnedString getDebugDescription() const;
1119+
BRIDGED_INLINE Kind getKind() const;
1120+
BRIDGED_INLINE bool isNonOverridden() const;
1121+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedDeclRef getMethodDecl() const;
11031122
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedFunction getImplementation() const;
1104-
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedVTableEntry advanceBy(SwiftInt index) const;
1123+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
1124+
static BridgedVTableEntry create(Kind kind, bool nonOverridden,
1125+
BridgedDeclRef methodDecl, BridgedFunction implementation);
11051126
};
11061127

11071128
struct BridgedVTableEntryArray {
@@ -1113,42 +1134,52 @@ struct BridgedVTable {
11131134
const swift::SILVTable * _Nonnull vTable;
11141135

11151136
BridgedOwnedString getDebugDescription() const;
1116-
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedVTableEntryArray getEntries() const;
1137+
BRIDGED_INLINE SwiftInt getNumEntries() const;
1138+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedVTableEntry getEntry(SwiftInt index) const;
1139+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedNominalTypeDecl getClass() const;
1140+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedType getSpecializedClassType() const;
1141+
};
1142+
1143+
struct OptionalBridgedVTable {
1144+
const swift::SILVTable * _Nullable table;
11171145
};
11181146

11191147
struct BridgedWitnessTableEntry {
1120-
const void * _Nonnull entry;
1148+
uint64_t storage[5];
11211149

11221150
enum class Kind {
1123-
Invalid,
1124-
Method,
1125-
AssociatedType,
1126-
AssociatedTypeProtocol,
1127-
BaseProtocol
1151+
invalid,
1152+
method,
1153+
associatedType,
1154+
associatedTypeProtocol,
1155+
baseProtocol
11281156
};
11291157

11301158
#ifdef USED_IN_CPP_SOURCE
1131-
const swift::SILWitnessTable::Entry * _Nonnull getEntry() const {
1132-
return (const swift::SILWitnessTable::Entry * _Nonnull)entry;
1159+
BridgedWitnessTableEntry(const swift::SILWitnessTable::Entry &entry) {
1160+
*reinterpret_cast<swift::SILWitnessTable::Entry *>(&storage) = entry;
1161+
}
1162+
1163+
const swift::SILWitnessTable::Entry &unbridged() const {
1164+
return *reinterpret_cast<const swift::SILWitnessTable::Entry *>(&storage);
11331165
}
11341166
#endif
11351167

11361168
BridgedOwnedString getDebugDescription() const;
11371169
BRIDGED_INLINE Kind getKind() const;
1170+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedDeclRef getMethodRequirement() const;
11381171
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE OptionalBridgedFunction getMethodFunction() const;
1139-
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedWitnessTableEntry advanceBy(SwiftInt index) const;
1140-
};
1141-
1142-
struct BridgedWitnessTableEntryArray {
1143-
BridgedWitnessTableEntry base;
1144-
SwiftInt count;
1172+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
1173+
static BridgedWitnessTableEntry createMethod(BridgedDeclRef requirement, BridgedFunction function);
11451174
};
11461175

11471176
struct BridgedWitnessTable {
11481177
const swift::SILWitnessTable * _Nonnull table;
11491178

11501179
BridgedOwnedString getDebugDescription() const;
1151-
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedWitnessTableEntryArray getEntries() const;
1180+
BRIDGED_INLINE SwiftInt getNumEntries() const;
1181+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedWitnessTableEntry getEntry(SwiftInt index) const;
1182+
BRIDGED_INLINE bool isDeclaration() const;
11521183
};
11531184

11541185
struct OptionalBridgedWitnessTable {
@@ -1159,7 +1190,8 @@ struct BridgedDefaultWitnessTable {
11591190
const swift::SILDefaultWitnessTable * _Nonnull table;
11601191

11611192
BridgedOwnedString getDebugDescription() const;
1162-
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedWitnessTableEntryArray getEntries() const;
1193+
BRIDGED_INLINE SwiftInt getNumEntries() const;
1194+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedWitnessTableEntry getEntry(SwiftInt index) const;
11631195
};
11641196

11651197
struct OptionalBridgedDefaultWitnessTable {

0 commit comments

Comments
 (0)