diff --git a/include/swift/AST/IRGenOptions.h b/include/swift/AST/IRGenOptions.h index 52ffcc34aca36..87fe069c794e2 100644 --- a/include/swift/AST/IRGenOptions.h +++ b/include/swift/AST/IRGenOptions.h @@ -65,6 +65,12 @@ enum class IRGenDebugInfoFormat : unsigned { CodeView }; +enum class IRGenLLVMLTOKind : unsigned { + None, + Thin, + Full +}; + enum class IRGenEmbedMode : unsigned { None, EmbedMarker, @@ -221,6 +227,8 @@ class IRGenOptions { /// Whether we should embed the bitcode file. IRGenEmbedMode EmbedMode : 2; + IRGenLLVMLTOKind LLVMLTOKind: 2; + /// Add names to LLVM values. unsigned HasValueNamesSetting : 1; unsigned ValueNames : 1; @@ -323,6 +331,7 @@ class IRGenOptions { DisableFPElimLeaf(false), DisableFPElim(true), Playground(false), EmitStackPromotionChecks(false), FunctionSections(false), PrintInlineTree(false), EmbedMode(IRGenEmbedMode::None), + LLVMLTOKind(IRGenLLVMLTOKind::None), HasValueNamesSetting(false), ValueNames(false), EnableReflectionMetadata(true), EnableReflectionNames(true), EnableAnonymousContextMangledNames(false), ForcePublicLinkage(false), diff --git a/include/swift/Driver/Action.h b/include/swift/Driver/Action.h index 3f4e5c4edec14..eddff1591ce65 100644 --- a/include/swift/Driver/Action.h +++ b/include/swift/Driver/Action.h @@ -329,16 +329,19 @@ class GeneratePCHJobAction : public JobAction { class DynamicLinkJobAction : public JobAction { virtual void anchor(); LinkKind Kind; + bool LTO; public: - DynamicLinkJobAction(ArrayRef Inputs, LinkKind K) + DynamicLinkJobAction(ArrayRef Inputs, LinkKind K, bool LTO) : JobAction(Action::Kind::DynamicLinkJob, Inputs, file_types::TY_Image), - Kind(K) { + Kind(K), LTO(LTO) { assert(Kind != LinkKind::None && Kind != LinkKind::StaticLibrary); } LinkKind getKind() const { return Kind; } + bool PerformLTO() const { return LTO; } + static bool classof(const Action *A) { return A->getKind() == Action::Kind::DynamicLinkJob; } diff --git a/include/swift/Driver/Driver.h b/include/swift/Driver/Driver.h index 9723f4527ced4..156a758af3cb9 100644 --- a/include/swift/Driver/Driver.h +++ b/include/swift/Driver/Driver.h @@ -102,6 +102,14 @@ class OutputInfo { /// The output type which should be used for compile actions. file_types::ID CompilerOutputType = file_types::ID::TY_INVALID; + enum class LTOKind { + None, + LLVMThin, + LLVMFull, + }; + + LTOKind LTOVariant = LTOKind::None; + /// Describes if and how the output of compile actions should be /// linked together. LinkKind LinkAction = LinkKind::None; diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index 96cea8b35cded..1e9ee77e3c561 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -499,6 +499,10 @@ def disable_bridging_pch : Flag<["-"], "disable-bridging-pch">, Flags<[HelpHidden]>, HelpText<"Disable automatic generation of bridging PCH files">; +def lto : Joined<["-"], "lto=">, + Flags<[FrontendOption, NoInteractiveOption]>, + HelpText<"Specify the LTO type to either 'llvm' or 'llvm-full'">; + // Experimental feature options // Note: this flag will be removed when JVP/differential generation in the diff --git a/lib/Driver/DarwinToolChains.cpp b/lib/Driver/DarwinToolChains.cpp index bfd3bd442d3cc..f50877d6db639 100644 --- a/lib/Driver/DarwinToolChains.cpp +++ b/lib/Driver/DarwinToolChains.cpp @@ -238,12 +238,15 @@ toolchains::Darwin::addLinkerInputArgs(InvocationInfo &II, Arguments.push_back("-filelist"); Arguments.push_back(context.getTemporaryFilePath("inputs", "LinkFileList")); II.FilelistInfos.push_back( - {Arguments.back(), file_types::TY_Object, + {Arguments.back(), context.OI.CompilerOutputType, FilelistInfo::WhichFiles::InputJobsAndSourceInputActions}); } else { addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, file_types::TY_Object); + addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, + file_types::TY_LLVM_BC); addInputsOfType(Arguments, context.InputActions, file_types::TY_Object); + addInputsOfType(Arguments, context.InputActions, file_types::TY_LLVM_BC); } @@ -306,6 +309,20 @@ toolchains::Darwin::addArgsToLinkARCLite(ArgStringList &Arguments, } } +void +toolchains::Darwin::addLTOLibArgs(ArgStringList &Arguments, + const JobContext &context) const { + llvm::SmallString<128> LTOLibPath; + if (findXcodeClangPath(LTOLibPath)) { + llvm::sys::path::remove_filename(LTOLibPath); // 'clang' + llvm::sys::path::remove_filename(LTOLibPath); // 'bin' + llvm::sys::path::append(LTOLibPath, "lib", "libLTO.dylib"); + + Arguments.push_back("-lto_library"); + Arguments.push_back(context.Args.MakeArgString(LTOLibPath)); + } +} + void toolchains::Darwin::addSanitizerArgs(ArgStringList &Arguments, const DynamicLinkJobAction &job, @@ -723,6 +740,10 @@ toolchains::Darwin::constructInvocation(const DynamicLinkJobAction &job, addArgsToLinkARCLite(Arguments, context); + if (job.PerformLTO()) { + addLTOLibArgs(Arguments, context); + } + for (const Arg *arg : context.Args.filtered(options::OPT_F, options::OPT_Fsystem)) { Arguments.push_back("-F"); @@ -790,14 +811,17 @@ toolchains::Darwin::constructInvocation(const StaticLinkJobAction &job, if (context.shouldUseInputFileList()) { Arguments.push_back("-filelist"); Arguments.push_back(context.getTemporaryFilePath("inputs", "LinkFileList")); - II.FilelistInfos.push_back({Arguments.back(), file_types::TY_Object, + II.FilelistInfos.push_back({Arguments.back(), context.OI.CompilerOutputType, FilelistInfo::WhichFiles::InputJobs}); } else { addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, file_types::TY_Object); + addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, + file_types::TY_LLVM_BC); } addInputsOfType(Arguments, context.InputActions, file_types::TY_Object); + addInputsOfType(Arguments, context.InputActions, file_types::TY_LLVM_BC); Arguments.push_back("-o"); diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 4b9428e9d3de0..ffb0d1e9f2770 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -1427,12 +1427,15 @@ static bool isSDKTooOld(StringRef sdkPath, const llvm::Triple &target) { void Driver::buildOutputInfo(const ToolChain &TC, const DerivedArgList &Args, const bool BatchMode, const InputFileList &Inputs, OutputInfo &OI) const { + auto LinkerInputType = Args.hasArg(options::OPT_lto) + ? file_types::TY_LLVM_BC + : file_types::TY_Object; // By default, the driver does not link its output; this will be updated // appropriately below if linking is required. OI.CompilerOutputType = driverKind == DriverKind::Interactive ? file_types::TY_Nothing - : file_types::TY_Object; + : LinkerInputType; if (const Arg *A = Args.getLastArg(options::OPT_num_threads)) { if (BatchMode) { @@ -1462,14 +1465,14 @@ void Driver::buildOutputInfo(const ToolChain &TC, const DerivedArgList &Args, diag::error_static_emit_executable_disallowed); OI.LinkAction = LinkKind::Executable; - OI.CompilerOutputType = file_types::TY_Object; + OI.CompilerOutputType = LinkerInputType; break; case options::OPT_emit_library: OI.LinkAction = Args.hasArg(options::OPT_static) ? LinkKind::StaticLibrary : LinkKind::DynamicLibrary; - OI.CompilerOutputType = file_types::TY_Object; + OI.CompilerOutputType = LinkerInputType; break; case options::OPT_static: @@ -1779,6 +1782,18 @@ void Driver::buildOutputInfo(const ToolChain &TC, const DerivedArgList &Args, } + if (const Arg *A = Args.getLastArg(options::OPT_lto)) { + auto LTOVariant = llvm::StringSwitch>(A->getValue()) + .Case("llvm", OutputInfo::LTOKind::LLVMThin) + .Case("llvm-full", OutputInfo::LTOKind::LLVMFull) + .Default(llvm::None); + if (LTOVariant) + OI.LTOVariant = LTOVariant.getValue(); + else + Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, + A->getAsString(Args), A->getValue()); + } + if (TC.getTriple().isOSWindows()) { if (const Arg *A = Args.getLastArg(options::OPT_libc)) { OI.RuntimeVariant = @@ -2113,15 +2128,17 @@ void Driver::buildActions(SmallVectorImpl &TopLevelActions, MergeModuleAction = C.createAction(AllModuleInputs); } + auto PerformLTO = Args.hasArg(options::OPT_lto); if (OI.shouldLink() && !AllLinkerInputs.empty()) { JobAction *LinkAction = nullptr; if (OI.LinkAction == LinkKind::StaticLibrary) { LinkAction = C.createAction(AllLinkerInputs, - OI.LinkAction); + OI.LinkAction); } else { LinkAction = C.createAction(AllLinkerInputs, - OI.LinkAction); + OI.LinkAction, + PerformLTO); } // On ELF platforms there's no built in autolinking mechanism, so we @@ -2130,7 +2147,7 @@ void Driver::buildActions(SmallVectorImpl &TopLevelActions, const auto &Triple = TC.getTriple(); SmallVector AutolinkExtractInputs; for (const Action *A : AllLinkerInputs) - if (A->getType() == file_types::TY_Object) { + if (A->getType() == OI.CompilerOutputType) { // Shared objects on ELF platforms don't have a swift1_autolink_entries // section in them because the section in the .o files is marked as // SHF_EXCLUDE. @@ -2146,7 +2163,7 @@ void Driver::buildActions(SmallVectorImpl &TopLevelActions, (Triple.getObjectFormat() == llvm::Triple::ELF && !Triple.isPS4()) || Triple.getObjectFormat() == llvm::Triple::Wasm || Triple.isOSCygMing(); - if (!AutolinkExtractInputs.empty() && AutolinkExtractRequired) { + if (!AutolinkExtractInputs.empty() && AutolinkExtractRequired && !PerformLTO) { auto *AutolinkExtractAction = C.createAction(AutolinkExtractInputs); // Takes the same inputs as the linker... diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 90065e3fe2aa3..70f33d855fd79 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -519,6 +519,11 @@ ToolChain::constructInvocation(const CompileJobAction &job, Arguments.push_back("-track-system-dependencies"); } + if (auto arg = context.Args.getLastArg(options::OPT_lto)) { + Arguments.push_back(context.Args.MakeArgString( + Twine("-lto=") + arg->getValue())); + } + context.Args.AddLastArg( Arguments, options:: diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 29a04c1b243a8..946a8e70bc446 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -48,6 +48,9 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain { void addDeploymentTargetArgs(llvm::opt::ArgStringList &Arguments, const JobContext &context) const; + void addLTOLibArgs(llvm::opt::ArgStringList &Arguments, + const JobContext &context) const; + void addCommonFrontendArgs( const OutputInfo &OI, const CommandOutput &output, const llvm::opt::ArgList &inputArgs, diff --git a/lib/Driver/UnixToolChains.cpp b/lib/Driver/UnixToolChains.cpp index 59f24a4eafe1e..75c812b9521ad 100644 --- a/lib/Driver/UnixToolChains.cpp +++ b/lib/Driver/UnixToolChains.cpp @@ -72,7 +72,10 @@ ToolChain::InvocationInfo toolchains::GenericUnix::constructInvocation( addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, file_types::TY_Object); + addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, + file_types::TY_LLVM_BC); addInputsOfType(Arguments, context.InputActions, file_types::TY_Object); + addInputsOfType(Arguments, context.InputActions, file_types::TY_LLVM_BC); Arguments.push_back("-o"); Arguments.push_back( @@ -167,6 +170,9 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job, std::string Linker; if (const Arg *A = context.Args.getLastArg(options::OPT_use_ld)) { Linker = A->getValue(); + } else if (context.OI.LTOVariant != OutputInfo::LTOKind::None) { + // Force to use lld for LTO + Linker = "lld"; } else { Linker = getDefaultLinker(); } @@ -218,6 +224,16 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job, Arguments.push_back("-pie"); } + switch (context.OI.LTOVariant) { + case OutputInfo::LTOKind::LLVMThin: + Arguments.push_back("-flto=thin"); + break; + case OutputInfo::LTOKind::LLVMFull: + Arguments.push_back("-flto=full"); + break; + case OutputInfo::LTOKind::None: break; + } + bool staticExecutable = false; bool staticStdlib = false; @@ -253,7 +269,11 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job, addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, file_types::TY_Object); + addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, + file_types::TY_LLVM_BC); addInputsOfType(Arguments, context.InputActions, file_types::TY_Object); + addInputsOfType(Arguments, context.InputActions, file_types::TY_LLVM_BC); + for (const Arg *arg : context.Args.filtered(options::OPT_F, options::OPT_Fsystem)) { @@ -368,7 +388,7 @@ toolchains::GenericUnix::constructInvocation(const StaticLinkJobAction &job, ArgStringList Arguments; // Configure the toolchain. - const char *AR = "ar"; + const char *AR = "llvm-ar"; Arguments.push_back("crs"); Arguments.push_back( @@ -376,7 +396,11 @@ toolchains::GenericUnix::constructInvocation(const StaticLinkJobAction &job, addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, file_types::TY_Object); + addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, + file_types::TY_LLVM_BC); addInputsOfType(Arguments, context.InputActions, file_types::TY_Object); + addInputsOfType(Arguments, context.InputActions, file_types::TY_LLVM_BC); + InvocationInfo II{AR, Arguments}; diff --git a/lib/Driver/WindowsToolChains.cpp b/lib/Driver/WindowsToolChains.cpp index 0fe623675eb1a..5131d14e14f03 100644 --- a/lib/Driver/WindowsToolChains.cpp +++ b/lib/Driver/WindowsToolChains.cpp @@ -143,7 +143,11 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job, addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, file_types::TY_Object); + addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, + file_types::TY_LLVM_BC); addInputsOfType(Arguments, context.InputActions, file_types::TY_Object); + addInputsOfType(Arguments, context.InputActions, file_types::TY_LLVM_BC); + for (const Arg *arg : context.Args.filtered(options::OPT_F, options::OPT_Fsystem)) { @@ -186,6 +190,21 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job, context.Args.AddAllArgs(Arguments, options::OPT_linker_option_Group); context.Args.AddAllArgValues(Arguments, options::OPT_Xclang_linker); + switch (context.OI.LTOVariant) { + case OutputInfo::LTOKind::LLVMThin: + case OutputInfo::LTOKind::LLVMFull: { + if (Linker.empty()) + Arguments.push_back("-fuse-ld=lld"); + if (context.OI.LTOVariant == OutputInfo::LTOKind::LLVMThin) { + Arguments.push_back("-flto=thin"); + } else { + Arguments.push_back("-flto=full"); + } + break; + } + case OutputInfo::LTOKind::None: break; + } + // Run clang++ in verbose mode if "-v" is set if (context.Args.hasArg(options::OPT_v)) { Arguments.push_back("-v"); @@ -210,22 +229,46 @@ toolchains::Windows::constructInvocation(const StaticLinkJobAction &job, ArgStringList Arguments; - const char *Linker = "link"; - if (const Arg *A = context.Args.getLastArg(options::OPT_use_ld)) - Linker = context.Args.MakeArgString(A->getValue()); - - Arguments.push_back("/lib"); - Arguments.push_back("-nologo"); + switch (context.OI.LTOVariant) { + case OutputInfo::LTOKind::LLVMThin: + case OutputInfo::LTOKind::LLVMFull: { + const char *AR = "llvm-ar"; + Arguments.push_back("crs"); - addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, - file_types::TY_Object); - addInputsOfType(Arguments, context.InputActions, file_types::TY_Object); + Arguments.push_back( + context.Args.MakeArgString(context.Output.getPrimaryOutputFilename())); - StringRef OutputFile = context.Output.getPrimaryOutputFilename(); - Arguments.push_back(context.Args.MakeArgString(Twine("/OUT:") + OutputFile)); + addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, + file_types::TY_Object); + addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, + file_types::TY_LLVM_BC); + addInputsOfType(Arguments, context.InputActions, file_types::TY_Object); + addInputsOfType(Arguments, context.InputActions, file_types::TY_LLVM_BC); - InvocationInfo II{Linker, Arguments}; - II.allowsResponseFiles = true; + InvocationInfo II{AR, Arguments}; - return II; + return II; + } + case OutputInfo::LTOKind::None: + const char *Linker = "link"; + if (const Arg *A = context.Args.getLastArg(options::OPT_use_ld)) + Linker = context.Args.MakeArgString(A->getValue()); + + Arguments.push_back("/lib"); + Arguments.push_back("-nologo"); + + addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, + file_types::TY_Object); + addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, + file_types::TY_LLVM_BC); + addInputsOfType(Arguments, context.InputActions, file_types::TY_Object); + addInputsOfType(Arguments, context.InputActions, file_types::TY_LLVM_BC); + + StringRef OutputFile = context.Output.getPrimaryOutputFilename(); + Arguments.push_back(context.Args.MakeArgString(Twine("/OUT:") + OutputFile)); + + InvocationInfo II{Linker, Arguments}; + II.allowsResponseFiles = true; + return II; + } } diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 17f28871d3243..7e68f9eeb6631 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1421,6 +1421,17 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args, } } + if (const Arg *A = Args.getLastArg(options::OPT_lto)) { + auto LLVMLTOKind = llvm::StringSwitch>(A->getValue()) + .Case("llvm", IRGenLLVMLTOKind::Thin) + .Case("llvm-full", IRGenLLVMLTOKind::Full) + .Default(llvm::None); + if (LLVMLTOKind) + Opts.LLVMLTOKind = LLVMLTOKind.getValue(); + else + Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, + A->getAsString(Args), A->getValue()); + } if (const Arg *A = Args.getLastArg(options::OPT_sanitize_coverage_EQ)) { Opts.SanitizeCoverage = diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp index f3947efa47588..060d2d3ac6c1b 100644 --- a/lib/IRGen/IRGen.cpp +++ b/lib/IRGen/IRGen.cpp @@ -548,9 +548,14 @@ bool swift::performLLVM(const IRGenOptions &Opts, case IRGenOutputKind::LLVMAssembly: EmitPasses.add(createPrintModulePass(*RawOS)); break; - case IRGenOutputKind::LLVMBitcode: - EmitPasses.add(createBitcodeWriterPass(*RawOS)); + case IRGenOutputKind::LLVMBitcode: { + if (Opts.LLVMLTOKind == IRGenLLVMLTOKind::Thin) { + EmitPasses.add(createWriteThinLTOBitcodePass(*RawOS)); + } else { + EmitPasses.add(createBitcodeWriterPass(*RawOS)); + } break; + } case IRGenOutputKind::NativeAssembly: case IRGenOutputKind::ObjectFile: { CodeGenFileType FileType; diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp index 306ae4e3697b1..007726983c0f6 100644 --- a/lib/IRGen/IRGenModule.cpp +++ b/lib/IRGen/IRGenModule.cpp @@ -1132,10 +1132,18 @@ void IRGenModule::addLinkLibrary(const LinkLibrary &linkLib) { switch (linkLib.getKind()) { case LibraryKind::Library: { - llvm::SmallString<32> opt = - getTargetDependentLibraryOption(Triple, linkLib.getName()); - AutolinkEntries.push_back( - llvm::MDNode::get(ctx, llvm::MDString::get(ctx, opt))); + if (TargetInfo.OutputObjectFormat == llvm::Triple::ELF && IRGen.Opts.LLVMLTOKind != IRGenLLVMLTOKind::None) { + // When performing LTO, we always use lld that supports auto linking mechanism with ELF. + // So embed dependent libraries names in "llvm.dependent-libraries" instead of options + // to avoid using swift-autolink-extract. + AutolinkEntries.push_back( + llvm::MDNode::get(ctx, llvm::MDString::get(ctx, linkLib.getName()))); + } else { + llvm::SmallString<32> opt = + getTargetDependentLibraryOption(Triple, linkLib.getName()); + AutolinkEntries.push_back( + llvm::MDNode::get(ctx, llvm::MDString::get(ctx, opt))); + } break; } case LibraryKind::Framework: { @@ -1222,7 +1230,12 @@ static bool isFirstObjectFileInModule(IRGenModule &IGM) { void IRGenModule::emitAutolinkInfo() { // Collect the linker options already in the module (from ClangCodeGen). // FIXME: This constant should be vended by LLVM somewhere. - auto *Metadata = Module.getOrInsertNamedMetadata("llvm.linker.options"); + // When performing LTO, we always use lld that supports auto linking mechanism with ELF. + // So embed dependent libraries names in "llvm.dependent-libraries" instead of "llvm.linker.options". + const StringRef AutolinkSectionName = + TargetInfo.OutputObjectFormat == llvm::Triple::ELF && IRGen.Opts.LLVMLTOKind != IRGenLLVMLTOKind::None + ? "llvm.dependent-libraries" : "llvm.linker.options"; + auto *Metadata = Module.getOrInsertNamedMetadata(AutolinkSectionName); for (llvm::MDNode *LinkOption : Metadata->operands()) AutolinkEntries.push_back(LinkOption); @@ -1237,9 +1250,9 @@ void IRGenModule::emitAutolinkInfo() { AutolinkEntries.end()); const bool AutolinkExtractRequired = - (TargetInfo.OutputObjectFormat == llvm::Triple::ELF && !Triple.isPS4()) || + ((TargetInfo.OutputObjectFormat == llvm::Triple::ELF && !Triple.isPS4()) || TargetInfo.OutputObjectFormat == llvm::Triple::Wasm || - Triple.isOSCygMing(); + Triple.isOSCygMing()) && IRGen.Opts.LLVMLTOKind == IRGenLLVMLTOKind::None; if (!AutolinkExtractRequired) { // On platforms that support autolinking, continue to use the metadata. diff --git a/test/Driver/Inputs/lto/lib.swift b/test/Driver/Inputs/lto/lib.swift new file mode 100644 index 0000000000000..2da93851bb3e7 --- /dev/null +++ b/test/Driver/Inputs/lto/lib.swift @@ -0,0 +1 @@ +public func libraryFunction() {} diff --git a/test/Driver/Inputs/lto/main.swift b/test/Driver/Inputs/lto/main.swift new file mode 100644 index 0000000000000..fef49f4c4f8f2 --- /dev/null +++ b/test/Driver/Inputs/lto/main.swift @@ -0,0 +1,3 @@ +import A + +libraryFunction() diff --git a/test/Driver/Inputs/lto/multifiles/file.swift b/test/Driver/Inputs/lto/multifiles/file.swift new file mode 100644 index 0000000000000..2ff6e02c99461 --- /dev/null +++ b/test/Driver/Inputs/lto/multifiles/file.swift @@ -0,0 +1,3 @@ +func anotherFileFunction() { + print(#function) +} diff --git a/test/Driver/Inputs/lto/multifiles/main.swift b/test/Driver/Inputs/lto/multifiles/main.swift new file mode 100644 index 0000000000000..c81b011f13bd9 --- /dev/null +++ b/test/Driver/Inputs/lto/multifiles/main.swift @@ -0,0 +1 @@ +anotherFileFunction() diff --git a/test/Driver/link-time-opt-lib-thin.swift b/test/Driver/link-time-opt-lib-thin.swift new file mode 100644 index 0000000000000..f07ecded6e0c1 --- /dev/null +++ b/test/Driver/link-time-opt-lib-thin.swift @@ -0,0 +1,12 @@ +// FIXME: ld64 in Xcode toolchain uses older version of LLVM than swiftc, so ld64 can't read module summary for LTO +// from bitcode file produced by compiler. This should be fixed before shipping Xcode toolchain by upgrading +// LLVM version used in ld64. +// XFAIL: OS=macosx +// XFAIL: OS=tvos +// XFAIL: OS=watchos +// XFAIL: OS=ios +// RUN: rm -rf %t +// RUN: %empty-directory(%t/thin) + +// RUN: %target-swiftc_driver %S/Inputs/lto/lib.swift -lto=llvm -emit-library -emit-module -module-name A -working-directory %t/thin +// RUN: %target-swiftc_driver %S/Inputs/lto/main.swift -L. -I. -lA -lto=llvm -working-directory %t/thin diff --git a/test/Driver/link-time-opt-lib.swift b/test/Driver/link-time-opt-lib.swift new file mode 100644 index 0000000000000..81cfaa4cafe92 --- /dev/null +++ b/test/Driver/link-time-opt-lib.swift @@ -0,0 +1,5 @@ +// RUN: rm -rf %t +// RUN: %empty-directory(%t/full) + +// RUN: %target-swiftc_driver %S/Inputs/lto/lib.swift -lto=llvm-full -emit-library -emit-module -module-name A -working-directory %t/full +// RUN: %target-swiftc_driver %S/Inputs/lto/main.swift -L. -I. -lA -lto=llvm-full -working-directory %t/full diff --git a/test/Driver/link-time-opt-staticlib-thin.swift b/test/Driver/link-time-opt-staticlib-thin.swift new file mode 100644 index 0000000000000..283b7c541fcbd --- /dev/null +++ b/test/Driver/link-time-opt-staticlib-thin.swift @@ -0,0 +1,14 @@ +// UNSUPPORTED: OS=windows-msvc +// FIXME: ld64 in Xcode toolchain uses older version of LLVM than swiftc, so ld64 can't read module summary for LTO +// from bitcode file produced by compiler. This should be fixed before shipping Xcode toolchain by upgrading +// LLVM version used in ld64. +// XFAIL: OS=macosx +// XFAIL: OS=tvos +// XFAIL: OS=watchos +// XFAIL: OS=ios + +// RUN: rm -rf %t +// RUN: %empty-directory(%t/thin-static) + +// RUN: %target-swiftc_driver %S/Inputs/lto/lib.swift -static -lto=llvm -emit-library -emit-module -module-name A -working-directory %t/thin-static +// RUN: %target-swiftc_driver %S/Inputs/lto/main.swift -L. -I. -lA -lto=llvm -working-directory %t/thin-static diff --git a/test/Driver/link-time-opt-staticlib.swift b/test/Driver/link-time-opt-staticlib.swift new file mode 100644 index 0000000000000..6daf95595bf3e --- /dev/null +++ b/test/Driver/link-time-opt-staticlib.swift @@ -0,0 +1,6 @@ +// UNSUPPORTED: OS=windows-msvc +// RUN: rm -rf %t +// RUN: %empty-directory(%t/full-static) + +// RUN: %target-swiftc_driver %S/Inputs/lto/lib.swift -static -lto=llvm-full -emit-library -emit-module -module-name A -working-directory %t/full-static +// RUN: %target-swiftc_driver %S/Inputs/lto/main.swift -L. -I. -lA -lto=llvm-full -working-directory %t/full-static diff --git a/test/Driver/link-time-opt.swift b/test/Driver/link-time-opt.swift new file mode 100644 index 0000000000000..28a92ad1fcc99 --- /dev/null +++ b/test/Driver/link-time-opt.swift @@ -0,0 +1,5 @@ +// RUN: %target-swiftc_driver -driver-print-jobs %S/../Inputs/empty.swift -lto=llvm | %FileCheck %s --check-prefix=CHECK-%target-os --check-prefix=CHECK +// CHECK: swift{{(c\.exe")?}} -frontend -emit-bc +// CHECK-macosx-NEXT: bin/ld {{.+}} -lto_library {{.+}}/lib/libLTO.dylib +// CHECK-windows-msvc-NEXT: clang.exe" {{.+}} -fuse-ld=lld -flto=thin +// CHECK-linux-gnu-NEXT: bin/clang {{.+}} -flto=thin diff --git a/utils/build-windows.bat b/utils/build-windows.bat index ca62cfef8f43e..3c9c11e65ff49 100644 --- a/utils/build-windows.bat +++ b/utils/build-windows.bat @@ -97,6 +97,7 @@ git clone --depth 1 --single-branch https://github.com/apple/swift-cmark cmark % git clone --depth 1 --single-branch --branch swift/master https://github.com/apple/llvm-project llvm-project %exitOnError% mklink /D "%source_root%\clang" "%source_root%\llvm-project\clang" mklink /D "%source_root%\llvm" "%source_root%\llvm-project\llvm" +mklink /D "%source_root%\lld" "%source_root%\llvm-project\lld" mklink /D "%source_root%\lldb" "%source_root%\llvm-project\lldb" mklink /D "%source_root%\compiler-rt" "%source_root%\llvm-project\compiler-rt" mklink /D "%source_root%\libcxx" "%source_root%\llvm-project\libcxx" @@ -165,7 +166,7 @@ cmake^ -DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-windows-msvc^ -DLLVM_ENABLE_PDB:BOOL=YES^ -DLLVM_ENABLE_ASSERTIONS:BOOL=YES^ - -DLLVM_ENABLE_PROJECTS:STRING=clang^ + -DLLVM_ENABLE_PROJECTS:STRING=lld;clang^ -DLLVM_TARGETS_TO_BUILD:STRING="AArch64;ARM;X86"^ -DLLVM_INCLUDE_BENCHMARKS:BOOL=NO^ -DLLVM_INCLUDE_DOCS:BOOL=NO^