Skip to content

Commit

Permalink
Merge pull request swiftlang#16142 from compnerd/irgen-dllstorage
Browse files Browse the repository at this point in the history
IRGen: the runtime is compacted into the stdlib
  • Loading branch information
compnerd authored May 30, 2018
2 parents 4b037e2 + 283c00e commit 477d43e
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 41 deletions.
22 changes: 20 additions & 2 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1850,11 +1850,21 @@ LinkInfo LinkInfo::get(const UniversalLinkageInfo &linkInfo,
ModuleDecl *swiftModule, 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);

entity.mangle(result.Name);
std::tie(result.Linkage, result.Visibility, result.DLLStorageClass) =
getIRLinkage(linkInfo, entity.getLinkage(isDefinition), isDefinition,
entity.isWeakImported(swiftModule));
getIRLinkage(linkInfo, entity.getLinkage(isStdlibOrDefinition),
isDefinition, entity.isWeakImported(swiftModule));
result.ForDefinition = isDefinition;
return result;
}
Expand Down Expand Up @@ -2333,6 +2343,14 @@ llvm::Function *IRGenModule::getAddrOfSILFunction(SILFunction *f,
fn = createFunction(*this, link, signature, insertBefore,
f->getOptimizationMode());

// If `hasCReferences` is true, then the function is either marked with
// @_silgen_name OR @_cdecl. If it is the latter, it must have a definition
// associated with it. The combination of the two allows us to identify the
// @_silgen_name functions. These are locally defined function thunks used in
// the standard library. Do not give them DLLImport DLL Storage.
if (useDllStorage() && f->hasCReferences() && !forDefinition)
fn->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);

// If we have an order number for this function, set it up as appropriate.
if (hasOrderNumber) {
EmittedFunctionsByOrder.insert(orderNumber, fn);
Expand Down
19 changes: 14 additions & 5 deletions lib/IRGen/IRGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,14 +660,23 @@ static void embedBitcode(llvm::Module *M, const IRGenOptions &Opts)
NewUsed->setSection("llvm.metadata");
}

