Skip to content

Commit 29c00f6

Browse files
committed
IRGen: improve DLLStorage computation for Windows
This slightly regresses the standard library build (intentionally) while generally improving the build of dispatch, foundation, xctest. Rather than continuing to rely on the short-term hack of special casing the standard library, identify the module where the decl originates from. If the module is the current module, then assume that the symbol need not be imported (static linking does not currently work on Windows anyways). This allows for properly identifying the module where the symbol will be homed. Because we no longer special case the standard library here, a few known metadata types will be incorrectly marked as being imported rather than local. Since linked entities which have `Shared` SILLinkage should be module local, special case them to always be local. Without this the metadata access function is still marked incorrectly. With this computation we now get nearly all the cases correct. Dispatch no longer has to rely on the linker relaxing the import to a local binding. XCTest is also clean. Foundation misses the following case: - `$sSS10FoundationE19_bridgeToObjectiveCAA8NSStringCyF` The regressed cases in swiftCore are: - `$sBi64_WV` - `$sBi8_WV` - `$sBi16_WV` - `$sBi32_WV` - `$sBpWV` - `$syycWV` - `$sBoWV` - `$sBOWV` - `$sBbWV` - `$sytWV`
1 parent 3a9969c commit 29c00f6

File tree

3 files changed

+45
-19
lines changed

3 files changed

+45
-19
lines changed

include/swift/IRGen/Linking.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,8 @@ class LinkEntity {
11551155
/// Get the default LLVM type to use for forward declarations of this
11561156
/// entity.
11571157
llvm::Type *getDefaultDeclarationType(IRGenModule &IGM) const;
1158+
1159+
bool isAlwaysSharedLinkage() const;
11581160
#undef LINKENTITY_GET_FIELD
11591161
#undef LINKENTITY_SET_FIELD
11601162
};

lib/IRGen/GenDecl.cpp

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,8 +1725,8 @@ void IRGenModule::emitVTableStubs() {
17251725

17261726
static IRLinkage
17271727
getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage,
1728-
ForDefinition_t isDefinition,
1729-
bool isWeakImported) {
1728+
ForDefinition_t isDefinition, bool isWeakImported,
1729+
bool isKnownLocal = false) {
17301730
#define RESULT(LINKAGE, VISIBILITY, DLL_STORAGE) \
17311731
IRLinkage{llvm::GlobalValue::LINKAGE##Linkage, \
17321732
llvm::GlobalValue::VISIBILITY##Visibility, \
@@ -1766,7 +1766,8 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage,
17661766
case SILLinkage::Private: {
17671767
if (info.forcePublicDecls() && !isDefinition)
17681768
return getIRLinkage(info, SILLinkage::PublicExternal, isDefinition,
1769-
isWeakImported);
1769+
isWeakImported, isKnownLocal);
1770+
17701771
auto linkage = info.needLinkerToMergeDuplicateSymbols()
17711772
? llvm::GlobalValue::LinkOnceODRLinkage
17721773
: llvm::GlobalValue::InternalLinkage;
@@ -1782,7 +1783,10 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage,
17821783

17831784
auto linkage = isWeakImported ? llvm::GlobalValue::ExternalWeakLinkage
17841785
: llvm::GlobalValue::ExternalLinkage;
1785-
return {linkage, llvm::GlobalValue::DefaultVisibility, ImportedStorage};
1786+
return {linkage, llvm::GlobalValue::DefaultVisibility,
1787+
isKnownLocal
1788+
? llvm::GlobalValue::DefaultStorageClass
1789+
: ImportedStorage};
17861790
}
17871791

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

17931797
return {llvm::GlobalValue::ExternalLinkage,
1794-
llvm::GlobalValue::DefaultVisibility, ImportedStorage};
1795-
1798+
llvm::GlobalValue::DefaultVisibility,
1799+
isKnownLocal
1800+
? llvm::GlobalValue::DefaultStorageClass
1801+
: ImportedStorage};
17961802
}
17971803

