Skip to content

IRGen: improve DLLStorage computation for Windows #30292

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
Mar 10, 2020
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
2 changes: 2 additions & 0 deletions include/swift/IRGen/Linking.h
Original file line number Diff line number Diff line change
Expand Up @@ -1155,6 +1155,8 @@ class LinkEntity {
/// Get the default LLVM type to use for forward declarations of this
/// entity.
llvm::Type *getDefaultDeclarationType(IRGenModule &IGM) const;

bool isAlwaysSharedLinkage() const;
#undef LINKENTITY_GET_FIELD
#undef LINKENTITY_SET_FIELD
};
Expand Down
45 changes: 26 additions & 19 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1725,8 +1725,8 @@ void IRGenModule::emitVTableStubs() {

static IRLinkage
getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage,
ForDefinition_t isDefinition,
bool isWeakImported) {
ForDefinition_t isDefinition, bool isWeakImported,
bool isKnownLocal = false) {
#define RESULT(LINKAGE, VISIBILITY, DLL_STORAGE) \
IRLinkage{llvm::GlobalValue::LINKAGE##Linkage, \
llvm::GlobalValue::VISIBILITY##Visibility, \
Expand Down Expand Up @@ -1766,7 +1766,8 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage,
case SILLinkage::Private: {
if (info.forcePublicDecls() && !isDefinition)
return getIRLinkage(info, SILLinkage::PublicExternal, isDefinition,
isWeakImported);
isWeakImported, isKnownLocal);

auto linkage = info.needLinkerToMergeDuplicateSymbols()
? llvm::GlobalValue::LinkOnceODRLinkage
: llvm::GlobalValue::InternalLinkage;
Expand All @@ -1782,7 +1783,10 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage,

auto linkage = isWeakImported ? llvm::GlobalValue::ExternalWeakLinkage
: llvm::GlobalValue::ExternalLinkage;
return {linkage, llvm::GlobalValue::DefaultVisibility, ImportedStorage};
return {linkage, llvm::GlobalValue::DefaultVisibility,
isKnownLocal
? llvm::GlobalValue::DefaultStorageClass
: ImportedStorage};
}

case SILLinkage::HiddenExternal:
Expand All @@ -1791,8 +1795,10 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage,
return RESULT(AvailableExternally, Hidden, Default);

return {llvm::GlobalValue::ExternalLinkage,
llvm::GlobalValue::DefaultVisibility, ImportedStorage};

llvm::GlobalValue::DefaultVisibility,
isKnownLocal
? llvm::GlobalValue::DefaultStorageClass
: ImportedStorage};
}

llvm_unreachable("bad SIL linkage");
Expand All @@ -1807,9 +1813,15 @@ void irgen::updateLinkageForDefinition(IRGenModule &IGM,
// entire linkage computation.
UniversalLinkageInfo linkInfo(IGM);
bool weakImported = entity.isWeakImported(IGM.getSwiftModule());

bool isKnownLocal = entity.isAlwaysSharedLinkage();
if (const auto *DC = entity.getDeclContextForEmission())
if (const auto *MD = DC->getParentModule())
isKnownLocal = IGM.getSwiftModule() == MD;

auto IRL =
getIRLinkage(linkInfo, entity.getLinkage(ForDefinition),
ForDefinition, weakImported);
ForDefinition, weakImported, isKnownLocal);
ApplyIRLinkage(IRL).to(global);

// Everything externally visible is considered used in Swift.
Expand All @@ -1834,21 +1846,16 @@ LinkInfo LinkInfo::get(const UniversalLinkageInfo &linkInfo,
const LinkEntity &entity,
ForDefinition_t isDefinition) {
LinkInfo result;
// FIXME: For anything in the standard library, we assume is locally defined.
// The only two ways imported interfaces are currently created is via a shims
// interface where the ClangImporter will correctly give us the proper DLL
// storage for the declaration. Otherwise, it is from a `@_silgen_name`
// attributed declaration, which we explicitly handle elsewhere. So, in the
// case of a standard library build, just assume everything is locally
// defined. Ideally, we would integrate the linkage calculation properly to
// avoid this special casing.
ForDefinition_t isStdlibOrDefinition =
ForDefinition_t(swiftModule->isStdlibModule() || isDefinition);

bool isKnownLocal = entity.isAlwaysSharedLinkage();
if (const auto *DC = entity.getDeclContextForEmission())
if (const auto *MD = DC->getParentModule())
isKnownLocal = MD == swiftModule;

entity.mangle(result.Name);
bool weakImported = entity.isWeakImported(swiftModule);
result.IRL = getIRLinkage(linkInfo, entity.getLinkage(isStdlibOrDefinition),
isDefinition, weakImported);
result.IRL = getIRLinkage(linkInfo, entity.getLinkage(isDefinition),
isDefinition, weakImported, isKnownLocal);
result.ForDefinition = isDefinition;
return result;
}
Expand Down
17 changes: 17 additions & 0 deletions lib/IRGen/Linking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,7 @@ DeclContext *LinkEntity::getDeclContextForEmission() const {
case Kind::TypeMetadataAccessFunction:
case Kind::TypeMetadataLazyCacheVariable:
case Kind::TypeMetadataDemanglingCacheVariable:
assert(isAlwaysSharedLinkage() && "kind should always be shared linkage");
return nullptr;

// TODO
Expand All @@ -1089,3 +1090,19 @@ DeclContext *LinkEntity::getDeclContextForEmission() const {
return nullptr;
}
}

bool LinkEntity::isAlwaysSharedLinkage() const {
switch (getKind()) {
case Kind::ModuleDescriptor:
case Kind::ExtensionDescriptor:
case Kind::AnonymousDescriptor:
case Kind::ObjCClassRef:
case Kind::TypeMetadataAccessFunction:
case Kind::TypeMetadataLazyCacheVariable:
case Kind::TypeMetadataDemanglingCacheVariable:
return true;

default:
return false;
}
}