diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -152,6 +152,7 @@ llvm::SmallVector undefined; llvm::SmallVector dynamicList; llvm::SmallVector buildIdVector; + llvm::SmallVector mllvmOpts; llvm::MapVector, uint64_t> callGraphProfile; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1347,8 +1347,10 @@ config->passPlugins = args::getStrings(args, OPT_load_pass_plugins); // Parse -mllvm options. - for (auto *arg : args.filtered(OPT_mllvm)) + for (auto *arg : args.filtered(OPT_mllvm)) { parseClangOption(arg->getValue(), arg->getSpelling()); + config->mllvmOpts.emplace_back(arg->getValue()); + } // --threads= takes a positive integer and provides the default value for // --thinlto-jobs=. diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -79,6 +79,8 @@ c.Options = initTargetOptionsFromCodeGenFlags(); c.Options.RelaxELFRelocations = true; c.Options.EmitAddrsig = true; + for (StringRef C : config->mllvmOpts) + c.MllvmArgs.emplace_back(C.str()); // Always emit a section per function/datum with LTO. c.Options.FunctionSections = true; 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 @@ -38,8 +38,7 @@ ; RUN: ls %t.cache | count 3 ; Check that we remove the least recently used file first. -; RUN: rm -fr %t.cache -; RUN: mkdir %t.cache +; RUN: rm -fr %t.cache && mkdir %t.cache ; RUN: echo xyz > %t.cache/llvmcache-old ; RUN: touch -t 198002011200 %t.cache/llvmcache-old ; RUN: echo xyz > %t.cache/llvmcache-newer @@ -51,6 +50,37 @@ ; 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: ld.lld --thinlto-cache-dir=%t.cache -o %t3 %t2.o %t.o +; RUN: ls %t.cache | count 3 +; 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 + +;; Adding another option resuls in 2 more cache entries +; RUN: rm -rf %t.cache && mkdir %t.cache +; RUN: ld.lld --thinlto-cache-dir=%t.cache -o %t3 %t2.o %t.o +; RUN: ls %t.cache | count 3 +; 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 -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: ld.lld --thinlto-cache-dir=%t.cache -o %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: 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 9 + +;; Different flag values matter +; 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 -mllvm -max-devirt-iterations=2 +; RUN: ls %t.cache | count 3 +; 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 + 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/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h --- a/llvm/include/llvm/LTO/Config.h +++ b/llvm/include/llvm/LTO/Config.h @@ -47,6 +47,7 @@ std::string CPU; TargetOptions Options; std::vector MAttrs; + std::vector MllvmArgs; std::vector PassPlugins; /// For adding passes that run right before codegen. std::function PreCodeGenPassesHook; diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -131,6 +131,8 @@ AddUnsigned(*Conf.CodeModel); else AddUnsigned(-1); + for (const auto &S : Conf.MllvmArgs) + AddString(S); AddUnsigned(Conf.CGOptLevel); AddUnsigned(Conf.CGFileType); AddUnsigned(Conf.OptLevel);