Skip to content

Commit 51fe191

Browse files
authored
Merge pull request swiftlang#28074 from slavapestov/global-opt-resilience-fix-5.1
SILOptimizer: Don't optimize initializers for dynamically-sized globals [5.1]
2 parents 50a0403 + 11d92e9 commit 51fe191

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

lib/IRGen/IRGenSIL.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5580,6 +5580,15 @@ void IRGenModule::emitSILStaticInitializers() {
55805580
if (!InitValue)
55815581
continue;
55825582

5583+
#ifndef NDEBUG
5584+
SILType loweredTy = Global.getLoweredType();
5585+
auto &ti = getTypeInfo(loweredTy);
5586+
5587+
auto expansion = getResilienceExpansionForLayout(&Global);
5588+
assert(ti.isFixedSize(expansion) &&
5589+
"cannot emit a static initializer for dynamically-sized global");
5590+
#endif
5591+
55835592
auto *IRGlobal =
55845593
Module.getGlobalVariable(Global.getName(), true /* = AllowLocal */);
55855594

lib/SILOptimizer/IPO/GlobalOpt.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,14 @@ void SILGlobalOpt::optimizeInitializer(SILFunction *AddrF,
739739
if (!SILG)
740740
return;
741741

742+
auto expansion = ResilienceExpansion::Maximal;
743+
if (hasPublicVisibility(SILG->getLinkage()))
744+
expansion = ResilienceExpansion::Minimal;
745+
746+
auto &tl = Module->Types.getTypeLowering(SILG->getLoweredType(), expansion);
747+
if (!tl.isLoadable())
748+
return;
749+
742750
LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: use static initializer for "
743751
<< SILG->getName() << '\n');
744752

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %target-swift-frontend -emit-sil -O -enable-library-evolution -primary-file %s | %FileCheck %s
2+
// RUN: %target-swift-frontend -emit-sil -O -enable-library-evolution -enable-testing -primary-file %s | %FileCheck %s --check-prefix=CHECK-TESTING
3+
4+
// If a global variable with a resilient type has public linkage, we have to
5+
// allocate a buffer for it even if the type has a fixed size in its
6+
// defining module.
7+
//
8+
// There are two cases where this can occur:
9+
//
10+
// - An internal property is defined in a resilient module built with
11+
// -enable-testing
12+
//
13+
// - A public property is defined to have the @_fixed_layout attribute
14+
15+
public struct Wrapper {
16+
var x: Int32
17+
18+
static let usefulConstant = Wrapper(x: 321)
19+
}
20+
21+
// CHECK-LABEL: sil_global hidden [let] @$s28globalopt_resilience_testing7WrapperV14usefulConstantACvpZ : $Wrapper = {
22+
// CHECK-NEXT: %0 = integer_literal $Builtin.Int32, 321
23+
// CHECK-NEXT: %1 = struct $Int32 (%0 : $Builtin.Int32)
24+
// CHECK-NEXT: %initval = struct $Wrapper (%1 : $Int32)
25+
// CHECK-NEXT: }
26+
27+
// CHECK-TESTING-LABEL: sil_global [let] @$s28globalopt_resilience_testing7WrapperV14usefulConstantACvpZ : $Wrapper{{$}}

0 commit comments

Comments
 (0)