@@ -33,13 +33,23 @@ let mandatoryPerformanceOptimizations = ModulePass(name: "mandatory-performance-
33
33
// For embedded Swift, optimize all the functions (there cannot be any
34
34
// generics, type metadata, etc.)
35
35
if moduleContext. options. enableEmbeddedSwift {
36
+ // We need to specialize all vtables which are referenced from non-generic contexts. Beside
37
+ // `alloc_ref`s of generic classes in non-generic functions, we also need to specialize generic
38
+ // superclasses of non-generic classes. E.g. `class Derived : Base<Int> {}`
39
+ specializeVTablesOfSuperclasses ( moduleContext)
40
+
36
41
worklist. addAllNonGenericFunctions ( of: moduleContext)
37
42
} else {
38
43
worklist. addAllPerformanceAnnotatedFunctions ( of: moduleContext)
39
44
worklist. addAllAnnotatedGlobalInitOnceFunctions ( of: moduleContext)
40
45
}
41
46
42
47
optimizeFunctionsTopDown ( using: & worklist, moduleContext)
48
+
49
+ if moduleContext. options. enableEmbeddedSwift {
50
+ // Print errors for generic functions in vtables, which is not allowed in embedded Swift.
51
+ checkVTablesForGenericFunctions ( moduleContext)
52
+ }
43
53
}
44
54
45
55
private func optimizeFunctionsTopDown( using worklist: inout FunctionWorklist ,
@@ -92,11 +102,15 @@ private func optimize(function: Function, _ context: FunctionPassContext, _ modu
92
102
// Embedded Swift specific transformations
93
103
case let alloc as AllocRefInst :
94
104
if context. options. enableEmbeddedSwift {
95
- specializeVTableAndAddEntriesToWorklist ( for: alloc. type, in: function, context, moduleContext, & worklist)
105
+ specializeVTableAndAddEntriesToWorklist ( for: alloc. type, in: function,
106
+ errorLocation: alloc. location,
107
+ moduleContext, & worklist)
96
108
}
97
109
case let metatype as MetatypeInst :
98
110
if context. options. enableEmbeddedSwift {
99
- specializeVTableAndAddEntriesToWorklist ( for: metatype. type, in: function, context, moduleContext, & worklist)
111
+ specializeVTableAndAddEntriesToWorklist ( for: metatype. type, in: function,
112
+ errorLocation: metatype. location,
113
+ moduleContext, & worklist)
100
114
}
101
115
case let classMethod as ClassMethodInst :
102
116
if context. options. enableEmbeddedSwift {
@@ -144,18 +158,23 @@ private func optimize(function: Function, _ context: FunctionPassContext, _ modu
144
158
}
145
159
146
160
private func specializeVTableAndAddEntriesToWorklist( for type: Type , in function: Function ,
147
- _ context: FunctionPassContext , _ moduleContext: ModulePassContext ,
161
+ errorLocation: Location ,
162
+ _ moduleContext: ModulePassContext ,
148
163
_ worklist: inout FunctionWorklist ) {
149
164
let vTablesCountBefore = moduleContext. vTables. count
150
165
151
- guard context . specializeVTable ( for : type, in : function ) != nil else {
166
+ guard specializeVTable ( forClassType : type, errorLocation : errorLocation , moduleContext ) != nil else {
152
167
return
153
168
}
154
169
155
170
// More than one new vtable might have been created (superclasses), process them all
156
171
let vTables = moduleContext. vTables
157
172
for i in vTablesCountBefore ..< vTables. count {
158
- for entry in vTables [ i] . entries {
173
+ for entry in vTables [ i] . entries
174
+ // A new vtable can still contain a generic function if the method couldn't be specialized for some reason
175
+ // and an error has been printed. Exclude generic functions to not run into an assert later.
176
+ where !entry. implementation. isGeneric
177
+ {
159
178
worklist. pushIfNotVisited ( entry. implementation)
160
179
}
161
180
}
@@ -240,6 +259,14 @@ private func shouldInline(apply: FullApplySite, callee: Function, alreadyInlined
240
259
return false
241
260
}
242
261
262
+ private func checkVTablesForGenericFunctions( _ context: ModulePassContext ) {
263
+ for vTable in context. vTables where !vTable. class. isGenericAtAnyLevel {
264
+ for entry in vTable. entries where entry. implementation. isGeneric {
265
+ context. diagnosticEngine. diagnose ( entry. methodDecl. location. sourceLoc, . non_final_generic_class_function)
266
+ }
267
+ }
268
+ }
269
+
243
270
private extension FullApplySite {
244
271
func resultIsUsedInGlobalInitialization( ) -> SmallProjectionPath ? {
245
272
guard parentFunction. isGlobalInitOnceFunction,
0 commit comments