Skip to content

Commit

Permalink
Merge pull request swiftlang#28072 from slavapestov/global-opt-resili…
Browse files Browse the repository at this point in the history
…ence-fix

SILOptimizer: Don't optimize initializers for dynamically-sized globals
  • Loading branch information
slavapestov authored Nov 8, 2019
2 parents 4d4ee03 + a86f174 commit 8280527
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
9 changes: 9 additions & 0 deletions lib/IRGen/IRGenSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5640,6 +5640,15 @@ void IRGenModule::emitSILStaticInitializers() {
if (!InitValue)
continue;

#ifndef NDEBUG
SILType loweredTy = Global.getLoweredType();
auto &ti = getTypeInfo(loweredTy);

auto expansion = getResilienceExpansionForLayout(&Global);
assert(ti.isFixedSize(expansion) &&
"cannot emit a static initializer for dynamically-sized global");
#endif

auto *IRGlobal =
Module.getGlobalVariable(Global.getName(), true /* = AllowLocal */);

Expand Down
8 changes: 8 additions & 0 deletions lib/SILOptimizer/IPO/GlobalOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,14 @@ void SILGlobalOpt::optimizeInitializer(SILFunction *AddrF,
if (!SILG)
return;

auto expansion = ResilienceExpansion::Maximal;
if (hasPublicVisibility(SILG->getLinkage()))
expansion = ResilienceExpansion::Minimal;

auto &tl = Module->Types.getTypeLowering(SILG->getLoweredType(), expansion);
if (!tl.isLoadable())
return;

LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: use static initializer for "
<< SILG->getName() << '\n');

Expand Down
27 changes: 27 additions & 0 deletions test/SILOptimizer/globalopt_resilience_testing.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// RUN: %target-swift-frontend -emit-sil -O -enable-library-evolution -primary-file %s | %FileCheck %s
// RUN: %target-swift-frontend -emit-sil -O -enable-library-evolution -enable-testing -primary-file %s | %FileCheck %s --check-prefix=CHECK-TESTING

// If a global variable with a resilient type has public linkage, we have to
// allocate a buffer for it even if the type has a fixed size in its
// defining module.
//
// There are two cases where this can occur:
//
// - An internal property is defined in a resilient module built with
// -enable-testing
//
// - A public property is defined to have the @_fixed_layout attribute

public struct Wrapper {
var x: Int32

static let usefulConstant = Wrapper(x: 321)
}

// CHECK-LABEL: sil_global hidden [let] @$s28globalopt_resilience_testing7WrapperV14usefulConstantACvpZ : $Wrapper = {
// CHECK-NEXT: %0 = integer_literal $Builtin.Int32, 321
// CHECK-NEXT: %1 = struct $Int32 (%0 : $Builtin.Int32)
// CHECK-NEXT: %initval = struct $Wrapper (%1 : $Int32)
// CHECK-NEXT: }

// CHECK-TESTING-LABEL: sil_global [let] @$s28globalopt_resilience_testing7WrapperV14usefulConstantACvpZ : $Wrapper{{$}}

0 comments on commit 8280527

Please sign in to comment.