diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -11,6 +11,7 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Object/COFF.h" @@ -123,6 +124,7 @@ bool showTiming = false; bool showSummary = false; unsigned debugTypes = static_cast(DebugType::None); + llvm::SmallVector mllvmOpts; std::vector natvisFiles; llvm::StringMap namedStreams; llvm::SmallString<128> pdbAltPath; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1425,8 +1425,10 @@ // Parse and evaluate -mllvm options. std::vector v; v.push_back("lld-link (LLVM option parsing)"); - for (auto *arg : args.filtered(OPT_mllvm)) + for (const auto *arg : args.filtered(OPT_mllvm)) { v.push_back(arg->getValue()); + config->mllvmOpts.emplace_back(arg->getValue()); + } cl::ResetAllOptionOccurrences(); cl::ParseCommandLineOptions(v.size(), v.data()); diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp --- a/lld/COFF/LTO.cpp +++ b/lld/COFF/LTO.cpp @@ -63,6 +63,8 @@ lto::Config c; c.Options = initTargetOptionsFromCodeGenFlags(); c.Options.EmitAddrsig = true; + for (StringRef C : config->mllvmOpts) + c.MllvmArgs.emplace_back(C.str()); // Always emit a section per function/datum with LTO. LLVM LTO should get most // of the benefit of linker GC, but there are still opportunities for ICF. diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1370,7 +1370,7 @@ config->passPlugins = args::getStrings(args, OPT_load_pass_plugins); // Parse -mllvm options. - for (auto *arg : args.filtered(OPT_mllvm)) { + for (const auto *arg : args.filtered(OPT_mllvm)) { parseClangOption(arg->getValue(), arg->getSpelling()); config->mllvmOpts.emplace_back(arg->getValue()); } diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -209,6 +209,7 @@ SymtabPresence localSymbolsPresence = SymtabPresence::All; SymbolPatterns localSymbolPatterns; + llvm::SmallVector mllvmOpts; bool zeroModTime = true; diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1785,8 +1785,10 @@ parseClangOption(saver().save("-mcpu=" + StringRef(arg->getValue())), arg->getSpelling()); - for (const Arg *arg : args.filtered(OPT_mllvm)) + for (const Arg *arg : args.filtered(OPT_mllvm)) { parseClangOption(arg->getValue(), arg->getSpelling()); + config->mllvmOpts.emplace_back(arg->getValue()); + } createSyntheticSections(); createSyntheticSymbols(); diff --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp --- a/lld/MachO/LTO.cpp +++ b/lld/MachO/LTO.cpp @@ -35,6 +35,8 @@ lto::Config c; c.Options = initTargetOptionsFromCodeGenFlags(); c.Options.EmitAddrsig = config->icfLevel == ICFLevel::safe; + for (StringRef C : config->mllvmOpts) + c.MllvmArgs.emplace_back(C.str()); c.CodeModel = getCodeModelFromCMModel(); c.CPU = getCPUStr(); c.MAttrs = getMAttrs(); diff --git a/lld/test/COFF/lto-cache.ll b/lld/test/COFF/lto-cache.ll --- a/lld/test/COFF/lto-cache.ll +++ b/lld/test/COFF/lto-cache.ll @@ -14,6 +14,51 @@ ; Two cached objects, plus a timestamp file and "foo", minus the file we removed. ; RUN: ls %t.cache | count 4 +;; Check that mllvm options participate in the cache key +; RUN: rm -rf %t.cache && mkdir %t.cache +; RUN: lld-link /lldltocache:%t.cache /entry:main /out:%t3 %t2.o %t.o +; RUN: ls %t.cache | count 3 +; RUN: lld-link /lldltocache:%t.cache /entry:main /out:%t3 %t2.o %t.o /mllvm:-enable-ml-inliner=default +; RUN: ls %t.cache | count 5 + +;; Adding another option resuls in 2 more cache entries +; RUN: rm -rf %t.cache && mkdir %t.cache +; RUN: lld-link /lldltocache:%t.cache /entry:main /out:%t3 %t2.o %t.o +; RUN: ls %t.cache | count 3 +; RUN: lld-link /lldltocache:%t.cache /entry:main /out:%t3 %t2.o %t.o /mllvm:-enable-ml-inliner=default +; RUN: ls %t.cache | count 5 +; RUN: lld-link /lldltocache:%t.cache /entry:main /out:%t3 %t2.o %t.o /mllvm:-enable-ml-inliner=default /mllvm:-max-devirt-iterations=1 +; RUN: ls %t.cache | count 7 + +;; Changing order may matter - e.g. if overriding /mllvm:options - so we get 2 more entries +; RUN: lld-link /lldltocache:%t.cache /entry:main /out:%t3 %t2.o %t.o /mllvm:-max-devirt-iterations=1 /mllvm:-enable-ml-inliner=default +; RUN: ls %t.cache | count 9 + +;; Going back to a pre-cached order doesn't create more entries. +; RUN: lld-link /lldltocache:%t.cache /entry:main /out:%t3 %t2.o %t.o /mllvm:-enable-ml-inliner=default /mllvm:-max-devirt-iterations=1 +; RUN: ls %t.cache | count 9 + +;; Different flag values matter +; RUN: rm -rf %t.cache && mkdir %t.cache +; RUN: lld-link /lldltocache:%t.cache /entry:main /out:%t3 %t2.o %t.o /mllvm:-enable-ml-inliner=default /mllvm:-max-devirt-iterations=2 +; RUN: ls %t.cache | count 3 +; RUN: lld-link /lldltocache:%t.cache /entry:main /out:%t3 %t2.o %t.o /mllvm:-enable-ml-inliner=default /mllvm:-max-devirt-iterations=1 +; RUN: ls %t.cache | count 5 + +;; Same flag value passed to different flags matters, and switching the order +;; of the two flags matters. +; RUN: rm -rf %t.cache && mkdir %t.cache +; RUN: lld-link /lldltocache:%t.cache /entry:main /out:%t3 %t2.o %t.o /mllvm:-enable-ml-inliner=default +; RUN: ls %t.cache | count 3 +; RUN: lld-link /lldltocache:%t.cache /entry:main /out:%t3 %t2.o %t.o /mllvm:-emit-dwarf-unwind=default +; RUN: ls %t.cache | count 5 +; RUN: lld-link /lldltocache:%t.cache /entry:main /out:%t3 %t2.o %t.o /mllvm:-enable-ml-inliner=default +; RUN: ls %t.cache | count 5 +; RUN: lld-link /lldltocache:%t.cache /entry:main /out:%t3 %t2.o %t.o /mllvm:-enable-ml-inliner=default /mllvm:-emit-dwarf-unwind=default +; RUN: ls %t.cache | count 7 +; RUN: lld-link /lldltocache:%t.cache /entry:main /out:%t3 %t2.o %t.o /mllvm:-emit-dwarf-unwind=default /mllvm:-enable-ml-inliner=default +; RUN: ls %t.cache | count 9 + target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc" diff --git a/lld/test/ELF/lto/cache.ll b/lld/test/ELF/lto/cache.ll --- a/lld/test/ELF/lto/cache.ll +++ b/lld/test/ELF/lto/cache.ll @@ -81,6 +81,20 @@ ; RUN: ld.lld --thinlto-cache-dir=%t.cache -o %t3 %t2.o %t.o -mllvm -enable-ml-inliner=default -mllvm -max-devirt-iterations=1 ; RUN: ls %t.cache | count 5 +;; Same flag value passed to different flags matters, and switching the order +;; of the two flags matters. +; RUN: rm -rf %t.cache && mkdir %t.cache +; RUN: ld.lld --thinlto-cache-dir=%t.cache -o %t3 %t2.o %t.o -mllvm -enable-ml-inliner=default +; RUN: ls %t.cache | count 3 +; RUN: ld.lld --thinlto-cache-dir=%t.cache -o %t3 %t2.o %t.o -mllvm -emit-dwarf-unwind=default +; RUN: ls %t.cache | count 5 +; RUN: ld.lld --thinlto-cache-dir=%t.cache -o %t3 %t2.o %t.o -mllvm -enable-ml-inliner=default +; RUN: ls %t.cache | count 5 +; RUN: ld.lld --thinlto-cache-dir=%t.cache -o %t3 %t2.o %t.o -mllvm -enable-ml-inliner=default -mllvm -emit-dwarf-unwind=default +; RUN: ls %t.cache | count 7 +; RUN: ld.lld --thinlto-cache-dir=%t.cache -o %t3 %t2.o %t.o -mllvm -emit-dwarf-unwind=default -mllvm -enable-ml-inliner=default +; RUN: ls %t.cache | count 9 + target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lld/test/MachO/lto-cache.ll b/lld/test/MachO/lto-cache.ll --- a/lld/test/MachO/lto-cache.ll +++ b/lld/test/MachO/lto-cache.ll @@ -69,6 +69,51 @@ ; CHECK: llvmcache-newer ; CHECK-NOT: llvmcache-old +;; Check that mllvm options participate in the cache key +; RUN: rm -rf %t/cache && mkdir %t/cache +; RUN: %lld -cache_path_lto %t/cache -o %t/test %t/foo.o %t/bar.o +; RUN: ls %t/cache | count 3 +; RUN: %lld -cache_path_lto %t/cache -o %t/test %t/foo.o %t/bar.o -mllvm -enable-ml-inliner=default +; RUN: ls %t/cache | count 5 + +;; Adding another option resuls in 2 more cache entries +; RUN: rm -rf %t/cache && mkdir %t/cache +; RUN: %lld -cache_path_lto %t/cache -o %t/test %t/foo.o %t/bar.o +; RUN: ls %t/cache | count 3 +; RUN: %lld -cache_path_lto %t/cache -o %t/test %t/foo.o %t/bar.o -mllvm -enable-ml-inliner=default +; RUN: ls %t/cache | count 5 +; RUN: %lld -cache_path_lto %t/cache -o %t/test %t/foo.o %t/bar.o -mllvm -enable-ml-inliner=default -mllvm -max-devirt-iterations=1 +; RUN: ls %t/cache | count 7 + +;; Changing order may matter - e.g. if overriding -mllvm options - so we get 2 more entries +; RUN: %lld -cache_path_lto %t/cache -o %t/test %t/foo.o %t/bar.o -mllvm -max-devirt-iterations=1 -mllvm -enable-ml-inliner=default +; RUN: ls %t/cache | count 9 + +;; Going back to a pre-cached order doesn't create more entries. +; RUN: %lld -cache_path_lto %t/cache -o %t/test %t/foo.o %t/bar.o -mllvm -enable-ml-inliner=default -mllvm -max-devirt-iterations=1 +; RUN: ls %t/cache | count 9 + +;; Different flag values matter +; RUN: rm -rf %t/cache && mkdir %t/cache +; RUN: %lld -cache_path_lto %t/cache -o %t/test %t/foo.o %t/bar.o -mllvm -enable-ml-inliner=default -mllvm -max-devirt-iterations=2 +; RUN: ls %t/cache | count 3 +; RUN: %lld -cache_path_lto %t/cache -o %t/test %t/foo.o %t/bar.o -mllvm -enable-ml-inliner=default -mllvm -max-devirt-iterations=1 +; RUN: ls %t/cache | count 5 + +;; Same flag value passed to different flags matters, and switching the order +;; of the two flags matters. +; RUN: rm -rf %t/cache && mkdir %t/cache +; RUN: %lld -cache_path_lto %t/cache -o %t/test %t/foo.o %t/bar.o -mllvm -enable-ml-inliner=default +; RUN: ls %t/cache | count 3 +; RUN: %lld -cache_path_lto %t/cache -o %t/test %t/foo.o %t/bar.o -mllvm -emit-dwarf-unwind=default +; RUN: ls %t/cache | count 5 +; RUN: %lld -cache_path_lto %t/cache -o %t/test %t/foo.o %t/bar.o -mllvm -enable-ml-inliner=default +; RUN: ls %t/cache | count 5 +; RUN: %lld -cache_path_lto %t/cache -o %t/test %t/foo.o %t/bar.o -mllvm -enable-ml-inliner=default -mllvm -emit-dwarf-unwind=default +; RUN: ls %t/cache | count 7 +; RUN: %lld -cache_path_lto %t/cache -o %t/test %t/foo.o %t/bar.o -mllvm -emit-dwarf-unwind=default -mllvm -enable-ml-inliner=default +; RUN: ls %t/cache | count 9 + ;--- foo.ll target triple = "x86_64-apple-macosx10.15.0"