Skip to content

Commit f4a0397

Browse files
authored
Merge pull request #68883 from kubamracek/embedded-release-devirt
[embedded] Re-enable ReleaseDevirtualizer and teach it to look for specialized destructors
2 parents 3f35f54 + 28a3d58 commit f4a0397

File tree

4 files changed

+22
-10
lines changed

4 files changed

+22
-10
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ReleaseDevirtualizer.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,14 @@ private func tryDevirtualizeRelease(
107107
// argument.
108108
let functionRef = builder.createFunctionRef(dealloc)
109109

110-
let substitutionMap = context.getContextSubstitutionMap(for: type)
110+
let substitutionMap: SubstitutionMap
111+
if dealloc.isGenericFunction {
112+
substitutionMap = context.getContextSubstitutionMap(for: type)
113+
} else {
114+
// In embedded Swift, dealloc might be a specialized deinit, so the substitution map on the old apply isn't valid for the new apply
115+
substitutionMap = SubstitutionMap()
116+
}
117+
111118
builder.createApply(function: functionRef, substitutionMap, arguments: [beginDealloc])
112119
context.erase(instruction: lastRelease)
113120
}

lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,15 @@ CalleeList CalleeCache::getDestructors(SILType type, bool isExactType) const {
306306
if (isExactType || classDecl->isFinal()) {
307307
// In case of a final class, just pick the deinit of the class.
308308
SILDeclRef destructor = SILDeclRef(classDecl->getDestructor());
309+
310+
// In embedded Swift, we need the specialized destructor, not the generic
311+
// one.
312+
if (auto *vtable = M.lookUpSpecializedVTable(type)) {
313+
if (auto entry = vtable->getEntry(M, destructor))
314+
return CalleeList(entry->getImplementation());
315+
return CalleeList();
316+
}
317+
309318
if (SILFunction *destrImpl = M.lookUpFunction(destructor))
310319
return CalleeList(destrImpl);
311320
return CalleeList();

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -760,14 +760,8 @@ static void addMidLevelFunctionPipeline(SILPassPipelinePlan &P) {
760760
static void addLowLevelPassPipeline(SILPassPipelinePlan &P) {
761761
P.startPipeline("LowLevel,Function", true /*isFunctionPassPipeline*/);
762762

763-
// MandatoryPerformanceOptimizations already took care of all specializations
764-
// in embedded Swift mode, running the release devirtualizer might introduce
765-
// more generic calls from non-generic functions, which breaks the assumptions
766-
// of embedded Swift.
767-
if (!P.getOptions().EmbeddedSwift) {
768-
// Should be after FunctionSignatureOpts and before the last inliner.
769-
P.addReleaseDevirtualizer();
770-
}
763+
// Should be after FunctionSignatureOpts and before the last inliner.
764+
P.addReleaseDevirtualizer();
771765

772766
addFunctionPasses(P, OptimizationLevelKind::LowLevel);
773767

test/embedded/classes-stack-promotion.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ struct Main {
8686
// CHECK-IR-NEXT: call {{.*}}@"$s4main5print_10terminatorys12StaticStringV_AEtF"
8787
// CHECK-IR-NEXT: call {{.*}}@"$s4main5print_10terminatorys12StaticStringV_AEtF"
8888
// CHECK-IR-NEXT: call {{.*}}@"$s4main3bar1oyAA7MyClassC_tF"
89-
// CHECK-IR-NEXT: call {{.*}}@swift_release
89+
// CHECK-IR-NEXT: call {{.*}}@swift_setDeallocating
90+
// CHECK-IR-NEXT: call {{.*}}@"$s4main5print_10terminatorys12StaticStringV_AEtF"
91+
// CHECK-IR-NEXT: call {{.*}}@"$s4main5print_10terminatorys12StaticStringV_AEtF"
9092
// CHECK-IR-NEXT: call {{.*}}@llvm.lifetime.end.p0
9193
// CHECK-IR-NEXT: call {{.*}}@"$s4main5print_10terminatorys12StaticStringV_AEtF"
9294
// CHECK-IR-NEXT: call {{.*}}@swift_initStackObject

0 commit comments

Comments
 (0)