From b8dd577693b2cc091a205d8fe27d58e79bc51e7e Mon Sep 17 00:00:00 2001 From: Han Sangjin Date: Sat, 13 Aug 2016 06:56:57 +0900 Subject: [PATCH] [swiftc] Fixed for Cygwin Fixed for the difference of Cygwin with other Windows variants (MSVC, Itanium, MinGW). - The platform name is renamed to "cygwin" from "windows" which is used for searching the standard libraries. - The consideration for DLL storage class (DllExport/DllImport) is not required for Cygwin and MinGW. There is no problem when linking in these environment. - Cygwin should use large memory model as default.(This may be changed if someone ports to 32bit) - Cygwin and MinGW should use the autolink feature in the sameway of Linux due to the linker's limit. --- CMakeLists.txt | 6 ++--- include/swift/Runtime/Concurrent.h | 2 +- lib/Basic/Platform.cpp | 12 +++++++++- lib/IRGen/GenDecl.cpp | 12 +++++----- lib/IRGen/GenFunc.cpp | 2 +- lib/IRGen/GenMeta.cpp | 2 +- lib/IRGen/IRGen.cpp | 11 +++++---- lib/IRGen/IRGenModule.cpp | 32 +++++++++++++++++---------- lib/IRGen/IRGenModule.h | 2 ++ lib/IRGen/TypeLayoutVerifier.cpp | 2 +- lib/LLVMPasses/ARCEntryPointBuilder.h | 3 ++- test/IRGen/autolink-coff-x86.swift | 18 +++++++++++++++ test/IRGen/autolink-coff.swift | 11 --------- utils/build-script-impl | 2 +- 14 files changed, 74 insertions(+), 43 deletions(-) create mode 100644 test/IRGen/autolink-coff-x86.swift diff --git a/CMakeLists.txt b/CMakeLists.txt index 70823a5515776..b06bc4c803e40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -589,10 +589,10 @@ elseif("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "FREEBSD") elseif("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "CYGWIN") # set(CMAKE_EXECUTABLE_FORMAT "ELF") - set(SWIFT_HOST_VARIANT "windows" CACHE STRING - "Deployment OS for Swift host tools (the compiler) [windows].") + set(SWIFT_HOST_VARIANT "cygwin" CACHE STRING + "Deployment OS for Swift host tools (the compiler) [cygwin].") - configure_sdk_unix(CYGWIN "Cygwin" "windows" "cygwin" "windows" "x86_64-unknown-windows-cygnus" "/") + configure_sdk_unix(CYGWIN "Cygwin" "cygwin" "cygwin" "x86_64" "x86_64-unknown-windows-cygnus" "/") set(SWIFT_PRIMARY_VARIANT_SDK_default "${SWIFT_HOST_VARIANT_SDK}") set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64") diff --git a/include/swift/Runtime/Concurrent.h b/include/swift/Runtime/Concurrent.h index fe369dd622721..48e37ab40fd59 100644 --- a/include/swift/Runtime/Concurrent.h +++ b/include/swift/Runtime/Concurrent.h @@ -17,7 +17,7 @@ #include #include "llvm/Support/Allocator.h" -#if defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(__CYGWIN__) #include #endif diff --git a/lib/Basic/Platform.cpp b/lib/Basic/Platform.cpp index f39cbe37fbb55..c30d6b86bf96d 100644 --- a/lib/Basic/Platform.cpp +++ b/lib/Basic/Platform.cpp @@ -119,7 +119,17 @@ StringRef swift::getPlatformNameForTriple(const llvm::Triple &triple) { case llvm::Triple::FreeBSD: return "freebsd"; case llvm::Triple::Win32: - return "windows"; + switch (triple.getEnvironment()) { + case llvm::Triple::Cygnus: + return "cygwin"; + case llvm::Triple::GNU: + return "mingw"; + case llvm::Triple::MSVC: + case llvm::Triple::Itanium: + return "windows"; + default: + llvm_unreachable("unsupported Windows environment"); + } case llvm::Triple::PS4: return "ps4"; } diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index 2d30b1afa0194..394b830ecea64 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -937,7 +937,7 @@ void IRGenModule::emitVTableStubs() { // For each eliminated method symbol create an alias to the stub. auto *alias = llvm::GlobalAlias::create(llvm::GlobalValue::ExternalLinkage, F.getName(), stub); - if (Triple.isOSBinFormatCOFF()) + if (useDllStorage()) alias->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); } } @@ -1260,7 +1260,7 @@ getIRLinkage(IRGenModule &IGM, SILLinkage linkage, bool isFragile, const auto ObjFormat = IGM.TargetInfo.OutputObjectFormat; bool IsELFObject = ObjFormat == llvm::Triple::ELF; - bool IsCOFFObject = ObjFormat == llvm::Triple::COFF; + bool UseDLLStorage = IGM.useDllStorage(); // Use protected visibility for public symbols we define on ELF. ld.so // doesn't support relative relocations at load time, which interferes with @@ -1270,11 +1270,11 @@ getIRLinkage(IRGenModule &IGM, SILLinkage linkage, bool isFragile, IsELFObject ? llvm::GlobalValue::ProtectedVisibility : llvm::GlobalValue::DefaultVisibility; llvm::GlobalValue::DLLStorageClassTypes ExportedStorage = - IsCOFFObject ? llvm::GlobalValue::DLLExportStorageClass - : llvm::GlobalValue::DefaultStorageClass; + UseDLLStorage ? llvm::GlobalValue::DLLExportStorageClass + : llvm::GlobalValue::DefaultStorageClass; llvm::GlobalValue::DLLStorageClassTypes ImportedStorage = - IsCOFFObject ? llvm::GlobalValue::DLLImportStorageClass - : llvm::GlobalValue::DefaultStorageClass; + UseDLLStorage ? llvm::GlobalValue::DLLImportStorageClass + : llvm::GlobalValue::DefaultStorageClass; if (isFragile) { // Fragile functions/globals must be visible from outside, regardless of diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp index 4523a402610de..46bf437bc2580 100644 --- a/lib/IRGen/GenFunc.cpp +++ b/lib/IRGen/GenFunc.cpp @@ -1511,7 +1511,7 @@ void irgen::emitBlockHeader(IRGenFunction &IGF, auto NSConcreteStackBlock = IGF.IGM.getModule()->getOrInsertGlobal("_NSConcreteStackBlock", IGF.IGM.ObjCClassStructTy); - if (IGF.IGM.Triple.isOSBinFormatCOFF()) + if (IGF.IGM.useDllStorage()) cast(NSConcreteStackBlock) ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp index bcbc3adccd110..fb4a2273f1d1f 100644 --- a/lib/IRGen/GenMeta.cpp +++ b/lib/IRGen/GenMeta.cpp @@ -4035,7 +4035,7 @@ static void emitObjCClassSymbol(IRGenModule &IGM, metadata->getLinkage(), classSymbol.str(), metadata, IGM.getModule()); - if (IGM.TargetInfo.OutputObjectFormat == llvm::Triple::COFF) + if (IGM.useDllStorage()) alias->setDLLStorageClass(metadata->getDLLStorageClass()); } diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp index f57cc59bab9f4..b5087d90caee8 100644 --- a/lib/IRGen/IRGen.cpp +++ b/lib/IRGen/IRGen.cpp @@ -496,10 +496,13 @@ swift::createTargetMachine(IRGenOptions &Opts, ASTContext &Ctx) { } // Create a target machine. - llvm::TargetMachine *TargetMachine - = Target->createTargetMachine(Triple.str(), CPU, - targetFeatures, TargetOpts, Reloc::PIC_, - CodeModel::Default, OptLevel); + auto cmodel = CodeModel::Default; + if (Triple.isWindowsCygwinEnvironment()) + cmodel = CodeModel::Large; + + llvm::TargetMachine *TargetMachine = + Target->createTargetMachine(Triple.str(), CPU, targetFeatures, TargetOpts, + Reloc::PIC_, cmodel, OptLevel); if (!TargetMachine) { Ctx.Diags.diagnose(SourceLoc(), diag::no_llvm_target, Triple.str(), "no LLVM target machine"); diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp index 8e22a64cd4305..6d77ea50575ad 100644 --- a/lib/IRGen/IRGenModule.cpp +++ b/lib/IRGen/IRGenModule.cpp @@ -117,6 +117,11 @@ static clang::CodeGenerator *createClangCodeGenerator(ASTContext &Context, return ClangCodeGen; } +/// A helper for determining if the triple uses the DLL storage +static bool useDllStorage(const llvm::Triple &Triple) { + return Triple.isOSBinFormatCOFF() && !Triple.isOSCygMing(); +} + IRGenModule::IRGenModule(IRGenerator &irgen, std::unique_ptr &&target, SourceFile *SF, llvm::LLVMContext &LLVMContext, @@ -439,7 +444,7 @@ llvm::Constant *swift::getRuntimeFn(llvm::Module &Module, if (auto fn = dyn_cast(cache)) { fn->setCallingConv(cc); - if (llvm::Triple(Module.getTargetTriple()).isOSBinFormatCOFF() && + if (::useDllStorage(llvm::Triple(Module.getTargetTriple())) && (fn->getLinkage() == llvm::GlobalValue::ExternalLinkage || fn->getLinkage() == llvm::GlobalValue::AvailableExternallyLinkage)) fn->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); @@ -519,7 +524,7 @@ llvm::Constant *swift::getWrapperFn(llvm::Module &Module, auto *globalFnPtr = new llvm::GlobalVariable( Module, fnPtrTy, false, llvm::GlobalValue::ExternalLinkage, nullptr, symbol); - if (llvm::Triple(Module.getTargetTriple()).isOSBinFormatCOFF()) + if (::useDllStorage(llvm::Triple(Module.getTargetTriple()))) globalFnPtr->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); // Forward all arguments. @@ -638,7 +643,7 @@ llvm::Constant *IRGenModule::getEmptyTupleMetadata() { EmptyTupleMetadata = Module.getOrInsertGlobal( MANGLE_AS_STRING(METADATA_SYM(EMPTY_TUPLE_MANGLING)), FullTypeMetadataStructTy); - if (Triple.isOSBinFormatCOFF()) + if (useDllStorage()) cast(EmptyTupleMetadata) ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); return EmptyTupleMetadata; @@ -652,7 +657,7 @@ llvm::Constant *IRGenModule::getObjCEmptyCachePtr() { // struct objc_cache _objc_empty_cache; ObjCEmptyCachePtr = Module.getOrInsertGlobal("_objc_empty_cache", OpaquePtrTy->getElementType()); - if (Triple.isOSBinFormatCOFF()) + if (useDllStorage()) cast(ObjCEmptyCachePtr) ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); } else { @@ -685,7 +690,7 @@ Address IRGenModule::getAddrOfObjCISAMask() { assert(TargetInfo.hasISAMasking()); if (!ObjCISAMaskPtr) { ObjCISAMaskPtr = Module.getOrInsertGlobal("swift_isaMask", IntPtrTy); - if (Triple.isOSBinFormatCOFF()) + if (useDllStorage()) cast(ObjCISAMaskPtr) ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); } @@ -851,7 +856,7 @@ void IRGenModule::addLinkLibrary(const LinkLibrary &linkLib) { llvm::SmallString<64> buf; encodeForceLoadSymbolName(buf, linkLib.getName()); auto symbolAddr = Module.getOrInsertGlobal(buf.str(), Int1Ty); - if (Triple.isOSBinFormatCOFF()) + if (useDllStorage()) cast(symbolAddr) ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); @@ -916,9 +921,9 @@ void IRGenModule::emitAutolinkInfo() { }), AutolinkEntries.end()); - if (TargetInfo.OutputObjectFormat == llvm::Triple::COFF || - TargetInfo.OutputObjectFormat == llvm::Triple::MachO || - Triple.isPS4()) { + if ((TargetInfo.OutputObjectFormat == llvm::Triple::COFF && + !Triple.isOSCygMing()) || + TargetInfo.OutputObjectFormat == llvm::Triple::MachO || Triple.isPS4()) { llvm::LLVMContext &ctx = Module.getContext(); if (!LinkerOptions) { @@ -935,8 +940,9 @@ void IRGenModule::emitAutolinkInfo() { assert(FoundOldEntry && "Could not replace old linker options entry?"); } } else { - assert(TargetInfo.OutputObjectFormat == llvm::Triple::ELF && - "expected ELF output format"); + assert((TargetInfo.OutputObjectFormat == llvm::Triple::ELF || + Triple.isOSCygMing()) && + "expected ELF output format or COFF format for Cygwin/MinGW"); // Merge the entries into null-separated string. llvm::SmallString<64> EntriesString; @@ -969,7 +975,7 @@ void IRGenModule::emitAutolinkInfo() { llvm::GlobalValue::CommonLinkage, llvm::Constant::getNullValue(Int1Ty), buf.str()); - if (Triple.isOSBinFormatCOFF()) + if (useDllStorage()) symbol->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); } } @@ -1072,6 +1078,8 @@ void IRGenModule::error(SourceLoc loc, const Twine &message) { message.toStringRef(buffer)); } +bool IRGenModule::useDllStorage() { return ::useDllStorage(Triple); } + void IRGenerator::addGenModule(SourceFile *SF, IRGenModule *IGM) { assert(GenModules.count(SF) == 0); GenModules[SF] = IGM; diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h index bef4bba032567..192e1ba4e5875 100644 --- a/lib/IRGen/IRGenModule.h +++ b/lib/IRGen/IRGenModule.h @@ -534,6 +534,8 @@ class IRGenModule { void fatal_unimplemented(SourceLoc, StringRef Message); void error(SourceLoc loc, const Twine &message); + bool useDllStorage(); + private: Size PtrSize; llvm::Type *FixedBufferTy; /// [N x i8], where N == 3 * sizeof(void*) diff --git a/lib/IRGen/TypeLayoutVerifier.cpp b/lib/IRGen/TypeLayoutVerifier.cpp index 3f0f97f25d66e..1423ce6770fdf 100644 --- a/lib/IRGen/TypeLayoutVerifier.cpp +++ b/lib/IRGen/TypeLayoutVerifier.cpp @@ -43,7 +43,7 @@ irgen::emitTypeLayoutVerifier(IRGenFunction &IGF, /*var arg*/ false); auto verifierFn = IGF.IGM.Module.getOrInsertFunction( "_swift_debug_verifyTypeLayoutAttribute", verifierFnTy); - if (IGF.IGM.Triple.isOSBinFormatCOFF()) + if (IGF.IGM.useDllStorage()) if (auto *F = dyn_cast(verifierFn)) F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); diff --git a/lib/LLVMPasses/ARCEntryPointBuilder.h b/lib/LLVMPasses/ARCEntryPointBuilder.h index bfc10ff6c442f..144e92e76c535 100644 --- a/lib/LLVMPasses/ARCEntryPointBuilder.h +++ b/lib/LLVMPasses/ARCEntryPointBuilder.h @@ -272,7 +272,8 @@ class ARCEntryPointBuilder { CheckUnowned = M.getOrInsertFunction("swift_checkUnowned", AttrList, Type::getVoidTy(M.getContext()), ObjectPtrTy, nullptr); - if (llvm::Triple(M.getTargetTriple()).isOSBinFormatCOFF()) + if (llvm::Triple(M.getTargetTriple()).isOSBinFormatCOFF() && + !llvm::Triple(M.getTargetTriple()).isOSCygMing()) if (auto *F = llvm::dyn_cast(CheckUnowned.get())) F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); return CheckUnowned.get(); diff --git a/test/IRGen/autolink-coff-x86.swift b/test/IRGen/autolink-coff-x86.swift new file mode 100644 index 0000000000000..cc372d2f17c77 --- /dev/null +++ b/test/IRGen/autolink-coff-x86.swift @@ -0,0 +1,18 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t + +// RUN: %swift -target x86_64--windows-gnu -parse-as-library -parse-stdlib -emit-module-path %t/module.swiftmodule -module-name module -module-link-name module %s +// RUN: %swift -target x86_64--windows-gnu -parse-as-library -parse-stdlib -module-name autolink -I %t -D MAIN_MODULE -emit-ir -o - %s | %FileCheck %s -check-prefix CHECK-GNU-IR +// RUN: %swift -target x86_64--windows-gnu -parse-as-library -parse-stdlib -module-name autolink -I %t -D MAIN_MODULE -S -o - %s | %FileCheck %s -check-prefix CHECK-GNU-ASM + +// REQUIRES: CODEGENERATOR=X86 + +#if MAIN_MODULE +import module +#endif + +// CHECK-GNU-IR: @_swift1_autolink_entries = private constant [9 x i8] c"-lmodule\00", section ".swift1_autolink_entries", align 8 +// CHECK-GNU-IR: @llvm.used = appending global [{{.*}} x i8*] [{{.*}}i8* getelementptr inbounds ([9 x i8], [9 x i8]* @_swift1_autolink_entries, i32 0, i32 0){{.*}}], section "llvm.metadata", align 8 + +// CHECK-GNU-ASM: .section .swift1_autolink_entries{{.*}} +// CHECK-GNU-ASM: .asciz "-lmodule" diff --git a/test/IRGen/autolink-coff.swift b/test/IRGen/autolink-coff.swift index ded2e97c9be60..a1c1bac801b02 100644 --- a/test/IRGen/autolink-coff.swift +++ b/test/IRGen/autolink-coff.swift @@ -1,10 +1,6 @@ // RUN: rm -rf %t // RUN: mkdir -p %t -// RUN: %swift -target thumbv7--windows-gnu -parse-as-library -parse-stdlib -emit-module-path %t/module.swiftmodule -module-name module -module-link-name module %s -// RUN: %swift -target thumbv7--windows-gnu -parse-as-library -parse-stdlib -module-name autolink -I %t -D MAIN_MODULE -emit-ir -o - %s | %FileCheck %s -check-prefix CHECK-GNU-IR -// RUN: %swift -target thumbv7--windows-gnu -parse-as-library -parse-stdlib -module-name autolink -I %t -D MAIN_MODULE -S -o - %s | %FileCheck %s -check-prefix CHECK-GNU-ASM - // RUN: %swift -target thumbv7--windows-itanium -parse-as-library -parse-stdlib -emit-module-path %t/module.swiftmodule -module-name module -module-link-name module %s // RUN: %swift -target thumbv7--windows-itanium -parse-as-library -parse-stdlib -module-name autolink -I %t -D MAIN_MODULE -emit-ir -o - %s | %FileCheck %s -check-prefix CHECK-MSVC-IR // RUN: %swift -target thumbv7--windows-itanium -parse-as-library -parse-stdlib -module-name autolink -I %t -D MAIN_MODULE -S -o - %s | %FileCheck %s -check-prefix CHECK-MSVC-ASM @@ -19,13 +15,6 @@ import module #endif -// CHECK-GNU-IR: !{{[0-9]+}} = !{i32 {{[0-9]+}}, !"Linker Options", [[NODE:![0-9]+]]} -// CHECK-GNU-IR: [[NODE]] = !{[[LIST:![0-9]+]]} -// CHECK-GNU-IR: [[LIST]] = !{!"-lmodule"} - -// CHECK-GNU-ASM: .section .drectve -// CHECK-GNU-ASM: .ascii " -lmodule" - // CHECK-MSVC-IR: !{{[0-9]+}} = !{i32 {{[0-9]+}}, !"Linker Options", [[NODE:![0-9]+]]} // CHECK-MSVC-IR: [[NODE]] = !{[[LIST:![0-9]+]]} // CHECK-MSVC-IR: [[LIST]] = !{!"/DEFAULTLIB:module.lib"} diff --git a/utils/build-script-impl b/utils/build-script-impl index 0874d61f23831..16e329a4738d6 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -419,7 +419,7 @@ function set_build_options_for_host() { USE_GOLD_LINKER=1 ;; cygwin-x86_64) - SWIFT_HOST_VARIANT="windows" + SWIFT_HOST_VARIANT="cygwin" SWIFT_HOST_VARIANT_SDK="CYGWIN" SWIFT_HOST_VARIANT_ARCH="x86_64" ;;