Skip to content

IRGen: internalize symbols with -static #41431

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
Feb 21, 2022
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
5 changes: 4 additions & 1 deletion include/swift/AST/IRGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,9 @@ class IRGenOptions {

unsigned InternalizeAtLink : 1;

/// Internalize symbols (static library) - do not export any public symbols.
unsigned InternalizeSymbols : 1;

/// Whether to avoid emitting zerofill globals as preallocated type metadata
/// and prototol conformance caches.
unsigned NoPreallocatedInstantiationCaches : 1;
Expand Down Expand Up @@ -443,7 +446,7 @@ class IRGenOptions {
DisableStandardSubstitutionsInReflectionMangling(false),
EnableGlobalISel(false), VirtualFunctionElimination(false),
WitnessMethodElimination(false), ConditionalRuntimeRecords(false),
InternalizeAtLink(false),
InternalizeAtLink(false), InternalizeSymbols(false),
NoPreallocatedInstantiationCaches(false),
CmdArgs(),
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
Expand Down
3 changes: 2 additions & 1 deletion include/swift/IRGen/Linking.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class UniversalLinkageInfo {
public:
bool IsELFObject;
bool UseDLLStorage;
bool Internalize;

/// True iff are multiple llvm modules.
bool HasMultipleIGMs;
Expand All @@ -57,7 +58,7 @@ class UniversalLinkageInfo {
explicit UniversalLinkageInfo(IRGenModule &IGM);

UniversalLinkageInfo(const llvm::Triple &triple, bool hasMultipleIGMs,
bool forcePublicDecls);
bool forcePublicDecls, bool isStaticLibrary);

/// In case of multiple llvm modules (in multi-threaded compilation) all
/// private decls must be visible from other files.
Expand Down
2 changes: 2 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2190,6 +2190,8 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
Opts.InternalizeAtLink = true;
}

Opts.InternalizeSymbols = FrontendOpts.Static;

if (Args.hasArg(OPT_disable_preallocated_instantiation_caches)) {
Opts.NoPreallocatedInstantiationCaches = true;
}
Expand Down
7 changes: 5 additions & 2 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2020,7 +2020,9 @@ void IRGenModule::emitVTableStubs() {
if (F.getEffectiveSymbolLinkage() == SILLinkage::Hidden)
alias->setVisibility(llvm::GlobalValue::HiddenVisibility);
else
ApplyIRLinkage(IRLinkage::ExternalExport).to(alias);
ApplyIRLinkage(IRGen.Opts.InternalizeSymbols
? IRLinkage::Internal
: IRLinkage::ExternalExport).to(alias);
}
}

Expand Down Expand Up @@ -2090,7 +2092,8 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage,
switch (linkage) {
case SILLinkage::Public:
return {llvm::GlobalValue::ExternalLinkage, PublicDefinitionVisibility,
ExportedStorage};
info.Internalize ? llvm::GlobalValue::DefaultStorageClass
: ExportedStorage};

case SILLinkage::PublicNonABI:
return isDefinition ? RESULT(WeakODR, Hidden, Default)
Expand Down
4 changes: 3 additions & 1 deletion lib/IRGen/GenKeyPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1352,7 +1352,9 @@ void IRGenModule::emitSILProperty(SILProperty *prop) {
TheTrivialPropertyDescriptor);
ApplyIRLinkage({linkInfo.getLinkage(),
linkInfo.getVisibility(),
llvm::GlobalValue::DLLExportStorageClass})
IRGen.Opts.InternalizeSymbols
? llvm::GlobalValue::DefaultStorageClass
: llvm::GlobalValue::DLLExportStorageClass})
.to(GA, linkInfo.isForDefinition());
}
return;
Expand Down
4 changes: 3 additions & 1 deletion lib/IRGen/IRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1574,7 +1574,9 @@ static llvm::GlobalObject *createForceImportThunk(IRGenModule &IGM) {
llvm::GlobalValue::LinkOnceODRLinkage, buf,
&IGM.Module);
ForceImportThunk->setAttributes(IGM.constructInitialAttributes());
ApplyIRLinkage(IRLinkage::ExternalExport).to(ForceImportThunk);
ApplyIRLinkage(IGM.IRGen.Opts.InternalizeSymbols
? IRLinkage::Internal
: IRLinkage::ExternalExport).to(ForceImportThunk);
if (IGM.Triple.supportsCOMDAT())
if (auto *GO = cast<llvm::GlobalObject>(ForceImportThunk))
GO->setComdat(IGM.Module.getOrInsertComdat(ForceImportThunk->getName()));
Expand Down
8 changes: 5 additions & 3 deletions lib/IRGen/Linking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,16 @@ bool swift::irgen::useDllStorage(const llvm::Triple &triple) {

UniversalLinkageInfo::UniversalLinkageInfo(IRGenModule &IGM)
: UniversalLinkageInfo(IGM.Triple, IGM.IRGen.hasMultipleIGMs(),
IGM.IRGen.Opts.ForcePublicLinkage) {}
IGM.IRGen.Opts.ForcePublicLinkage,
IGM.IRGen.Opts.InternalizeSymbols) {}

