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:
Saleem Abdulrasool
2018-04-26 21:09:07 -07:00
parent 7324046d02
commit 283c00e41e
5 changed files with 90 additions and 36 deletions

View File

@@ -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)))