Skip to content

Commit 65e9122

Browse files
committed
Further restrict MetatypeInst constant folding to only apply to types defined in the current module
1 parent b241932 commit 65e9122

File tree

3 files changed

+40
-20
lines changed

3 files changed

+40
-20
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/OptUtils.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,12 +464,17 @@ extension Instruction {
464464
return context.canMakeStaticObjectReadOnly(objectType: gvi.type)
465465

466466
// Metatypes (and upcasts of them to existentials) can be used as static initializers for SE-0492, as long as they
467-
// are not generic or resilient
467+
// are:
468+
// (1) not a generic type
469+
// (2) not a resilient type
470+
// (3) not a resilient conformance
471+
// (4) a type defined in the currently compiled module
468472
case let mti as MetatypeInst:
469473
if !mti.type.isGenericAtAnyLevel,
470474
let nominal = mti.type.canonicalType.instanceTypeOfMetatype.nominal,
471475
!nominal.isGenericAtAnyLevel,
472-
!nominal.isResilient(in: mti.parentFunction) {
476+
!nominal.isResilient(in: mti.parentFunction),
477+
nominal.parentModule == context.currentModuleContext {
473478
return true
474479
}
475480
return false

test/SILOptimizer/static_init_metatypes.swift

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,38 +16,31 @@ public struct S: Hashable, Sendable, MyProtocol, MyProtocol2 {}
1616
extension Int: MyProtocol, MyProtocol2 {}
1717

1818
public let metatype1 = Int.self
19-
// SIL: sil_global [let] @$s4test9metatype1Simvp : $@thin Int.Type = {
20-
// SIL-NEXT: %initval = metatype $@thin Int.Type
21-
// SIL-NEXT: }
19+
// SIL: sil_global [let] @$s4test9metatype1Simvp : $@thin Int.Type
20+
// SIL-EMPTY:
2221
public let metatype2 = S.self
2322
// SIL: sil_global [let] @$s4test9metatype2AA1SVmvp : $@thin S.Type = {
2423
// SIL-NEXT: %initval = metatype $@thin S.Type
2524
// SIL-NEXT: }
2625
public let metatype3: Any.Type = Int.self
27-
// SIL: sil_global [let] @$s4test9metatype3ypXpvp : $@thick any Any.Type = {
28-
// SIL-NEXT: %0 = metatype $@thick Int.Type // user: %1
29-
// SIL-NEXT: %initval = init_existential_metatype %0, $@thick any Any.Type
30-
// SIL-NEXT: }
26+
// SIL: sil_global [let] @$s4test9metatype3ypXpvp : $@thick any Any.Type
27+
// SIL-EMPTY:
3128
public let metatype4: Any.Type = S.self
3229
// SIL: sil_global [let] @$s4test9metatype4ypXpvp : $@thick any Any.Type = {
3330
// SIL-NEXT: %0 = metatype $@thick S.Type // user: %1
3431
// SIL-NEXT: %initval = init_existential_metatype %0, $@thick any Any.Type
3532
// SIL-NEXT: }
3633
public let metatype5: any MyProtocol.Type = Int.self
37-
// SIL: sil_global [let] @$s4test9metatype5AA10MyProtocol_pXpvp : $@thick any MyProtocol.Type = {
38-
// SIL-NEXT: %0 = metatype $@thick Int.Type // user: %1
39-
// SIL-NEXT: %initval = init_existential_metatype %0, $@thick any MyProtocol.Type
40-
// SIL-NEXT: }
34+
// SIL: sil_global [let] @$s4test9metatype5AA10MyProtocol_pXpvp : $@thick any MyProtocol.Type
35+
// SIL-EMPTY:
4136
public let metatype6: any MyProtocol.Type = S.self
4237
// SIL: sil_global [let] @$s4test9metatype6AA10MyProtocol_pXpvp : $@thick any MyProtocol.Type = {
4338
// SIL-NEXT: %0 = metatype $@thick S.Type // user: %1
4439
// SIL-NEXT: %initval = init_existential_metatype %0, $@thick any MyProtocol.Type
4540
// SIL-NEXT: }
4641
public let metatype7: any (MyProtocol & MyProtocol2).Type = Int.self
47-
// SIL: sil_global [let] @$s4test9metatype7AA10MyProtocol_AA0C9Protocol2pXpvp : $@thick any (MyProtocol & MyProtocol2).Type = {
48-
// SIL-NEXT: %0 = metatype $@thick Int.Type // user: %1
49-
// SIL-NEXT: %initval = init_existential_metatype %0, $@thick any (MyProtocol & MyProtocol2).Type
50-
// SIL-NEXT: }
42+
// SIL: sil_global [let] @$s4test9metatype7AA10MyProtocol_AA0C9Protocol2pXpvp : $@thick any (MyProtocol & MyProtocol2).Type
43+
// SIL-EMPTY:
5144
public let metatype8: any (MyProtocol & MyProtocol2).Type = S.self
5245
// SIL: sil_global [let] @$s4test9metatype8AA10MyProtocol_AA0C9Protocol2pXpvp : $@thick any (MyProtocol & MyProtocol2).Type = {
5346
// SIL-NEXT: %0 = metatype $@thick S.Type // user: %1
@@ -100,9 +93,6 @@ public var metatype22: [Any.Type] = [S.self]
10093
@main
10194
struct Main { static func main() { } }
10295

103-
// IR: @"$s4test9metatype3ypXpvp" = {{.*}}constant ptr @"$sSiN"
10496
// IR: @"$s4test9metatype4ypXpvp" = {{.*}}constant ptr getelementptr inbounds{{.*}} ({{.*}}, ptr @"$s4test1SVMf", {{.*}})
105-
// IR: @"$s4test9metatype5AA10MyProtocol_pXpvp" = {{.*}}constant <{ ptr, ptr }> <{ ptr @"$sSiN", ptr @"$sSi4test10MyProtocolAAWP" }>
10697
// IR: @"$s4test9metatype6AA10MyProtocol_pXpvp" = {{.*}}constant <{ ptr, ptr }> <{ ptr getelementptr inbounds{{.*}} ({{.*}}, ptr @"$s4test1SVMf", {{.*}}), ptr @"$s4test1SVAA10MyProtocolAAWP" }>
107-
// IR: @"$s4test9metatype7AA10MyProtocol_AA0C9Protocol2pXpvp" = {{.*}}constant <{ ptr, ptr, ptr }> <{ ptr @"$sSiN", ptr @"$sSi4test10MyProtocolAAWP", ptr @"$sSi4test11MyProtocol2AAWP" }>
10898
// IR: @"$s4test9metatype8AA10MyProtocol_AA0C9Protocol2pXpvp" = {{.*}}constant <{ ptr, ptr, ptr }> <{ ptr getelementptr inbounds{{.*}} ({{.*}}, ptr @"$s4test1SVMf", {{.*}}), ptr @"$s4test1SVAA10MyProtocolAAWP", ptr @"$s4test1SVAA11MyProtocol2AAWP" }>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %{python} %utils/split_file.py -o %t %s
3+
4+
// RUN: %target-swift-frontend -parse-as-library -emit-module -o %t/MyModule.swiftmodule %t/MyModule.swift -O
5+
// RUN: %target-swift-frontend -parse-as-library -I %t %t/Main.swift -O -emit-sil | %FileCheck %s --check-prefix SIL
6+
// RUN: %target-swift-frontend -parse-as-library -I %t %t/Main.swift -O -emit-ir | %FileCheck %s --check-prefix IR
7+
8+
// BEGIN MyModule.swift
9+
10+
public class MyClass {}
11+
12+
// BEGIN Main.swift
13+
14+
import MyModule
15+
16+
public let classMetatype = MyClass.self
17+
public let classMetatypeArray = [classMetatype]
18+
19+
// SIL: sil_global [let] @$s4Main13classMetatype8MyModule0D5ClassCmvp : $@thick MyClass.Type
20+
// SIL-EMPTY:
21+
// SIL: sil_global [let] @$s4Main18classMetatypeArraySay8MyModule0E5ClassCmGvp : $Array<MyClass.Type>
22+
// SIL-EMPTY:
23+
24+
// IR: @"$s4Main13classMetatype8MyModule0D5ClassCmvp" = global ptr null
25+
// IR: @"$s4Main18classMetatypeArraySay8MyModule0E5ClassCmGvp" = global %TSa zeroinitializer

0 commit comments

Comments
 (0)