@@ -38,6 +38,7 @@ namespace {
3838
3939class VTableSpecializer : public SILModuleTransform {
4040 bool specializeVTables (SILModule &module );
41+ bool specializeVTablesOfSuperclasses (SILModule &module );
4142
4243 // / The entry point to the transformation.
4344 void run () override {
@@ -85,9 +86,11 @@ static bool specializeVTablesInFunction(SILFunction &func, SILModule &module,
8586bool VTableSpecializer::specializeVTables (SILModule &module ) {
8687 bool changed = false ;
8788 for (SILFunction &func : module ) {
88- specializeVTablesInFunction (func, module , this );
89+ changed |= specializeVTablesInFunction (func, module , this );
8990 }
9091
92+ changed |= specializeVTablesOfSuperclasses (module );
93+
9194 for (SILVTable *vtable : module .getVTables ()) {
9295 if (vtable->getClass ()->isGenericContext ()) continue ;
9396
@@ -112,6 +115,28 @@ bool VTableSpecializer::specializeVTables(SILModule &module) {
112115 return changed;
113116}
114117
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+
115140SILVTable *swift::specializeVTableForType (SILType classTy, SILModule &module ,
116141 SILTransform *transform) {
117142 CanType astType = classTy.getASTType ();
0 commit comments