UniversalLinkageInfo::UniversalLinkageInfo(const llvm::Triple &triple,
bool hasMultipleIGMs,
bool forcePublicDecls)
bool forcePublicDecls,
bool isStaticLibrary)
: IsELFObject(triple.isOSBinFormatELF()),
UseDLLStorage(useDllStorage(triple)), HasMultipleIGMs(hasMultipleIGMs),
ForcePublicDecls(forcePublicDecls) {}
Internalize(isStaticLibrary), ForcePublicDecls(forcePublicDecls) {}

/// Mangle this entity into the given buffer.
void LinkEntity::mangle(SmallVectorImpl<char> &buffer) const {
Expand Down
3 changes: 2 additions & 1 deletion lib/TBDGen/TBDGenVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,8 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
ModuleDecl *swiftModule, const TBDGenOptions &opts,
APIRecorder &recorder)
: DataLayoutDescription(dataLayoutString),
UniversalLinkInfo(target, opts.HasMultipleIGMs, /*forcePublic*/ false),
UniversalLinkInfo(target, opts.HasMultipleIGMs, /*forcePublic*/ false,
/*static=*/false),
SwiftModule(swiftModule), Opts(opts), recorder(recorder),
previousInstallNameMap(parsePreviousModuleInstallNameMap()) {}

Expand Down
76 changes: 76 additions & 0 deletions test/IRGen/static-library.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// RUN: %empty-directory(%t)
// RUN: %swiftc_driver_plain -target x86_64-unknown-windows-msvc -DLIBRARY -module-name Library -emit-library -static -autolink-force-load -module-link-name Library %s -o %t/library.lib -emit-module-path %t
// RUN: %swiftc_driver_plain -target x86_64-unknown-windows-msvc -DLIBRARY -module-name Library -emit-library -static -autolink-force-load -module-link-name Library %s -S -emit-ir -o - | %FileCheck -check-prefix CHECK-LIBRARY %s
// RUN: %swiftc_driver_plain -target x86_64-unknown-windows-msvc -I %t -emit-library -S -emit-ir -o - %s | %FileCheck -check-prefix CHECK-EMBEDDING %s

// REQUIRES: OS=windows-msvc

#if LIBRARY

// nominal type descriptor for Library.C
// CHECK-LIBRARY: @"$s7Library1CCMn" = constant

// nominal type descriptor for Library.S
// CHECK-LIBRARY: @"$s7Library1SVMn" = constant

// method descriptor for Library.C.method
// CHECK-LBRARY: @"$s7Library1CC6methodyyFTq" = alias

// type metadata for Library.C
// CHECK-LIBRARY: @"$s7Library1CCN" = alias

// type metadata for Library.S
// CHECK-LIBRARY: @"$s7Library1SVN" = alias

public func f() {
}

// Library.f() -> ()
// CHECK-LIBRARY: define swiftcc void @"$s7Library1fyyF"()

open class C {
var property: () -> () {
return f
}

open func method() {
}
}

// Library.C.method() -> ()
// CHECK-LIBRARY: define swiftcc void @"$s7Library1CC6methodyyF"(%T7Library1CC* swiftself %0)

// Library.C.deinit
// CHECK-LIBRARY: define swiftcc %swift.refcounted* @"$s7Library1CCfd"(%T7Library1CC* swiftself %0)

// Library.C.__deallocating_deinit
// CHECK-LIBRARY: define swiftcc void @"$s7Library1CCfD"(%T7Library1CC* swiftself %0)

// Library.C.__allocating_init() -> Library.C
// CHECK-LIBRARY: define swiftcc %T7Library1CC* @"$s7Library1CCACycfC"(%swift.type* swiftself %0)

public struct S {
var member: () -> Void = f
}

// variable initialization expression of Library.S.member : () -> ()
// CHECK-LIBRARY: define swiftcc { i8*, %swift.refcounted* } @"$s7Library1SV6memberyycvpfi"()

// type metadata accessor for Library.C
// CHECK-LIBRARY: define swiftcc %swift.metadata_response @"$s7Library1CCMa"(i64 %0)

// type metadata accessor for Library.S
// CHECK-LIBRARY: define swiftcc %swift.metadata_response @"$s7Library1SVMa"(i64 %0)

// CHECK-LIBRARY: define internal void @"_swift_FORCE_LOAD_$_Library"()

#else
import Library
func f() {
Library.f()
}

// CHECK-EMBEDDING-NOT: @"_swift_FORCE_LOAD_$_Library"

#endif