From a92e9b3288254628f2492d308a3d6ff0c90b6544 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Thu, 3 Sep 2020 18:50:32 +0000 Subject: [PATCH] SILOptimizer: make vtable pruning less aggressive A class which is marked as internal or public can be visible outside of the current file, where the use of the VWT indirectly is possible. If the VWT is modified and inlined, it is possible that the offsets will no longer match resulting in an invalid dispatch. Limit the pass to when WMO is enabled or the type is private in non-WMO cases. --- lib/SILOptimizer/Transforms/PruneVTables.cpp | 10 ++++++++-- test/SILOptimizer/prune-vtables.sil | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/lib/SILOptimizer/Transforms/PruneVTables.cpp b/lib/SILOptimizer/Transforms/PruneVTables.cpp index 18543900f921e..f1c37c892c8c9 100644 --- a/lib/SILOptimizer/Transforms/PruneVTables.cpp +++ b/lib/SILOptimizer/Transforms/PruneVTables.cpp @@ -27,10 +27,16 @@ using namespace swift; namespace { class PruneVTables : public SILModuleTransform { - void runOnVTable(SILModule *M, - SILVTable *vtable) { + void runOnVTable(SILModule *M, SILVTable *vtable) { LLVM_DEBUG(llvm::dbgs() << "PruneVTables inspecting table:\n"; vtable->print(llvm::dbgs())); + if (!M->isWholeModule() && + vtable->getClass()->getEffectiveAccess() >= AccessLevel::FilePrivate) { + LLVM_DEBUG(llvm::dbgs() << "Ignoring visible table: "; + vtable->print(llvm::dbgs())); + return; + } + for (auto &entry : vtable->getMutableEntries()) { // We don't need to worry about entries that are overridden, diff --git a/test/SILOptimizer/prune-vtables.sil b/test/SILOptimizer/prune-vtables.sil index d72af0b338b10..633dc9e53bf5a 100644 --- a/test/SILOptimizer/prune-vtables.sil +++ b/test/SILOptimizer/prune-vtables.sil @@ -14,9 +14,9 @@ sil @PrivateA_yesOverrides : $@convention(method) (@guaranteed PrivateA) -> () sil @PrivateA_isFinal : $@convention(method) (@guaranteed PrivateA) -> () // NOWMO-LABEL: sil_vtable PrivateA { -// NOWMO: #PrivateA.noOverrides{{.*}} [nonoverridden] +// NOWMO: #PrivateA.noOverrides{{[^[]]*}} // NOWMO-NOT: #PrivateA.yesOverrides{{.*}} [nonoverridden] -// NOWMO: #PrivateA.isFinal{{.*}} [nonoverridden] +// NOWMO: #PrivateA.isFinal{{[^[]]*}} // WMO-LABEL: sil_vtable PrivateA { // WMO: #PrivateA.noOverrides{{.*}} [nonoverridden] @@ -35,9 +35,9 @@ private class PrivateB: PrivateA { sil @PrivateB_yesOverrides : $@convention(method) (@guaranteed PrivateB) -> () // NOWMO-LABEL: sil_vtable PrivateB { -// NOWMO: #PrivateA.noOverrides{{.*}} [nonoverridden] +// NOWMO: #PrivateA.noOverrides{{[^[]]*}} // NOWMO-NOT: #PrivateA.yesOverrides{{.*}} [nonoverridden] -// NOWMO: #PrivateA.isFinal{{.*}} [nonoverridden] +// NOWMO: #PrivateA.isFinal{{[^[]]*}} // WMO-LABEL: sil_vtable PrivateB { // WMO: #PrivateA.noOverrides{{.*}} [nonoverridden] @@ -62,7 +62,7 @@ sil @InternalA_isFinal : $@convention(method) (@guaranteed InternalA) -> () // NOWMO-LABEL: sil_vtable InternalA { // NOWMO-NOT: #InternalA.noOverrides{{.*}} [nonoverridden] // NOWMO-NOT: #InternalA.yesOverrides{{.*}} [nonoverridden] -// NOWMO: #InternalA.isFinal{{.*}} [nonoverridden] +// NOWMO: #InternalA.isFinal{{[^[]]*}} // WMO-LABEL: sil_vtable InternalA { // WMO: #InternalA.noOverrides{{.*}} [nonoverridden] @@ -83,7 +83,7 @@ sil @InternalB_yesOverrides : $@convention(method) (@guaranteed InternalB) -> () // NOWMO-LABEL: sil_vtable InternalB { // NOWMO-NOT: #InternalA.noOverrides{{.*}} [nonoverridden] // NOWMO-NOT: #InternalA.yesOverrides{{.*}} [nonoverridden] -// NOWMO: #InternalA.isFinal{{.*}} [nonoverridden] +// NOWMO: #InternalA.isFinal{{[^[]]*}} // WMO-LABEL: sil_vtable InternalB { // WMO: #InternalA.noOverrides{{.*}} [nonoverridden] @@ -108,7 +108,7 @@ sil @PublicA_isFinal : $@convention(method) (@guaranteed PublicA) -> () // NOWMO-LABEL: sil_vtable PublicA { // NOWMO-NOT: #PublicA.noOverrides{{.*}} [nonoverridden] // NOWMO-NOT: #PublicA.yesOverrides{{.*}} [nonoverridden] -// NOWMO: #PublicA.isFinal{{.*}} [nonoverridden] +// NOWMO: #PublicA.isFinal{{[^[]]*}} // WMO-LABEL: sil_vtable PublicA { // WMO: #PublicA.noOverrides{{.*}} [nonoverridden] @@ -129,7 +129,7 @@ sil @PublicB_yesOverrides : $@convention(method) (@guaranteed PublicB) -> () // NOWMO-LABEL: sil_vtable PublicB { // NOWMO-NOT: #PublicA.noOverrides{{.*}} [nonoverridden] // NOWMO-NOT: #PublicA.yesOverrides{{.*}} [nonoverridden] -// NOWMO: #PublicA.isFinal{{.*}} [nonoverridden] +// NOWMO: #PublicA.isFinal{{[^[]]*}} // WMO-LABEL: sil_vtable PublicB { // WMO: #PublicA.noOverrides{{.*}} [nonoverridden] @@ -154,7 +154,7 @@ sil @OpenA_isFinal : $@convention(method) (@guaranteed OpenA) -> () // NOWMO-LABEL: sil_vtable OpenA { // NOWMO-NOT: #OpenA.noOverrides{{.*}} [nonoverridden] // NOWMO-NOT: #OpenA.yesOverrides{{.*}} [nonoverridden] -// NOWMO: #OpenA.isFinal{{.*}} [nonoverridden] +// NOWMO: #OpenA.isFinal{{[^[]]*}} // WMO-LABEL: sil_vtable OpenA { // WMO-NOT: #OpenA.noOverrides{{.*}} [nonoverridden] @@ -175,7 +175,7 @@ sil @OpenB_yesOverrides : $@convention(method) (@guaranteed OpenB) -> () // NOWMO-LABEL: sil_vtable OpenB { // NOWMO-NOT: #OpenA.noOverrides{{.*}} [nonoverridden] // NOWMO-NOT: #OpenA.yesOverrides{{.*}} [nonoverridden] -// NOWMO: #OpenA.isFinal{{.*}} [nonoverridden] +// NOWMO: #OpenA.isFinal{{[^[]]*}} // WMO-LABEL: sil_vtable OpenB { // WMO-NOT: #OpenA.noOverrides{{.*}} [nonoverridden]