mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Pacage CMO] Update and add more tests
This commit is contained in:
30
test/IRGen/package-cmo-global-accessor.swift
Normal file
30
test/IRGen/package-cmo-global-accessor.swift
Normal file
@@ -0,0 +1,30 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// RUN: %target-build-swift -module-name=File -package-name Pkg -I%t -emit-ir %s -o %t/IR-nonres.ir
|
||||
// RUN: %target-build-swift -module-name=File -package-name Pkg -I%t -emit-ir %s -enable-library-evolution -o %t/IR-res.ir
|
||||
// RUN: %target-build-swift -module-name=File -package-name Pkg -I%t -emit-ir %s -enable-library-evolution -wmo -Xfrontend -experimental-allow-non-resilient-access -Xfrontend -experimental-package-cmo -o %t/IR-res-package-cmo.ir
|
||||
|
||||
// RUN: %FileCheck %s --check-prefix=CHECK-IR-NONRES < %t/IR-nonres.ir
|
||||
// RUN: %FileCheck %s --check-prefix=CHECK-IR-RES < %t/IR-res.ir
|
||||
// RUN: %FileCheck %s --check-prefix=CHECK-IR-RES < %t/IR-res-package-cmo.ir
|
||||
|
||||
public struct S {
|
||||
public static let x = "hello world"
|
||||
package static let y = "dogs cats"
|
||||
}
|
||||
|
||||
public struct R {
|
||||
package static let a = "foo"
|
||||
public static let b = "bar"
|
||||
}
|
||||
|
||||
// CHECK-IR-NONRES: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @"$s4File1SV1xSSvau"()
|
||||
// CHECK-IR-NONRES: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @"$s4File1SV1ySSvau"()
|
||||
// CHECK-IR-NONRES: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @"$s4File1RV1aSSvau"()
|
||||
// CHECK-IR-NONRES: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @"$s4File1RV1bSSvau"()
|
||||
|
||||
// CHECK-IR-RES: define hidden swiftcc ptr @"$s4File1SV1xSSvau"()
|
||||
// CHECK-IR-RES: define hidden swiftcc ptr @"$s4File1SV1ySSvau"()
|
||||
// CHECK-IR-RES: define hidden swiftcc ptr @"$s4File1RV1aSSvau"()
|
||||
// CHECK-IR-RES: define hidden swiftcc ptr @"$s4File1RV1bSSvau"()
|
||||
|
||||
65
test/IRGen/package-cmo-serialize-witness-thunk.swift
Normal file
65
test/IRGen/package-cmo-serialize-witness-thunk.swift
Normal file
@@ -0,0 +1,65 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// RUN: %target-swift-frontend -module-name=Lib -package-name libpkg -emit-silgen %s -enable-library-evolution -wmo -o %t/Lib-no-pcmo-silgen.sil
|
||||
|
||||
// RUN: %target-swift-frontend -module-name=Lib -package-name libpkg -emit-sil %s -enable-library-evolution -wmo -o %t/Lib-no-pcmo-sil.sil
|
||||
|
||||
// RUN: %target-swift-frontend -module-name=Lib -package-name libpkg -emit-ir %s -enable-library-evolution -wmo -o %t/Lib-no-pcmo-ir.ll -emit-tbd-path %t/Lib-no-pcmo-tbd.tbd -tbd-install_name Lib
|
||||
|
||||
// RUN: %target-swift-frontend -module-name=Lib -package-name libpkg -emit-silgen %s -enable-library-evolution -wmo -allow-non-resilient-access -package-cmo -o %t/Lib-silgen.sil
|
||||
|
||||
// RUN: %target-swift-frontend -module-name=Lib -package-name libpkg -emit-sil %s -enable-library-evolution -wmo -allow-non-resilient-access -package-cmo -o %t/Lib-sil.sil
|
||||
|
||||
// RUN: %target-swift-frontend -module-name=Lib -package-name libpkg -emit-ir %s -enable-library-evolution -wmo -allow-non-resilient-access -package-cmo -o %t/Lib-ir.ll -emit-tbd-path %t/Lib-tbd.tbd -tbd-install_name Lib
|
||||
|
||||
// RUN: %FileCheck %s --check-prefix=CHECK-NO-PCMO-SILGEN < %t/Lib-no-pcmo-silgen.sil
|
||||
// RUN: %FileCheck %s --check-prefix=CHECK-NO-PCMO-SIL < %t/Lib-no-pcmo-sil.sil
|
||||
// RUN: %FileCheck %s --check-prefix=CHECK-NO-PCMO-IR < %t/Lib-no-pcmo-ir.ll
|
||||
// RUN: %FileCheck %s --check-prefix=CHECK-NO-PCMO-TBD < %t/Lib-no-pcmo-tbd.tbd
|
||||
// RUN: %FileCheck %s --check-prefix=CHECK-SILGEN < %t/Lib-silgen.sil
|
||||
// RUN: %FileCheck %s --check-prefix=CHECK-SIL < %t/Lib-sil.sil
|
||||
// RUN: %FileCheck %s --check-prefix=CHECK-IR < %t/Lib-ir.ll
|
||||
// RUN: %FileCheck %s --check-prefix=CHECK-TBD < %t/Lib-tbd.tbd
|
||||
|
||||
|
||||
/// TEST that a public (or package) protocol witness thunk gets a shared linkage if Package CMO is enabled.
|
||||
/// It also gets [serialized] in emit-silgen.
|
||||
///
|
||||
// protocol witness for Proto.foo.getter in conformance Pub
|
||||
|
||||
// CHECK-NO-PCMO-SILGEN-DAG: sil private [transparent] [thunk] [ossa] @$s3Lib3PubVAA5ProtoA2aDP3fooSSvgTW : $@convention(witness_method: Proto) (@in_guaranteed Pub) -> @owned String {
|
||||
// CHECK-SILGEN-DAG: sil shared [transparent] [serialized] [thunk] [ossa] @$s3Lib3PubVAA5ProtoA2aDP3fooSSvgTW : $@convention(witness_method: Proto) (@in_guaranteed Pub) -> @owned String {
|
||||
|
||||
// CHECK-NO-PCMO-SIL-DAG: sil private [transparent] [thunk] @$s3Lib3PubVAA5ProtoA2aDP3fooSSvgTW : $@convention(witness_method: Proto) (@in_guaranteed Pub) -> @owned String {
|
||||
// CHECK-SIL-DAG: sil shared [transparent] [thunk] @$s3Lib3PubVAA5ProtoA2aDP3fooSSvgTW : $@convention(witness_method: Proto) (@in_guaranteed Pub) -> @owned String {
|
||||
|
||||
// CHECK-NO-PCMO-IR-DAG: define internal swiftcc { {{i64|i32}}, ptr } @"$s3Lib3PubVAA5ProtoA2aDP3fooSSvgTW"
|
||||
// CHECK-IR-DAG: define linkonce_odr hidden swiftcc { {{i64|i32}}, ptr } @"$s3Lib3PubVAA5ProtoA2aDP3fooSSvgTW"
|
||||
|
||||
// protocol witness for Proto.bar(_:) in conformance Pub
|
||||
|
||||
// CHECK-NO-PCMO-SILGEN-DAG: sil private [transparent] [thunk] [ossa] @$s3Lib3PubVAA5ProtoA2aDP3baryS2iFTW : $@convention(witness_method: Proto) (Int, @in_guaranteed Pub) -> Int {
|
||||
// CHECK-SILGEN-DAG: sil shared [transparent] [serialized] [thunk] [ossa] @$s3Lib3PubVAA5ProtoA2aDP3baryS2iFTW : $@convention(witness_method: Proto) (Int, @in_guaranteed Pub) -> Int {
|
||||
|
||||
// CHECK-NO-PCMO-SIL-DAG: sil private [transparent] [thunk] @$s3Lib3PubVAA5ProtoA2aDP3baryS2iFTW : $@convention(witness_method: Proto) (Int, @in_guaranteed Pub) -> Int {
|
||||
// CHECK-SIL-DAG: sil shared [transparent] [thunk] @$s3Lib3PubVAA5ProtoA2aDP3baryS2iFTW : $@convention(witness_method: Proto) (Int, @in_guaranteed Pub) -> Int {
|
||||
|
||||
// CHECK-NO-PCMO-IR-DAG: define internal swiftcc {{i64|i32}} @"$s3Lib3PubVAA5ProtoA2aDP3baryS2iFTW"
|
||||
// CHECK-IR-DAG: define linkonce_odr hidden swiftcc i64 @"$s3Lib3PubVAA5ProtoA2aDP3baryS2iFTW"
|
||||
|
||||
// CHECK-NO-PCMO-TBD-NOT: s3Lib3PubVAA5ProtoA2aDP3fooSSvgTW
|
||||
// CHECK-NO-PCMO-TBD-NOT: s3Lib3PubVAA5ProtoA2aDP3baryS2iFTW
|
||||
// CHECK-TBD-NOT: s3Lib3PubVAA5ProtoA2aDP3fooSSvgTW
|
||||
// CHECK-TBD-NOT: s3Lib3PubVAA5ProtoA2aDP3baryS2iFTW
|
||||
|
||||
public protocol Proto {
|
||||
var foo: String { get set }
|
||||
func bar(_ arg: Int) -> Int
|
||||
}
|
||||
|
||||
public struct Pub: Proto {
|
||||
public var foo = "foo"
|
||||
public func bar(_ arg: Int) -> Int {
|
||||
return arg
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// RUN: %target-build-swift -module-name=File -package-name Pkg -I%t -emit-ir %s | %FileCheck %s --check-prefix=CHECK-IR-NONRES
|
||||
// RUN: %target-build-swift -module-name=File -package-name Pkg -I%t -emit-ir %s -enable-library-evolution | %FileCheck %s --check-prefix=CHECK-IR-RES
|
||||
// RUN: %target-build-swift -module-name=File -package-name Pkg -I%t -emit-ir %s -enable-library-evolution -Xfrontend -experimental-allow-non-resilient-access -Xfrontend -experimental-package-cmo | %FileCheck %s --check-prefix=CHECK-IR-RES
|
||||
|
||||
public struct S {
|
||||
public static var x = "hello world"
|
||||
}
|
||||
|
||||
// CHECK-IR-NONRES: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @"$s4File1SV1xSSvau"()
|
||||
// CHECK-IR-RES: define hidden swiftcc ptr @"$s4File1SV1xSSvau"()
|
||||
|
||||
@@ -20,13 +20,12 @@
|
||||
/// Test 1: They should be deserialized into Client as Lib and Client are in the same package.
|
||||
// RUN: %FileCheck -check-prefix=CHECK-INPKG %s < %t/InPkgClient.sil
|
||||
|
||||
// Pub.init(_:) is removed after getting lined below.
|
||||
// CHECK-INPKG-NOT: @$s3Lib3PubCyACSicfc
|
||||
|
||||
// Pub.__allocating_init(_:)
|
||||
// CHECK-INPKG: sil public_external @$s3Lib3PubCyACSicfC : $@convention(method) (Int, @thick Pub.Type) -> @owned Pub {
|
||||
// Pub.init(_:) is inlined in this block, as its body was deserialized.
|
||||
// CHECK-INPKG: ref_element_addr {{.*}} : $Pub, #Pub.pubVar
|
||||
// CHECK-INPKG: function_ref @$s3Lib3PubCyACSicfc
|
||||
|
||||
// Pub.init(_:)
|
||||
// CHECK-INPKG: sil @$s3Lib3PubCyACSicfc : $@convention(method) (Int, @owned Pub) -> @owned Pub
|
||||
|
||||
// CHECK-INPKG: sil_vtable Pub {
|
||||
// CHECK-INPKG: #Pub.pubVar!getter: (Pub) -> () -> Int : @$s3Lib3PubC6pubVarSivg // Pub.pubVar.getter
|
||||
@@ -72,11 +71,6 @@
|
||||
|
||||
// CHECK-LIB: sil [serialized] [exact_self_class] [canonical] @$s3Lib3PubCyACSicfC : $@convention(method) (Int, @thick Pub.Type) -> @owned Pub {
|
||||
// CHECK-LIB: function_ref @$s3Lib3PubCyACSicfc : $@convention(method) (Int, @owned Pub) -> @owned Pub
|
||||
// Pub.init(_:)
|
||||
|
||||
// CHECK-LIB: sil [serialized_for_package] [canonical] @$s3Lib3PubCyACSicfc : $@convention(method) (Int, @owned Pub) -> @owned Pub {
|
||||
// CHECK-LIB: ref_element_addr {{.*}} : $Pub, #Pub.pubVar
|
||||
// Pub.__allocating_init(_:)
|
||||
|
||||
// Pub.pkgVar.getter
|
||||
// CHECK-LIB: sil package [serialized_for_package] [canonical] @$s3Lib3PubC6pkgVarSivg : $@convention(method) (@guaranteed Pub) -> Int {
|
||||
@@ -106,21 +100,35 @@ public protocol PubProto {
|
||||
public class Pub: PubProto {
|
||||
public var pubVar: Int = 1
|
||||
package var pkgVar: Int = 2
|
||||
var internalVar: Int = 3
|
||||
public init(_ arg: Int) {
|
||||
pubVar = arg
|
||||
pkgVar = arg
|
||||
}
|
||||
public func pubFunc(_ arg: Pub) {
|
||||
print(arg.pubVar)
|
||||
}
|
||||
}
|
||||
|
||||
public class SubPub: Pub {
|
||||
override public func pubFunc(_ arg: Pub) {
|
||||
print(arg.pubVar, arg.internalVar)
|
||||
}
|
||||
}
|
||||
|
||||
//--- Client.swift
|
||||
import Lib
|
||||
|
||||
public func test(_ arg: Int) -> Int {
|
||||
public func test1(_ arg: Int) -> Int {
|
||||
let x = Pub(arg)
|
||||
x.pubVar = 3
|
||||
return x.run()
|
||||
}
|
||||
|
||||
public func test2(_ arg: Int) {
|
||||
SubPub(arg).pubFunc(Pub(arg))
|
||||
}
|
||||
|
||||
public extension PubProto {
|
||||
func run() -> Int {
|
||||
return pubVar
|
||||
|
||||
53
test/SILOptimizer/package-cmo-inlining-pass.swift
Normal file
53
test/SILOptimizer/package-cmo-inlining-pass.swift
Normal file
@@ -0,0 +1,53 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// RUN: %target-swift-frontend %s \
|
||||
// RUN: -emit-sil -module-name=Lib -package-name Pkg \
|
||||
// RUN: -package-cmo -allow-non-resilient-access \
|
||||
// RUN: -O -wmo -enable-library-evolution \
|
||||
// RUN: -Xllvm -sil-print-function=s3Lib3fooyS2iF 2>&1 | %FileCheck %s
|
||||
|
||||
/// TEST that accessing PkgStruct in the following functions gets inlined after perf inlining pass.
|
||||
public func bar(_ arg: Int) -> Int {
|
||||
let p = PkgStruct(1, 2)
|
||||
return arg > 0 ? p.field1 : p.field2
|
||||
}
|
||||
|
||||
package func foo(_ arg: Int) -> Int {
|
||||
let p = PkgStruct(1, 2)
|
||||
return arg > 0 ? p.field1 : p.field2
|
||||
}
|
||||
|
||||
package struct PkgStruct {
|
||||
package let field1: Int
|
||||
package let field2: Int
|
||||
package init(_ arg1: Int, _ arg2: Int) {
|
||||
field1 = arg1
|
||||
field2 = arg2
|
||||
}
|
||||
}
|
||||
|
||||
/// BEFORE perf inlining pass.
|
||||
// CHECK: sil package @$s3Lib3fooyS2iF : $@convention(thin) (Int) -> Int {
|
||||
// CHECK: [[PKG_STACK:%.*]] = alloc_stack $PkgStruct
|
||||
// CHECK: [[FUNC_REF:%.*]] = function_ref @$s3Lib9PkgStructVyACSi_SitcfC : $@convention(method) (Int, Int, @thin PkgStruct.Type) -> @out PkgStruct
|
||||
// CHECK: apply [[FUNC_REF]]
|
||||
// CHECK: [[F1:%.*]] = struct_element_addr [[PKG_STACK]] : $*PkgStruct, #PkgStruct.field1
|
||||
// CHECK: load [[F1]] : $*Int
|
||||
// CHECK: [[F2:%.*]] = struct_element_addr [[PKG_STACK]] : $*PkgStruct, #PkgStruct.field2
|
||||
// CHECK: load [[F2]] : $*Int
|
||||
|
||||
/// AFTER perf inlining pass; body of `@$s3Lib9PkgStructVyACSi_SitcfC` gets inlined.
|
||||
// CHECK: *** SIL function after {{.*}} EarlyPerfInliner (early-inline)
|
||||
// CHECK: sil package @$s3Lib3fooyS2iF : $@convention(thin) (Int) -> Int {
|
||||
// CHECK: [[PKG_ALLOC:%.*]] = alloc_stack $PkgStruct
|
||||
// CHECK: [[PKG_INIT:%.*]] = alloc_stack [var_decl] $PkgStruct, var, name "self"
|
||||
// CHECK: [[FIELD1_IVAR:%.*]] = struct_element_addr [[PKG_INIT]] : $*PkgStruct, #PkgStruct.field1
|
||||
// CHECK: store {{.*}} to [[FIELD1_IVAR]] : $*Int
|
||||
// CHECK: [[FIELD2_IVAR:%.*]] = struct_element_addr [[PKG_INIT]] : $*PkgStruct, #PkgStruct.field2
|
||||
// CHECK: store {{.*}} to [[FIELD2_IVAR]] : $*Int
|
||||
// CHECK: [[PKG_STR:%.*]] = struct $PkgStruct
|
||||
// CHECK: store [[PKG_STR]] to [[PKG_ALLOC]] : $*PkgStruct
|
||||
// CHECK: [[FIELD1:%.*]] = struct_element_addr [[PKG_ALLOC]] : $*PkgStruct, #PkgStruct.field1
|
||||
// CHECK: load [[FIELD1]] : $*Int
|
||||
// CHECK: [[FIELD2:%.*]] = struct_element_addr [[PKG_ALLOC]] : $*PkgStruct, #PkgStruct.field2
|
||||
// CHECK: load [[FIELD2]] : $*Int
|
||||
@@ -29,10 +29,15 @@ import Lib
|
||||
|
||||
/// There should be no linker error on a public function
|
||||
/// that contains symbols internal to Lib module.
|
||||
///
|
||||
|
||||
// CHECK-MAIN-NOT: s3Lib14createPubClassySixlF
|
||||
// CHECK-MAIN-NOT: s3Lib19usePubStructKeypathySixlF
|
||||
|
||||
// CHECK-MAIN: function_ref @$s3Lib11useInternalySiAA4BaseCF : $@convention(thin) (@guaranteed Base) -> Int
|
||||
let x = useInternal(Base())
|
||||
|
||||
/// Since Base is not serialized, accessing its field should go
|
||||
/// Since Base is not serialized, accessing its field should go
|
||||
/// through `class_method`.
|
||||
// CHECK-MAIN: class_method {{.*}} : $Base, #Base.baseVarPkg!getter : (Base) -> () -> Int, $@convention(method) (@guaranteed Base) -> Int
|
||||
let y = usePkg(Base())
|
||||
@@ -51,7 +56,55 @@ let w = usePubWithInternalField(PubKlassWithInternalMember(1))
|
||||
// CHECK-MAIN: sil @$s3Lib11useInternalySiAA4BaseCF : $@convention(thin) (@guaranteed Base) -> Int
|
||||
|
||||
// PubKlassWithInternalMember.__allocating_init(_:)
|
||||
// CHECK-MAIN: sil public_external @$s3Lib26PubKlassWithInternalMemberCyACSicfC : $@convention(method) (Int, @thick PubKlassWithInternalMember.Type) -> @owned PubKlassWithInternalMember {
|
||||
// CHECK-MAIN-DAG: sil public_external @$s3Lib26PubKlassWithInternalMemberCyACSicfC : $@convention(method) (Int, @thick PubKlassWithInternalMember.Type) -> @owned PubKlassWithInternalMember {
|
||||
|
||||
func checkNested() {
|
||||
// PubContainer initializer is inlined.
|
||||
// CHECK-MAIN: struct $PubContainer ()
|
||||
let c = PubContainer()
|
||||
// CHECK-MAIN: function_ref @$s3Lib12PubContainerV9pubMemberyxxlF
|
||||
print(c.pubMember(27))
|
||||
}
|
||||
|
||||
|
||||
func checkClasses() {
|
||||
/// Inlined
|
||||
print(createPubClass(0))
|
||||
|
||||
/// Not inlined as functions below contain private/internal symbols
|
||||
// CHECK-MAIN: function_ref @$s3Lib20createPubClass_neverySixlF
|
||||
print(createPubClass_never(0))
|
||||
|
||||
// CHECK-MAIN: function_ref @$s3Lib14createPrvClassySixlF
|
||||
print(createPrvClass(0))
|
||||
|
||||
// CHECK-MAIN: function_ref @$s3Lib20createPrvClass_neverySixlF
|
||||
print(createPrvClass_never(0))
|
||||
}
|
||||
|
||||
func checkKeyPaths() {
|
||||
/// Inlined
|
||||
// CHECK-MAIN: function_ref @$s3Lib19getPubStructKeypathys7KeyPathCyAA0cD0VSiGxlF
|
||||
print(usePubStructKeypath(0))
|
||||
|
||||
/// Not inlined as functions below contain private/internal symbols
|
||||
// CHECK-MAIN: function_ref @$s3Lib24useInternalStructKeypathySixlF
|
||||
print(useInternalStructKeypath(0))
|
||||
|
||||
// CHECK-MAIN: function_ref @$s3Lib15useClassKeypathySixlF
|
||||
print(useClassKeypath(0))
|
||||
}
|
||||
|
||||
checkNested()
|
||||
checkClasses()
|
||||
checkKeyPaths()
|
||||
|
||||
// CHECK-MAIN-DAG: sil public_external [_semantics "optimize.sil.specialize.generic.never"] @$s3Lib20createPubClass_neverySixlF : $@convention(thin) <T> (@in_guaranteed T) -> Int {
|
||||
// CHECK-MAIN-DAG: sil @$s3Lib14createPrvClassySixlF : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> Int
|
||||
// CHECK-MAIN-DAG: sil [_semantics "optimize.sil.specialize.generic.never"] @$s3Lib20createPrvClass_neverySixlF : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> Int
|
||||
// CHECK-MAIN-DAG: sil @$s3Lib12PubContainerV9pubMemberyxxlF : $@convention(method) <τ_0_0> (@in_guaranteed τ_0_0, @in_guaranteed PubContainer) -> @out τ_0_0
|
||||
// CHECK-MAIN-DAG: sil @$s3Lib24useInternalStructKeypathySixlF : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> Int
|
||||
// CHECK-MAIN-DAG: sil @$s3Lib15useClassKeypathySixlF : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> Int
|
||||
|
||||
|
||||
//--- Lib.swift
|
||||
@@ -140,6 +193,139 @@ public class PubKlassWithInternalMember {
|
||||
}
|
||||
}
|
||||
|
||||
// createPubClass<A>(_:)
|
||||
// CHECK-DAG: sil [serialized_for_package] [canonical] @$s3Lib14createPubClassySixlF : $@convention(thin) <T> (@in_guaranteed T) -> Int {
|
||||
public func createPubClass<T>(_ t: T) -> Int {
|
||||
return getPubClass(t).foo()
|
||||
}
|
||||
|
||||
// CHECK-DAG: sil [serialized_for_package] [_semantics "optimize.sil.specialize.generic.never"] [canonical] @$s3Lib20createPubClass_neverySixlF : $@convention(thin) <T> (@in_guaranteed T) -> Int {
|
||||
@_semantics("optimize.sil.specialize.generic.never")
|
||||
public func createPubClass_never<T>(_ t: T) -> Int {
|
||||
return getPubClass(t).foo()
|
||||
}
|
||||
|
||||
// CHECK-DAG: sil [serialized_for_package] [canonical] @$s3Lib11getPubClassyAA13PublicDerivedCyxGxlF : $@convention(thin) <T> (@in_guaranteed T) -> @owned PublicDerived<T> {
|
||||
public func getPubClass<T>(_ t : T) -> PublicDerived<T> {
|
||||
return PublicDerived<T>(t)
|
||||
}
|
||||
|
||||
// Not serialized
|
||||
public func createPrvClass<T>(_ t: T) -> Int {
|
||||
return getPrvClass(t).foo()
|
||||
}
|
||||
|
||||
// Not serialized
|
||||
@_semantics("optimize.sil.specialize.generic.never")
|
||||
public func createPrvClass_never<T>(_ t: T) -> Int {
|
||||
return getPrvClass(t).foo()
|
||||
}
|
||||
|
||||
// Not serialized
|
||||
private func getPrvClass<T>(_ t : T) -> PrivateBase<T> {
|
||||
return PrivateDerived<T>(t)
|
||||
}
|
||||
|
||||
public class PublicBase<T> {
|
||||
public var t: T
|
||||
public func foo() -> Int { return 27 }
|
||||
public init(_ t: T) { self.t = t }
|
||||
}
|
||||
|
||||
public class PublicDerived<T> : PublicBase<T> {
|
||||
override public func foo() -> Int { return 28 }
|
||||
}
|
||||
|
||||
private class PrivateBase<T> {
|
||||
var t: T
|
||||
func foo() -> Int { return 27 }
|
||||
init(_ t: T) { self.t = t }
|
||||
}
|
||||
|
||||
private class PrivateDerived<T> : PrivateBase<T> {
|
||||
override func foo() -> Int { return 28 }
|
||||
}
|
||||
|
||||
public struct PubContainer {
|
||||
private final class PrvBase {}
|
||||
public init() {}
|
||||
|
||||
// Not serialized; contains exported func
|
||||
// but references a private class.
|
||||
public func pubMember<T>(_ t: T) -> T {
|
||||
var arr = Array<PrvBase>()
|
||||
arr.append(PrvBase())
|
||||
print(arr)
|
||||
exportedFunc(arr)
|
||||
return t
|
||||
}
|
||||
}
|
||||
|
||||
@_specialize(exported: true, where T == Int)
|
||||
@inlinable
|
||||
public func exportedFunc<T>(_ t: T) {
|
||||
print(t)
|
||||
}
|
||||
|
||||
public func pubFunc<T>(_ t: T) -> Int {
|
||||
return getPubClass(t).foo()
|
||||
}
|
||||
|
||||
@_semantics("optimize.sil.specialize.generic.never")
|
||||
public func pubFuncNoSpecialize<T>(_ t: T) -> Int {
|
||||
return getPubClass(t).foo()
|
||||
}
|
||||
|
||||
struct MyInternalStruct {
|
||||
var x: Int { return 27 }
|
||||
var y: Int { return 28 }
|
||||
}
|
||||
|
||||
public struct PubStruct {
|
||||
public var x: Int { return 27 }
|
||||
public var y: Int { return 28 }
|
||||
}
|
||||
|
||||
class Myclass {
|
||||
var x: Int { return 27 }
|
||||
var y: Int { return 28 }
|
||||
}
|
||||
|
||||
class Derived : Myclass {
|
||||
override var x: Int { return 29 }
|
||||
override var y: Int { return 30 }
|
||||
}
|
||||
|
||||
|
||||
func getInternalStructKeypath<T>(_ t: T) -> KeyPath<MyInternalStruct, Int> {
|
||||
return \MyInternalStruct.x
|
||||
}
|
||||
|
||||
// CHECK-DAG: sil [canonical] @$s3Lib19getPubStructKeypathys7KeyPathCyAA0cD0VSiGxlF : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @owned KeyPath<PubStruct, Int>
|
||||
public func getPubStructKeypath<T>(_ t: T) -> KeyPath<PubStruct, Int> {
|
||||
return \PubStruct.x
|
||||
}
|
||||
|
||||
public func useInternalStructKeypath<T>(_ t: T) -> Int {
|
||||
let s = MyInternalStruct()
|
||||
return s[keyPath: getInternalStructKeypath(t)]
|
||||
}
|
||||
|
||||
// CHECK-DAG: sil [serialized_for_package] [canonical] @$s3Lib19usePubStructKeypathySixlF : $@convention(thin) <T> (@in_guaranteed T) -> Int {
|
||||
public func usePubStructKeypath<T>(_ t: T) -> Int {
|
||||
let p = PubStruct()
|
||||
return p[keyPath: getPubStructKeypath(t)]
|
||||
}
|
||||
|
||||
func getClassKeypath<T>(_ t: T) -> KeyPath<Myclass, Int> {
|
||||
return \Myclass.x
|
||||
}
|
||||
|
||||
public func useClassKeypath<T>(_ t: T) -> Int {
|
||||
let c = Derived()
|
||||
return c[keyPath: getClassKeypath(t)]
|
||||
}
|
||||
|
||||
/// PubKlass doesn't contain internal symbols so its vtable is serialized.
|
||||
// CHECK-LABEL: sil_vtable [serialized_for_package] PubKlass {
|
||||
// CHECK-NEXT: #PubKlass.init!allocator: (PubKlass.Type) -> () -> PubKlass : @$s3Lib8PubKlassCACycfC
|
||||
@@ -1,206 +0,0 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: split-file %s %t
|
||||
|
||||
// RUN: %target-build-swift %t/Lib.swift \
|
||||
// RUN: -module-name=Lib -package-name Pkg \
|
||||
// RUN: -parse-as-library -emit-module -emit-module-path %t/Lib.swiftmodule -I%t \
|
||||
// RUN: -Xfrontend -experimental-package-cmo -Xfrontend -experimental-allow-non-resilient-access \
|
||||
// RUN: -O -wmo -enable-library-evolution
|
||||
// RUN: %target-sil-opt %t/Lib.swiftmodule -sil-verify-all -o %t/Lib.sil
|
||||
|
||||
// RUN: %target-build-swift -module-name=Main -package-name Pkg -I%t -emit-sil -O -wmo -Xllvm -sil-disable-pass=FunctionSignatureOpts %t/main.swift -o %t/Main.sil
|
||||
|
||||
// RUN: %FileCheck %s --check-prefixes=CHECK < %t/Lib.sil
|
||||
// RUN: %FileCheck %s --check-prefixes=CHECK-MAIN < %t/Main.sil
|
||||
|
||||
|
||||
//--- main.swift
|
||||
import Lib
|
||||
|
||||
// CHECK-MAIN-NOT: s3Lib14createPubClassySixlF
|
||||
// CHECK-MAIN-NOT: s3Lib19usePubStructKeypathySixlF
|
||||
|
||||
func checkClasses() {
|
||||
/// Inlined
|
||||
print(createPubClass(0))
|
||||
|
||||
/// Not inlined as functions below contain private/internal symbols
|
||||
// CHECK-MAIN-DAG: function_ref @$s3Lib20createPubClass_neverySixlF
|
||||
// CHECK-MAIN-DAG: sil public_external [_semantics "optimize.sil.specialize.generic.never"] @$s3Lib20createPubClass_neverySixlF : $@convention(thin) <T> (@in_guaranteed T) -> Int {
|
||||
print(createPubClass_never(0))
|
||||
|
||||
// CHECK-MAIN-DAG: function_ref @$s3Lib14createPrvClassySixlF
|
||||
// CHECK-MAIN-DAG: sil @$s3Lib14createPrvClassySixlF : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> Int
|
||||
print(createPrvClass(0))
|
||||
|
||||
// CHECK-MAIN-DAG: function_ref @$s3Lib20createPrvClass_neverySixlF
|
||||
// CHECK-MAIN-DAG: sil [_semantics "optimize.sil.specialize.generic.never"] @$s3Lib20createPrvClass_neverySixlF : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> Int
|
||||
print(createPrvClass_never(0))
|
||||
}
|
||||
|
||||
func checkNested() {
|
||||
// PubContainer initializer is inlined.
|
||||
// CHECK-MAIN-DAG: struct $PubContainer ()
|
||||
let c = PubContainer()
|
||||
// CHECK-MAIN-DAG: function_ref @$s3Lib12PubContainerV9pubMemberyxxlF
|
||||
// CHECK-MAIN-DAG: sil @$s3Lib12PubContainerV9pubMemberyxxlF : $@convention(method) <τ_0_0> (@in_guaranteed τ_0_0, @in_guaranteed PubContainer) -> @out τ_0_0
|
||||
print(c.pubMember(27))
|
||||
}
|
||||
|
||||
func checkKeyPaths() {
|
||||
/// Inlined
|
||||
// CHECK-MAIN-DAG: function_ref @$s3Lib19getPubStructKeypathys7KeyPathCyAA0cD0VSiGxlF
|
||||
print(usePubStructKeypath(0))
|
||||
|
||||
/// Not inlined as functions below contain private/internal symbols
|
||||
// CHECK-MAIN-DAG: function_ref @$s3Lib24useInternalStructKeypathySixlF
|
||||
// CHECK-MAIN-DAG: sil @$s3Lib24useInternalStructKeypathySixlF : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> Int
|
||||
print(useInternalStructKeypath(0))
|
||||
|
||||
// CHECK-MAIN-DAG: function_ref @$s3Lib15useClassKeypathySixlF
|
||||
// CHECK-MAIN-DAG: sil @$s3Lib15useClassKeypathySixlF : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> Int
|
||||
print(useClassKeypath(0))
|
||||
}
|
||||
|
||||
checkNested()
|
||||
checkClasses()
|
||||
checkKeyPaths()
|
||||
|
||||
|
||||
//--- Lib.swift
|
||||
|
||||
// createPubClass<A>(_:)
|
||||
// CHECK-DAG: sil [serialized_for_package] [canonical] @$s3Lib14createPubClassySixlF : $@convention(thin) <T> (@in_guaranteed T) -> Int {
|
||||
public func createPubClass<T>(_ t: T) -> Int {
|
||||
return getPubClass(t).foo()
|
||||
}
|
||||
|
||||
// CHECK-DAG: sil [serialized_for_package] [_semantics "optimize.sil.specialize.generic.never"] [canonical] @$s3Lib20createPubClass_neverySixlF : $@convention(thin) <T> (@in_guaranteed T) -> Int {
|
||||
@_semantics("optimize.sil.specialize.generic.never")
|
||||
public func createPubClass_never<T>(_ t: T) -> Int {
|
||||
return getPubClass(t).foo()
|
||||
}
|
||||
|
||||
// CHECK-DAG: sil [serialized_for_package] [canonical] @$s3Lib11getPubClassyAA13PublicDerivedCyxGxlF : $@convention(thin) <T> (@in_guaranteed T) -> @owned PublicDerived<T> {
|
||||
public func getPubClass<T>(_ t : T) -> PublicDerived<T> {
|
||||
return PublicDerived<T>(t)
|
||||
}
|
||||
|
||||
// Not serialized
|
||||
public func createPrvClass<T>(_ t: T) -> Int {
|
||||
return getPrvClass(t).foo()
|
||||
}
|
||||
|
||||
// Not serialized
|
||||
@_semantics("optimize.sil.specialize.generic.never")
|
||||
public func createPrvClass_never<T>(_ t: T) -> Int {
|
||||
return getPrvClass(t).foo()
|
||||
}
|
||||
|
||||
// Not serialized
|
||||
private func getPrvClass<T>(_ t : T) -> PrivateBase<T> {
|
||||
return PrivateDerived<T>(t)
|
||||
}
|
||||
|
||||
public class PublicBase<T> {
|
||||
public var t: T
|
||||
public func foo() -> Int { return 27 }
|
||||
public init(_ t: T) { self.t = t }
|
||||
}
|
||||
|
||||
public class PublicDerived<T> : PublicBase<T> {
|
||||
override public func foo() -> Int { return 28 }
|
||||
}
|
||||
|
||||
private class PrivateBase<T> {
|
||||
var t: T
|
||||
func foo() -> Int { return 27 }
|
||||
init(_ t: T) { self.t = t }
|
||||
}
|
||||
|
||||
private class PrivateDerived<T> : PrivateBase<T> {
|
||||
override func foo() -> Int { return 28 }
|
||||
}
|
||||
|
||||
public struct PubContainer {
|
||||
private final class PrvBase {}
|
||||
public init() {}
|
||||
|
||||
// Not serialized; contains exported func
|
||||
// but references a private class.
|
||||
public func pubMember<T>(_ t: T) -> T {
|
||||
var arr = Array<PrvBase>()
|
||||
arr.append(PrvBase())
|
||||
print(arr)
|
||||
exportedFunc(arr)
|
||||
return t
|
||||
}
|
||||
}
|
||||
|
||||
@_specialize(exported: true, where T == Int)
|
||||
@inlinable
|
||||
public func exportedFunc<T>(_ t: T) {
|
||||
print(t)
|
||||
}
|
||||
|
||||
public func pubFunc<T>(_ t: T) -> Int {
|
||||
return getPubClass(t).foo()
|
||||
}
|
||||
|
||||
@_semantics("optimize.sil.specialize.generic.never")
|
||||
public func pubFuncNoSpecialize<T>(_ t: T) -> Int {
|
||||
return getPubClass(t).foo()
|
||||
}
|
||||
|
||||
|
||||
struct InternalStruct {
|
||||
var x: Int { return 27 }
|
||||
var y: Int { return 28 }
|
||||
}
|
||||
|
||||
public struct PubStruct {
|
||||
public var x: Int { return 27 }
|
||||
public var y: Int { return 28 }
|
||||
}
|
||||
|
||||
class Myclass {
|
||||
var x: Int { return 27 }
|
||||
var y: Int { return 28 }
|
||||
}
|
||||
|
||||
class Derived : Myclass {
|
||||
override var x: Int { return 29 }
|
||||
override var y: Int { return 30 }
|
||||
}
|
||||
|
||||
|
||||
func getInternalStructKeypath<T>(_ t: T) -> KeyPath<InternalStruct, Int> {
|
||||
return \InternalStruct.x
|
||||
}
|
||||
|
||||
// CHECK-DAG: sil [canonical] @$s3Lib19getPubStructKeypathys7KeyPathCyAA0cD0VSiGxlF : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @owned KeyPath<PubStruct, Int>
|
||||
public func getPubStructKeypath<T>(_ t: T) -> KeyPath<PubStruct, Int> {
|
||||
return \PubStruct.x
|
||||
}
|
||||
|
||||
public func useInternalStructKeypath<T>(_ t: T) -> Int {
|
||||
let s = InternalStruct()
|
||||
return s[keyPath: getInternalStructKeypath(t)]
|
||||
}
|
||||
|
||||
// CHECK-DAG: sil [serialized_for_package] [canonical] @$s3Lib19usePubStructKeypathySixlF : $@convention(thin) <T> (@in_guaranteed T) -> Int {
|
||||
public func usePubStructKeypath<T>(_ t: T) -> Int {
|
||||
let p = PubStruct()
|
||||
return p[keyPath: getPubStructKeypath(t)]
|
||||
}
|
||||
|
||||
func getClassKeypath<T>(_ t: T) -> KeyPath<Myclass, Int> {
|
||||
return \Myclass.x
|
||||
}
|
||||
|
||||
|
||||
public func useClassKeypath<T>(_ t: T) -> Int {
|
||||
let c = Derived()
|
||||
return c[keyPath: getClassKeypath(t)]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user