mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
IRGen: special case the handling for the stdlib
Because the runtime is compacted into the standard library, functions which are normally imported are actually local definitions. Use module level named metadata to identify the module as being the swift standard library. Refactor the condition slightly to improve code readability. This addresses SR-7107!
This commit is contained in:
@@ -466,6 +466,31 @@ static bool isReturnedAttribute(llvm::Attribute::AttrKind Attr) {
|
||||
return Attr == llvm::Attribute::Returned;
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool isStandardLibrary(const llvm::Module &M) {
|
||||
if (auto *Flags = M.getNamedMetadata("swift.module.flags")) {
|
||||
for (const auto *F : Flags->operands()) {
|
||||
const auto *Key = dyn_cast_or_null<llvm::MDString>(F->getOperand(0));
|
||||
if (!Key)
|
||||
continue;
|
||||
|
||||
const auto *Value =
|
||||
dyn_cast_or_null<llvm::ConstantAsMetadata>(F->getOperand(1));
|
||||
if (!Value)
|
||||
continue;
|
||||
|
||||
if (Key->getString() == "standard-library")
|
||||
return cast<llvm::ConstantInt>(Value->getValue())->isOne();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IRGenModule::isStandardLibrary() const {
|
||||
return ::isStandardLibrary(Module);
|
||||
}
|
||||
|
||||
llvm::Constant *swift::getRuntimeFn(llvm::Module &Module,
|
||||
llvm::Constant *&cache,
|
||||
const char *name,
|
||||
@@ -493,10 +518,13 @@ llvm::Constant *swift::getRuntimeFn(llvm::Module &Module,
|
||||
if (auto fn = dyn_cast<llvm::Function>(cache)) {
|
||||
fn->setCallingConv(cc);
|
||||
|
||||
if (::useDllStorage(llvm::Triple(Module.getTargetTriple())) &&
|
||||
((fn->getLinkage() == llvm::GlobalValue::ExternalLinkage &&
|
||||
fn->isDeclaration()) ||
|
||||
fn->getLinkage() == llvm::GlobalValue::AvailableExternallyLinkage))
|
||||
bool IsExternal =
|
||||
fn->getLinkage() == llvm::GlobalValue::AvailableExternallyLinkage ||
|
||||
(fn->getLinkage() == llvm::GlobalValue::ExternalLinkage &&
|
||||
fn->isDeclaration());
|
||||
|
||||
if (!isStandardLibrary(Module) && IsExternal &&
|
||||
::useDllStorage(llvm::Triple(Module.getTargetTriple())))
|
||||
fn->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
|
||||
|
||||
llvm::AttrBuilder buildFnAttr;
|
||||
@@ -567,18 +595,16 @@ IRGenModule::createStringConstant(StringRef Str,
|
||||
return { global, address };
|
||||
}
|
||||
|
||||
#define KNOWN_METADATA_ACCESSOR(NAME, SYM) \
|
||||
llvm::Constant *IRGenModule::get##NAME() { \
|
||||
if (NAME) \
|
||||
return NAME; \
|
||||
NAME = Module.getOrInsertGlobal( \
|
||||
SYM, \
|
||||
FullTypeMetadataStructTy); \
|
||||
if (useDllStorage()) \
|
||||
cast<llvm::GlobalVariable>(NAME) \
|
||||
->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); \
|
||||
return NAME; \
|
||||
}
|
||||
#define KNOWN_METADATA_ACCESSOR(NAME, SYM) \
|
||||
llvm::Constant *IRGenModule::get##NAME() { \
|
||||
if (NAME) \
|
||||
return NAME; \
|
||||
NAME = Module.getOrInsertGlobal(SYM, FullTypeMetadataStructTy); \
|
||||
if (useDllStorage() && !isStandardLibrary()) \
|
||||
cast<llvm::GlobalVariable>(NAME)->setDLLStorageClass( \
|
||||
llvm::GlobalValue::DLLImportStorageClass); \
|
||||
return NAME; \
|
||||
}
|
||||
|
||||
KNOWN_METADATA_ACCESSOR(EmptyTupleMetadata,
|
||||
MANGLE_AS_STRING(METADATA_SYM(EMPTY_TUPLE_MANGLING)))
|
||||
|
||||
Reference in New Issue
Block a user