static void initLLVMModule(const IRGenModule &IGM) {
static void initLLVMModule(const IRGenModule &IGM, ModuleDecl &M) {
auto *Module = IGM.getModule();
assert(Module && "Expected llvm:Module for IR generation!");

Module->setTargetTriple(IGM.Triple.str());

// Set the module's string representation.
Module->setDataLayout(IGM.DataLayout.getStringRepresentation());

auto *MDNode = IGM.getModule()->getOrInsertNamedMetadata("swift.module.flags");
auto &Context = IGM.getModule()->getContext();
auto *Value = M.isStdlibModule() ? llvm::ConstantInt::getTrue(Context)
: llvm::ConstantInt::getFalse(Context);
MDNode->addOperand(llvm::MDTuple::get(Context,
{llvm::MDString::get(Context,
"standard-library"),
llvm::ConstantAsMetadata::get(Value)}));
}

std::pair<IRGenerator *, IRGenModule *>
Expand All @@ -686,7 +695,7 @@ swift::irgen::createIRGenModule(SILModule *SILMod, StringRef OutputFilename,
new IRGenModule(*irgen, std::move(targetMachine), nullptr, LLVMContext,
"", OutputFilename, MainInputFilenameForDebugInfo);

initLLVMModule(*IGM);
initLLVMModule(*IGM, *SILMod->getSwiftModule());

return std::pair<IRGenerator *, IRGenModule *>(irgen, IGM);
}
Expand Down Expand Up @@ -741,7 +750,7 @@ static std::unique_ptr<llvm::Module> performIRGeneration(IRGenOptions &Opts,
ModuleName, PSPs.OutputFilename,
PSPs.MainInputFilenameForDebugInfo);

initLLVMModule(IGM);
initLLVMModule(IGM, *SILMod->getSwiftModule());

// Run SIL level IRGen preparation passes.
runIRGenPreparePasses(*SILMod, IGM);
Expand Down Expand Up @@ -907,7 +916,7 @@ static void performParallelIRGeneration(
ModuleName, *OutputIter++, nextSF->getFilename());
IGMcreated = true;

initLLVMModule(*IGM);
initLLVMModule(*IGM, *SILMod->getSwiftModule());
if (!DidRunSILCodeGenPreparePasses) {
// Run SIL level IRGen preparation passes on the module the first time
// around.
Expand Down Expand Up @@ -1097,7 +1106,7 @@ swift::createSwiftModuleObjectFile(SILModule &SILMod, StringRef Buffer,

IRGenModule IGM(irgen, std::move(targetMachine), nullptr, VMContext,
OutputPath, OutputPath, "");
initLLVMModule(IGM);
initLLVMModule(IGM, *SILMod.getSwiftModule());
auto *Ty = llvm::ArrayType::get(IGM.Int8Ty, Buffer.size());
auto *Data =
llvm::ConstantDataArray::getString(VMContext, Buffer, /*AddNull=*/false);
Expand Down
58 changes: 42 additions & 16 deletions lib/IRGen/IRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)))
Expand Down
2 changes: 2 additions & 0 deletions lib/IRGen/IRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,8 @@ class IRGenModule {
llvm::Module *releaseModule();
llvm::AttributeList getAllocAttrs();

bool isStandardLibrary() const;

private:
llvm::Constant *EmptyTupleMetadata = nullptr;
llvm::Constant *AnyExistentialMetadata = nullptr;
Expand Down
3 changes: 2 additions & 1 deletion lib/IRGen/MetadataRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,9 +432,10 @@ llvm::Constant *irgen::tryEmitConstantHeapMetadataRef(IRGenModule &IGM,
ConstantReference
irgen::tryEmitConstantTypeMetadataRef(IRGenModule &IGM, CanType type,
SymbolReferenceKind refKind) {
if (IGM.isStandardLibrary())
return ConstantReference();
if (!isTypeMetadataAccessTrivial(IGM, type))
return ConstantReference();

return IGM.getAddrOfTypeMetadata(type, refKind);
}

Expand Down
41 changes: 24 additions & 17 deletions stdlib/public/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -254,20 +254,27 @@ if(SWIFT_BUILD_STATIC_STDLIB AND "${SWIFT_HOST_VARIANT_SDK}" STREQUAL "LINUX")
list(APPEND swift_core_private_link_libraries swiftImageInspectionShared)
endif()

add_swift_library(swiftCore ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB IS_STDLIB_CORE
${SWIFTLIB_SOURCES}
# The copy_shim_headers target dependency is required to let the
# build system know that there's a rule to produce the shims
# directory, but is not sufficient to cause the object file to be rebuilt
# when the shim header changes. Therefore, we pass both the target
# and the generated directory as dependencies.
FILE_DEPENDS
copy_shim_headers "${SWIFTLIB_DIR}/shims"
${GROUP_INFO_JSON_FILE}
SWIFT_COMPILE_FLAGS ${swift_stdlib_compile_flags}
LINK_FLAGS ${swift_core_link_flags}
PRIVATE_LINK_LIBRARIES ${swift_core_private_link_libraries}
INCORPORATE_OBJECT_LIBRARIES swiftRuntime swiftStdlibStubs
INCORPORATE_OBJECT_LIBRARIES_SHARED_ONLY ${shared_only_libs}
FRAMEWORK_DEPENDS ${swift_core_framework_depends}
INSTALL_IN_COMPONENT stdlib)
add_swift_library(swiftCore
${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB IS_STDLIB_CORE
${SWIFTLIB_SOURCES}
# The copy_shim_headers target dependency is required to let the
# build system know that there's a rule to produce the shims
# directory, but is not sufficient to cause the object file to be rebuilt
# when the shim header changes. Therefore, we pass both the target
# and the generated directory as dependencies.
FILE_DEPENDS
copy_shim_headers "${SWIFTLIB_DIR}/shims" ${GROUP_INFO_JSON_FILE}
SWIFT_COMPILE_FLAGS
${swift_stdlib_compile_flags} -Xcc -DswiftCore_EXPORTS
LINK_FLAGS
${swift_core_link_flags}
PRIVATE_LINK_LIBRARIES
${swift_core_private_link_libraries}
INCORPORATE_OBJECT_LIBRARIES
swiftRuntime swiftStdlibStubs
INCORPORATE_OBJECT_LIBRARIES_SHARED_ONLY
${shared_only_libs}
FRAMEWORK_DEPENDS
${swift_core_framework_depends}
INSTALL_IN_COMPONENT
stdlib)

0 comments on commit 477d43e

Please sign in to comment.