Skip to content

Commit 916e96d

Browse files
authored
Merge pull request #81974 from eeckstein/fix-mpo-6.2
[6.2] MandatoryPerformanceOptimizations: make sure to handle de-serialized vtable methods
2 parents 3604f89 + 890de1a commit 916e96d

File tree

3 files changed

+85
-15
lines changed

3 files changed

+85
-15
lines changed

SwiftCompilerSources/Sources/Optimizer/ModulePasses/MandatoryPerformanceOptimizations.swift

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ private func optimizeFunctionsTopDown(using worklist: inout FunctionWorklist,
6868
// We need handle this case with a function signature optimization.
6969
removeMetatypeArgumentsInCallees(of: f, moduleContext)
7070

71-
worklist.addCallees(of: f)
71+
worklist.addCallees(of: f, moduleContext)
7272
}
7373
}
7474

@@ -521,29 +521,41 @@ fileprivate struct FunctionWorklist {
521521
return
522522
}
523523

524-
mutating func addCallees(of function: Function) {
524+
mutating func addCallees(of function: Function, _ context: ModulePassContext) {
525525
for inst in function.instructions {
526526
switch inst {
527-
case let apply as ApplySite:
528-
if let callee = apply.referencedFunction {
529-
pushIfNotVisited(callee)
527+
case let fri as FunctionRefInst:
528+
pushIfNotVisited(fri.referencedFunction)
529+
case let alloc as AllocRefInst:
530+
if context.options.enableEmbeddedSwift {
531+
addVTableMethods(forClassType: alloc.type, context)
530532
}
531-
case let bi as BuiltinInst:
532-
switch bi.id {
533-
case .Once, .OnceWithContext:
534-
if let fri = bi.operands[1].value as? FunctionRefInst {
535-
pushIfNotVisited(fri.referencedFunction)
533+
case let metatype as MetatypeInst:
534+
if context.options.enableEmbeddedSwift {
535+
let instanceType = metatype.type.loweredInstanceTypeOfMetatype(in: function)
536+
if instanceType.isClass {
537+
addVTableMethods(forClassType: instanceType, context)
536538
}
537-
break;
538-
default:
539-
break
540539
}
540+
541541
default:
542542
break
543543
}
544544
}
545545
}
546546

547+
mutating func addVTableMethods(forClassType classType: Type, _ context: ModulePassContext) {
548+
guard let vtable = classType.isGenericAtAnyLevel ?
549+
context.lookupSpecializedVTable(for: classType) :
550+
context.lookupVTable(for: classType.nominal!)
551+
else {
552+
return
553+
}
554+
for entry in vtable.entries where !entry.implementation.isGeneric {
555+
pushIfNotVisited(entry.implementation)
556+
}
557+
}
558+
547559
mutating func addWitnessMethods(of witnessTable: WitnessTable) {
548560
for entry in witnessTable.entries {
549561
if case .method(_, let witness) = entry,

test/SILOptimizer/mandatory_performance_optimizations.sil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ bb0(%0 : $Int, %1 : @owned $Builtin.NativeObject):
215215
return %8 : $Builtin.NativeObject
216216
}
217217

218-
// CHECK-LABEL: sil [signature_optimized_thunk] [ossa] @metatype_arg :
218+
// CHECK-LABEL: sil [signature_optimized_thunk] [perf_constraint] [ossa] @metatype_arg :
219219
sil [ossa] @metatype_arg : $@convention(thin) (Int, @thick Int.Type, @owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
220220
bb0(%0 : $Int, %1 : $@thick Int.Type, %2 : @owned $Builtin.NativeObject):
221221
fix_lifetime %1 : $@thick Int.Type
@@ -243,7 +243,7 @@ bb2(%13 : @owned $any Error):
243243
throw %13 : $any Error
244244
}
245245

246-
// CHECK-LABEL: sil [signature_optimized_thunk] [ossa] @metatype_arg_throws :
246+
// CHECK-LABEL: sil [signature_optimized_thunk] [perf_constraint] [ossa] @metatype_arg_throws :
247247
sil [ossa] @metatype_arg_throws : $@convention(thin) (Int, @thick Int.Type, @owned Builtin.NativeObject) -> (@owned Builtin.NativeObject, @error any Error) {
248248
bb0(%0 : $Int, %1 : $@thick Int.Type, %2 : @owned $Builtin.NativeObject):
249249
fix_lifetime %1 : $@thick Int.Type
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -enable-experimental-feature Embedded -c -I%t -parse-as-library %t/MyModule.swift -o %t/MyModule.o -emit-module -emit-module-path %t/MyModule.swiftmodule -emit-empty-object-file
5+
// RUN: %target-swift-frontend -enable-experimental-feature Embedded -c -I%t %t/Main.swift -o %t/Main.o
6+
// RUN: %target-clang %t/Main.o %t/MyModule.o -o %t/a.out
7+
// RUN: %target-run %t/a.out | %FileCheck %s
8+
9+
// REQUIRES: executable_test
10+
// REQUIRES: swift_feature_Embedded
11+
12+
//--- MyModule.swift
13+
14+
public class C<T> {
15+
public func foo() {
16+
let x = X<Int>(x: 27)
17+
x.bar()
18+
}
19+
}
20+
21+
class D<T>: C<T> {
22+
override public func foo() {
23+
print("D")
24+
}
25+
}
26+
27+
class X<T: BinaryInteger> {
28+
var x: T
29+
30+
init(x: T) { self.x = x }
31+
32+
func bar() {
33+
print(x)
34+
}
35+
}
36+
37+
class Y<T: BinaryInteger>: X<T> {
38+
override func bar() {
39+
}
40+
}
41+
42+
@inline(never)
43+
public func create<T>(_ t: T.Type) -> C<T> {
44+
return C<T>()
45+
}
46+
47+
//--- Main.swift
48+
49+
import MyModule
50+
51+
@inline(never)
52+
public func testit() {
53+
let c = create(Int.self)
54+
c.foo()
55+
}
56+
57+
// CHECK: 27
58+
testit()

0 commit comments

Comments
 (0)