17981804
llvm_unreachable("bad SIL linkage");
@@ -1807,9 +1813,15 @@ void irgen::updateLinkageForDefinition(IRGenModule &IGM,
18071813
// entire linkage computation.
18081814
UniversalLinkageInfo linkInfo(IGM);
18091815
bool weakImported = entity.isWeakImported(IGM.getSwiftModule());
1816+
1817+
bool isKnownLocal = entity.isAlwaysSharedLinkage();
1818+
if (const auto *DC = entity.getDeclContextForEmission())
1819+
if (const auto *MD = DC->getParentModule())
1820+
isKnownLocal = IGM.getSwiftModule() == MD;
1821+
18101822
auto IRL =
18111823
getIRLinkage(linkInfo, entity.getLinkage(ForDefinition),
1812-
ForDefinition, weakImported);
1824+
ForDefinition, weakImported, isKnownLocal);
18131825
ApplyIRLinkage(IRL).to(global);
18141826

18151827
// Everything externally visible is considered used in Swift.
@@ -1834,21 +1846,16 @@ LinkInfo LinkInfo::get(const UniversalLinkageInfo &linkInfo,
18341846
const LinkEntity &entity,
18351847
ForDefinition_t isDefinition) {
18361848
LinkInfo result;
1837-
// FIXME: For anything in the standard library, we assume is locally defined.
1838-
// The only two ways imported interfaces are currently created is via a shims
1839-
// interface where the ClangImporter will correctly give us the proper DLL
1840-
// storage for the declaration. Otherwise, it is from a `@_silgen_name`
1841-
// attributed declaration, which we explicitly handle elsewhere. So, in the
1842-
// case of a standard library build, just assume everything is locally
1843-
// defined. Ideally, we would integrate the linkage calculation properly to
1844-
// avoid this special casing.
1845-
ForDefinition_t isStdlibOrDefinition =
1846-
ForDefinition_t(swiftModule->isStdlibModule() || isDefinition);
1849+
1850+
bool isKnownLocal = entity.isAlwaysSharedLinkage();
1851+
if (const auto *DC = entity.getDeclContextForEmission())
1852+
if (const auto *MD = DC->getParentModule())
1853+
isKnownLocal = MD == swiftModule;
18471854

18481855
entity.mangle(result.Name);
18491856
bool weakImported = entity.isWeakImported(swiftModule);
1850-
result.IRL = getIRLinkage(linkInfo, entity.getLinkage(isStdlibOrDefinition),
1851-
isDefinition, weakImported);
1857+
result.IRL = getIRLinkage(linkInfo, entity.getLinkage(isDefinition),
1858+
isDefinition, weakImported, isKnownLocal);
18521859
result.ForDefinition = isDefinition;
18531860
return result;
18541861
}

lib/IRGen/Linking.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,7 @@ DeclContext *LinkEntity::getDeclContextForEmission() const {
10771077
case Kind::TypeMetadataAccessFunction:
10781078
case Kind::TypeMetadataLazyCacheVariable:
10791079
case Kind::TypeMetadataDemanglingCacheVariable:
1080+
assert(isAlwaysSharedLinkage() && "kind should always be shared linkage");
10801081
return nullptr;
10811082

10821083
// TODO
@@ -1089,3 +1090,19 @@ DeclContext *LinkEntity::getDeclContextForEmission() const {
10891090
return nullptr;
10901091
}
10911092
}
1093+
1094+
bool LinkEntity::isAlwaysSharedLinkage() const {
1095+
switch (getKind()) {
1096+
case Kind::ModuleDescriptor:
1097+
case Kind::ExtensionDescriptor:
1098+
case Kind::AnonymousDescriptor:
1099+
case Kind::ObjCClassRef:
1100+
case Kind::TypeMetadataAccessFunction:
1101+
case Kind::TypeMetadataLazyCacheVariable:
1102+
case Kind::TypeMetadataDemanglingCacheVariable:
1103+
return true;
1104+
1105+
default:
1106+
return false;
1107+
}
1108+
}

0 commit comments

Comments
 (0)