Index: lld/COFF/Config.h =================================================================== --- lld/COFF/Config.h +++ lld/COFF/Config.h @@ -10,6 +10,7 @@ #define LLD_COFF_CONFIG_H #include "llvm/ADT/MapVector.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.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; Index: lld/COFF/Driver.cpp =================================================================== --- lld/COFF/Driver.cpp +++ 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()); Index: lld/COFF/LTO.cpp =================================================================== --- lld/COFF/LTO.cpp +++ 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. Index: lld/ELF/Driver.cpp =================================================================== --- lld/ELF/Driver.cpp +++ 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()); } Index: lld/MachO/Config.h =================================================================== --- lld/MachO/Config.h +++ lld/MachO/Config.h @@ -209,6 +209,7 @@ SymtabPresence localSymbolsPresence = SymtabPresence::All; SymbolPatterns localSymbolPatterns; + llvm::SmallVector mllvmOpts; bool zeroModTime = true; Index: lld/MachO/Driver.cpp =================================================================== --- lld/MachO/Driver.cpp +++ 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(); Index: lld/MachO/LTO.cpp =================================================================== --- lld/MachO/LTO.cpp +++ 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(); Index: lld/test/COFF/lto-cache.ll =================================================================== --- lld/test/COFF/lto-cache.ll +++ 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" Index: lld/test/ELF/lto/cache.ll =================================================================== --- lld/test/ELF/lto/cache.ll +++ 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" Index: lld/test/MachO/lto-cache.ll =================================================================== --- lld/test/MachO/lto-cache.ll +++ 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"