Skip to content

[PackageCMO] Global var and accessor linkage should be kept private/hidden in SILGen. #74416

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3060,9 +3060,6 @@ bool AbstractStorageDecl::isResilient(ModuleDecl *M,
case ResilienceExpansion::Maximal:
if (M == getModuleContext())
return false;
// Access non-resiliently if package optimization is enabled
if (bypassResilienceInPackage(M))
return false;
return isResilient();
}
llvm_unreachable("bad resilience expansion");
Expand Down
4 changes: 3 additions & 1 deletion lib/SIL/IR/SILDeclRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,9 @@ static LinkageLimit getLinkageLimit(SILDeclRef constant) {
return Limit::OnDemand;

case Kind::GlobalAccessor:
return cast<VarDecl>(d)->isStrictlyResilient() ? Limit::NeverPublic : Limit::None;
// global unsafeMutableAddressor should be kept hidden if its decl
// is resilient.
return cast<VarDecl>(d)->isResilient() ? Limit::NeverPublic : Limit::None;

case Kind::DefaultArgGenerator:
// If the default argument is to be serialized, only use non-ABI public
Expand Down
4 changes: 2 additions & 2 deletions lib/SILGen/SILGenGlobalVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ SILGlobalVariable *SILGenModule::getSILGlobalVariable(VarDecl *gDecl,

// Get the linkage for SILGlobalVariable.
FormalLinkage formalLinkage;
if (gDecl->isResilient() &&
!gDecl->getModuleContext()->serializePackageEnabled())
// sil_global linkage should be kept private if its decl is resilient.
if (gDecl->isResilient())
formalLinkage = FormalLinkage::Private;
else
formalLinkage = getDeclLinkage(gDecl);
Expand Down
21 changes: 0 additions & 21 deletions test/IRGen/package_bypass_resilience_global_accessor.swift

This file was deleted.

13 changes: 13 additions & 0 deletions test/IRGen/package_global_accessor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// 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"()

Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

/// To bypass resilience at use site, Client needs to be in the same package as its
/// loaded module and also opt in with -experimental-package-bypass-resilience.
// RUN: %target-swift-frontend -emit-silgen %t/Client.swift -I %t -module-name Client -package-name mypkg -experimental-package-bypass-resilience | %FileCheck %s --check-prefixes=CHECK,CHECK-BYPASS
// RUN: %target-swift-frontend -emit-silgen %t/Client.swift -I %t -module-name Client -package-name mypkg -experimental-package-bypass-resilience -enable-library-evolution | %FileCheck %s --check-prefixes=CHECK,CHECK-BYPASS
// RUN: %target-swift-frontend -emit-silgen %t/Client.swift -I %t -module-name Client -package-name mypkg -experimental-package-bypass-resilience | %FileCheck %s --check-prefixes=CHECK,CHECK-ACCESS
// RUN: %target-swift-frontend -emit-silgen %t/Client.swift -I %t -module-name Client -package-name mypkg -experimental-package-bypass-resilience -enable-library-evolution | %FileCheck %s --check-prefixes=CHECK,CHECK-ACCESS

/// Utils can be built with both -enable-testing and -experimental-allow-non-resilient-access.
// RUN: rm -rf %t/Utils.swiftmodule
Expand Down Expand Up @@ -158,7 +158,7 @@ func foo() {
// CHECK: sil hidden [ossa] @$s6Client3fooyyF : $@convention(thin) () -> () {
// CHECK-DEFAULT: function_ref @$s5Utils9PkgStructV6pkgVarSivg : $@convention(method) (@in_guaranteed PkgStruct) -> Int
// CHECK-DEFAULT: sil package_external @$s5Utils9PkgStructV6pkgVarSivg : $@convention(method) (@in_guaranteed PkgStruct) -> Int
// CHECK-BYPASS: struct_element_addr {{.*}} : $*PkgStruct, #PkgStruct.pkgVar
// CHECK-ACCESS: function_ref @$s5Utils9PkgStructV6pkgVarSivg
// CHECK-NONRES: struct_extract {{.*}} : $PkgStruct, #PkgStruct.pkgVar

func bar() {
Expand All @@ -168,5 +168,5 @@ func bar() {
// CHECK: sil hidden [ossa] @$s6Client3baryyF : $@convention(thin) () -> () {
// CHECK-DEFAULT: function_ref @$s5Utils9PubStructV6pubVarSivg : $@convention(method) (@in_guaranteed PubStruct) -> Int
// CHECK-DEFAULT: sil @$s5Utils9PubStructV6pubVarSivg : $@convention(method) (@in_guaranteed PubStruct) -> Int
// CHECK-BYPASS: struct_element_addr {{.*}} : $*PubStruct, #PubStruct.pubVar
// CHECK-ACCESS: function_ref @$s5Utils9PubStructV6pubVarSivg
// CHECK-NONRES: struct_extract {{.*}} : $PubStruct, #PubStruct.pubVar
54 changes: 54 additions & 0 deletions test/SILGen/package_global_accessor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// RUN: %empty-directory(%t)
// RUN: split-file %s %t

// RUN: %target-build-swift -module-name=Lib -package-name Pkg -I%t -emit-silgen %t/Lib.swift -o %t/Lib-nonres.sil
// RUN: %FileCheck %s --check-prefix=CHECK-NONRES < %t/Lib-nonres.sil
// RUN: %target-build-swift -module-name=Lib -package-name Pkg -I%t -emit-silgen -O -wmo %t/Lib.swift | %FileCheck %s --check-prefix=CHECK-NONRES
// RUN: %target-build-swift -module-name=Lib -package-name Pkg -I%t -emit-silgen %t/Lib.swift -enable-library-evolution -o %t/Lib-res.sil
// RUN: %FileCheck %s < %t/Lib-res.sil
// RUN: %target-build-swift -module-name=Lib -package-name Pkg -I%t -emit-silgen %t/Lib.swift -enable-library-evolution -O -wmo | %FileCheck %s
// RUN: %target-build-swift -module-name=Lib -package-name Pkg -I%t -emit-silgen %t/Lib.swift -enable-library-evolution -Xfrontend -experimental-allow-non-resilient-access -Xfrontend -experimental-package-cmo -O -wmo | %FileCheck %s

// RUN: %target-build-swift -module-name=Lib -package-name Pkg -I%t -emit-module %t/Lib.swift -enable-library-evolution -Xfrontend -experimental-allow-non-resilient-access -Xfrontend -experimental-package-cmo -O -wmo -o %t/Lib.swiftmodule
// RUN: %target-build-swift -module-name=Client -package-name Pkg -I%t -emit-silgen %t/Client.swift -I %t | %FileCheck %s --check-prefix=CHECK-CLIENT

//--- Client.swift
import Lib
public func client() {
/// Should not be calling S.x.unsafeMutableAddressor when accessing resilient global var;
/// instead, should be calling the opaque getter.
// CHECK-CLIENT-NOT: s3Lib1SV1xSSvau
// CHECK-CLIENT: function_ref @$s3Lib1SV1xSSvgZ
print(S.x)
}

//--- Lib.swift
public struct S {
public static var x = "hello world"
}

// one-time initialization token for x
// CHECK-NONRES: sil_global private @$s3Lib1SV1x_Wz : $Builtin.Word
// CHECK: sil_global private @$s3Lib1SV1x_Wz : $Builtin.Word

// static S.x
// CHECK-NONRES: sil_global @$s3Lib1SV1xSSvpZ : $String
// CHECK: sil_global private @$s3Lib1SV1xSSvpZ : $String

// one-time initialization function for x
// CHECK-NONRES: sil private [global_init_once_fn] [ossa] @$s3Lib1SV1x_WZ : $@convention(c) (Builtin.RawPointer) -> () {
// CHECK: sil private [global_init_once_fn] [ossa] @$s3Lib1SV1x_WZ : $@convention(c) (Builtin.RawPointer) -> () {

// S.x.unsafeMutableAddressor
// CHECK-NONRES: sil [global_init] [ossa] @$s3Lib1SV1xSSvau : $@convention(thin) () -> Builtin.RawPointer {
// CHECK: sil hidden [global_init] [ossa] @$s3Lib1SV1xSSvau : $@convention(thin) () -> Builtin.RawPointer {
// CHECK: global_addr @$s3Lib1SV1x_Wz
// CHECK: address_to_pointer
// function_ref one-time initialization function for x
// CHECK: function_ref @$s3Lib1SV1x_WZ
// CHECK: global_addr @$s3Lib1SV1xSSvpZ
// CHECK: address_to_pointer

// static S.x.getter
// CHECK-NONRES: sil [transparent] [serialized] [ossa] @$s3Lib1SV1xSSvgZ : $@convention(method) (@thin S.Type) -> @owned String {
// CHECK: sil [ossa] @$s3Lib1SV1xSSvgZ : $@convention(method) (@thin S.Type) -> @owned String {
9 changes: 6 additions & 3 deletions test/SILOptimizer/package-cmo-inlinable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public func inUsePubStruct(_ arg: Int) -> PubStruct {
// CHECK-MAIN: sil [ossa] @$s4Main12usePubStructy3Lib0cD0VSiF : $@convention(thin) (Int) -> @out PubStruct {
public func usePubStruct(_ arg: Int) -> PubStruct {
var p = PubStruct(1)
// CHECK-MAIN: struct_element_addr {{.*}} : $*PubStruct, #PubStruct.pub
// CHECK-MAIN: function_ref @$s3Lib9PubStructVyACSicfC
// CHECK-MAIN: function_ref @$s3Lib9PubStructV3pubSivM
p.pub += arg
return p
}
Expand All @@ -58,15 +59,17 @@ package func inUseUfiPkgStruct(_ arg: Int) -> UfiPkgStruct {
// CHECK-MAIN: sil package [ossa] @$s4Main15useUfiPkgStructy3Lib0cdE0VSiF : $@convention(thin) (Int) -> @out UfiPkgStruct {
package func useUfiPkgStruct(_ arg: Int) -> UfiPkgStruct {
var p = UfiPkgStruct(1)
// CHECK-MAIN: struct_element_addr {{.*}} : $*UfiPkgStruct, #UfiPkgStruct.ufiPkg
// CHECK-MAIN: function_ref @$s3Lib12UfiPkgStructVyACSicfC
// CHECK-MAIN: function_ref @$s3Lib12UfiPkgStructV03ufiC0SivM
p.ufiPkg += arg
return p
}

// CHECK-MAIN: sil package [ossa] @$s4Main12usePkgStructy3Lib0cD0VSiF : $@convention(thin) (Int) -> @out PkgStruct {
package func usePkgStruct(_ arg: Int) -> PkgStruct {
var p = PkgStruct(1)
// CHECK-MAIN: struct_element_addr {{.*}} : $*PkgStruct, #PkgStruct.pkg
// CHECK-MAIN: function_ref @$s3Lib9PkgStructVyACSicfC
// CHECK-MAIN: function_ref @$s3Lib9PkgStructV3pkgSivM
p.pkg += arg
return p
}
Expand Down
Loading