From 35735e7d0c57b57953623eb069d3812cd95d25e6 Mon Sep 17 00:00:00 2001 From: Jeremy Legendre Date: Mon, 5 Jul 2021 18:01:40 -0400 Subject: [PATCH 1/4] [LTO] Driver support for -lto_library flag This commit adds support for the -lto_library flag, allowing users to specify a custom LTO library on Darwin. This also fixes an issue where the default LTO library is used even if Driver is run from inside an alternate toolchain. --- include/swift/Driver/Driver.h | 2 ++ include/swift/Option/Options.td | 5 ++++ lib/Driver/DarwinToolChains.cpp | 24 ++++++++++++++++--- lib/Driver/Driver.cpp | 6 +++++ test/Driver/link-time-opt-darwin-ld-lib.swift | 15 ++++++++++++ 5 files changed, 49 insertions(+), 3 deletions(-) diff --git a/include/swift/Driver/Driver.h b/include/swift/Driver/Driver.h index 68dc04fff1351..11da8cccf6fdb 100644 --- a/include/swift/Driver/Driver.h +++ b/include/swift/Driver/Driver.h @@ -109,6 +109,8 @@ class OutputInfo { LTOKind LTOVariant = LTOKind::None; + std::string LibLTOPath; + /// 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 4ffc539bddc8c..9feb70e030879 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -549,6 +549,11 @@ def disable_bridging_pch : Flag<["-"], "disable-bridging-pch">, def lto : Joined<["-"], "lto=">, Flags<[FrontendOption, NoInteractiveOption]>, HelpText<"Specify the LTO type to either 'llvm-thin' or 'llvm-full'">; + +def lto_library : Separate<["-"], "lto_library">, + Flags<[FrontendOption, ArgumentIsPath, SwiftAPIExtractOption, SwiftSymbolGraphExtractOption, + SwiftAPIDigesterOption]>, + HelpText<"Perform LTO with ">, MetaVarName<"">; def access_notes_path : Separate<["-"], "access-notes-path">, Flags<[FrontendOption, ArgumentIsPath]>, diff --git a/lib/Driver/DarwinToolChains.cpp b/lib/Driver/DarwinToolChains.cpp index 3f858e77275d7..6d05757f6d86e 100644 --- a/lib/Driver/DarwinToolChains.cpp +++ b/lib/Driver/DarwinToolChains.cpp @@ -321,10 +321,28 @@ toolchains::Darwin::addArgsToLinkARCLite(ArgStringList &Arguments, void toolchains::Darwin::addLTOLibArgs(ArgStringList &Arguments, const JobContext &context) const { - llvm::SmallString<128> LTOLibPath; - if (findXcodeClangLibPath("libLTO.dylib", LTOLibPath)) { + if (!context.OI.LibLTOPath.empty()) { + // Check for user-specified LTO library. Arguments.push_back("-lto_library"); - Arguments.push_back(context.Args.MakeArgString(LTOLibPath)); + Arguments.push_back(context.Args.MakeArgString(context.OI.LibLTOPath)); + } else { + // Check for relative libLTO.dylib. This would be the expected behavior in an + // Xcode toolchain. + StringRef P = llvm::sys::path::parent_path(getDriver().getSwiftProgramPath()); + llvm::SmallString<128> LibLTOPath(P); + llvm::sys::path::append(LibLTOPath, "lib"); + llvm::sys::path::append(LibLTOPath, "libLTO.dylib"); + if (llvm::sys::fs::exists(LibLTOPath)) { + Arguments.push_back("-lto_library"); + Arguments.push_back(context.Args.MakeArgString(LibLTOPath)); + } else { + // Use libLTO.dylib from the default toolchain if a relative one does not exist. + llvm::SmallString<128> LibLTOPath; + if (findXcodeClangLibPath("libLTO.dylib", LibLTOPath)) { + Arguments.push_back("-lto_library"); + Arguments.push_back(context.Args.MakeArgString(LibLTOPath)); + } + } } } diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index c06cf49827727..dece951514d03 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -1448,6 +1448,12 @@ void Driver::buildOutputInfo(const ToolChain &TC, const DerivedArgList &Args, Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, A->getAsString(Args), A->getValue()); } + + if (const Arg *A = Args.getLastArg(options::OPT_lto_library)) { + OI.LibLTOPath = A->getValue(); + } else { + OI.LibLTOPath = ""; + } auto CompilerOutputType = OI.LTOVariant != OutputInfo::LTOKind::None ? file_types::TY_LLVM_BC diff --git a/test/Driver/link-time-opt-darwin-ld-lib.swift b/test/Driver/link-time-opt-darwin-ld-lib.swift index b3998e24d2b78..d72569e189e78 100644 --- a/test/Driver/link-time-opt-darwin-ld-lib.swift +++ b/test/Driver/link-time-opt-darwin-ld-lib.swift @@ -24,3 +24,18 @@ // CHECK-SIMPLE-FULL-macosx: ld // CHECK-SIMPLE-FULL-macosx-DAG: -lto_library {{.+}}/lib/libLTO.dylib // CHECK-SIMPLE-FULL-macosx-DAG: [[OBJECTFILE]] + + +// Check that driver does not see libLTO.dylib as an input + +// RUN: %swiftc_driver -driver-print-jobs %S/../Inputs/empty.swift -lto=llvm-full -lto_library /foo/libLTO.dylib -target x86_64-apple-macosx10.9 | %FileCheck %s --check-prefix=CHECK-SIMPLE-LTO-LIB --check-prefix=CHECK-SIMPLE-LTO-LIB-macosx + +// CHECK-SIMPLE-LTO-LIB: swift +// CHECK-SIMPLE-LTO-LIB-DAG: -emit-bc +// CHECK-SIMPLE-LTO-LIB-DAG: -lto=llvm-full +// CHECK-SIMPLE-LTO-LIB-NOT: -lto_library /foo/libLTO.dylib +// CHECK-SIMPLE-LTO-LIB-DAG: -o [[OBJECTFILE:.*\.bc]] + +// CHECK-SIMPLE-LTO-LIB-macosx: ld +// CHECK-SIMPLE-LTO-LIB-macosx-DAG: -lto_library /foo/libLTO.dylib +// CHECK-SIMPLE-LTO-LIB-macosx-DAG: [[OBJECTFILE]] From ebd59927d6e347673876a9c64554fff48abca254 Mon Sep 17 00:00:00 2001 From: Jeremy Legendre Date: Mon, 5 Jul 2021 23:56:42 -0400 Subject: [PATCH 2/4] Use Swift-style args for Driver --- include/swift/Option/Options.td | 4 ++-- test/Driver/link-time-opt-darwin-ld-lib.swift | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index 9feb70e030879..46151fdd3cdc9 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -550,10 +550,10 @@ def lto : Joined<["-"], "lto=">, Flags<[FrontendOption, NoInteractiveOption]>, HelpText<"Specify the LTO type to either 'llvm-thin' or 'llvm-full'">; -def lto_library : Separate<["-"], "lto_library">, +def lto_library : Separate<["-"], "lto-library">, Flags<[FrontendOption, ArgumentIsPath, SwiftAPIExtractOption, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>, - HelpText<"Perform LTO with ">, MetaVarName<"">; + HelpText<"Perform LTO with ">, MetaVarName<"">; def access_notes_path : Separate<["-"], "access-notes-path">, Flags<[FrontendOption, ArgumentIsPath]>, diff --git a/test/Driver/link-time-opt-darwin-ld-lib.swift b/test/Driver/link-time-opt-darwin-ld-lib.swift index d72569e189e78..c82265075b5de 100644 --- a/test/Driver/link-time-opt-darwin-ld-lib.swift +++ b/test/Driver/link-time-opt-darwin-ld-lib.swift @@ -28,12 +28,12 @@ // Check that driver does not see libLTO.dylib as an input -// RUN: %swiftc_driver -driver-print-jobs %S/../Inputs/empty.swift -lto=llvm-full -lto_library /foo/libLTO.dylib -target x86_64-apple-macosx10.9 | %FileCheck %s --check-prefix=CHECK-SIMPLE-LTO-LIB --check-prefix=CHECK-SIMPLE-LTO-LIB-macosx +// RUN: %swiftc_driver -driver-print-jobs %S/../Inputs/empty.swift -lto=llvm-full -lto-library /foo/libLTO.dylib -target x86_64-apple-macosx10.9 | %FileCheck %s --check-prefix=CHECK-SIMPLE-LTO-LIB --check-prefix=CHECK-SIMPLE-LTO-LIB-macosx // CHECK-SIMPLE-LTO-LIB: swift // CHECK-SIMPLE-LTO-LIB-DAG: -emit-bc // CHECK-SIMPLE-LTO-LIB-DAG: -lto=llvm-full -// CHECK-SIMPLE-LTO-LIB-NOT: -lto_library /foo/libLTO.dylib +// CHECK-SIMPLE-LTO-LIB-NOT: -lto-library /foo/libLTO.dylib // CHECK-SIMPLE-LTO-LIB-DAG: -o [[OBJECTFILE:.*\.bc]] // CHECK-SIMPLE-LTO-LIB-macosx: ld From 7fa9fcf01f20366671224b86b6030653820cdf72 Mon Sep 17 00:00:00 2001 From: Jeremy Legendre Date: Tue, 6 Jul 2021 01:34:37 -0400 Subject: [PATCH 3/4] Update flag options Co-authored-by: Owen Voorhees --- include/swift/Option/Options.td | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index 46151fdd3cdc9..f4fd283cf1133 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -551,8 +551,7 @@ def lto : Joined<["-"], "lto=">, HelpText<"Specify the LTO type to either 'llvm-thin' or 'llvm-full'">; def lto_library : Separate<["-"], "lto-library">, - Flags<[FrontendOption, ArgumentIsPath, SwiftAPIExtractOption, SwiftSymbolGraphExtractOption, - SwiftAPIDigesterOption]>, + Flags<[FrontendOption, ArgumentIsPath, NoInteractiveOption]>, HelpText<"Perform LTO with ">, MetaVarName<"">; def access_notes_path : Separate<["-"], "access-notes-path">, From 1a381683e42836e225ad7c63ca9addd637f5a04d Mon Sep 17 00:00:00 2001 From: Jeremy Legendre Date: Mon, 12 Jul 2021 15:36:33 -0400 Subject: [PATCH 4/4] Fix relative libLTO path --- lib/Driver/DarwinToolChains.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Driver/DarwinToolChains.cpp b/lib/Driver/DarwinToolChains.cpp index 6d05757f6d86e..e4047e2839ed4 100644 --- a/lib/Driver/DarwinToolChains.cpp +++ b/lib/Driver/DarwinToolChains.cpp @@ -330,6 +330,7 @@ void toolchains::Darwin::addLTOLibArgs(ArgStringList &Arguments, // Xcode toolchain. StringRef P = llvm::sys::path::parent_path(getDriver().getSwiftProgramPath()); llvm::SmallString<128> LibLTOPath(P); + llvm::sys::path::remove_filename(LibLTOPath); // Remove '/bin' llvm::sys::path::append(LibLTOPath, "lib"); llvm::sys::path::append(LibLTOPath, "libLTO.dylib"); if (llvm::sys::fs::exists(LibLTOPath)) {