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.insert(config->mllvmOpts.end(), 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 (const auto 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 @@ -51,6 +51,23 @@ ; CHECK: llvmcache-newer ; CHECK-NOT: llvmcache-old +; Check that mllvm options participate in the cache key +; RUN: rm -rf %t.cache +; RUN: 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: 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 + 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 @@ -48,6 +48,7 @@ TargetOptions Options; std::vector MAttrs; std::vector PassPlugins; + std::vector MllvmArgs; /// For adding passes that run right before codegen. std::function PreCodeGenPassesHook; Optional RelocModel = Reloc::PIC_; 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);