@@ -38,6 +38,7 @@ namespace {
38
38
39
39
class VTableSpecializer : public SILModuleTransform {
40
40
bool specializeVTables (SILModule &module );
41
+ bool specializeVTablesOfSuperclasses (SILModule &module );
41
42
42
43
// / The entry point to the transformation.
43
44
void run () override {
@@ -85,9 +86,11 @@ static bool specializeVTablesInFunction(SILFunction &func, SILModule &module,
85
86
bool VTableSpecializer::specializeVTables (SILModule &module ) {
86
87
bool changed = false ;
87
88
for (SILFunction &func : module ) {
88
- specializeVTablesInFunction (func, module , this );
89
+ changed |= specializeVTablesInFunction (func, module , this );
89
90
}
90
91
92
+ changed |= specializeVTablesOfSuperclasses (module );
93
+
91
94
for (SILVTable *vtable : module .getVTables ()) {
92
95
if (vtable->getClass ()->isGenericContext ()) continue ;
93
96
@@ -112,6 +115,28 @@ bool VTableSpecializer::specializeVTables(SILModule &module) {
112
115
return changed;
113
116
}
114
117
118
+ bool VTableSpecializer::specializeVTablesOfSuperclasses (SILModule &module ) {
119
+ bool changed = false ;
120
+ // The module's vtable table can grow while we are specializing superclass vtables.
121
+ for (unsigned i = 0 ; i < module .getVTables ().size (); ++i) {
122
+ SILVTable *vtable = module .getVTables ()[i];
123
+ if (vtable->getClass ()->isGenericContext () && !vtable->getClassType ())
124
+ continue ;
125
+
126
+ SILType superClassTy;
127
+ if (SILType classTy = vtable->getClassType ()) {
128
+ superClassTy = classTy.getSuperclass ();
129
+ } else {
130
+ if (Type superTy = vtable->getClass ()->getSuperclass ())
131
+ superClassTy = SILType::getPrimitiveObjectType (superTy->getCanonicalType ());
132
+ }
133
+ if (superClassTy) {
134
+ changed |= (specializeVTableForType (superClassTy, module , this ) != nullptr );
135
+ }
136
+ }
137
+ return changed;
138
+ }
139
+
115
140
SILVTable *swift::specializeVTableForType (SILType classTy, SILModule &module ,
116
141
SILTransform *transform) {
117
142
CanType astType = classTy.getASTType ();
0 commit comments