diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 1c338cc63fa87..8e86d5493b3d0 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -102,6 +102,12 @@ enum class ICFLevel { // behavior. }; +enum class LTOKind{ + Default, // Any LTO mode without Unified LTO. The default mode. + UnifiedRegular, // Regular LTO, with Unified LTO enabled. + UnifiedThin // ThinLTO, with Unified LTO enabled. +}; + // Global configuration. struct Configuration { enum ManifestKind { Default, SideBySide, Embed, No }; @@ -317,6 +323,8 @@ struct Configuration { bool writeCheckSum = false; EmitKind emit = EmitKind::Obj; bool allowDuplicateWeak = false; + LTOKind ltoKind; + bool useDefaultPipeline = false; }; } // namespace lld::coff diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 5613c2e6993a5..44cb85f694b1e 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1882,6 +1882,15 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { if (s.getAsInteger(10, config->ltoPartitions) || config->ltoPartitions == 0) error("/opt:lldltopartitions: invalid partition count: " + s); + } else if (s.consume_front("lldltobackend=")) { + config->ltoKind = StringSwitch(s) + .Case("default", LTOKind::Default) + .Case("unifiedthin", LTOKind::UnifiedThin) + .Case("unifiedregular", LTOKind::UnifiedRegular) + .Default(LTOKind::Default); + + } else if (s.equals("ltodefaultpipeline")) { + config->useDefaultPipeline = true; } else if (s != "lbr" && s != "nolbr") error("/opt: unknown option: " + s); } diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp index 7df9319112136..20942e6e55d3d 100644 --- a/lld/COFF/LTO.cpp +++ b/lld/COFF/LTO.cpp @@ -47,6 +47,19 @@ std::string BitcodeCompiler::getThinLTOOutputFile(StringRef path) { return lto::getThinLTOOutputFile(path, ctx.config.thinLTOPrefixReplaceOld, ctx.config.thinLTOPrefixReplaceNew); } +static lto::LTO::LTOKind toLTOKind(LTOKind kind) { + switch (kind) { + case LTOKind::Default: { + return lto::LTO::LTOK_Default; + } + case LTOKind::UnifiedRegular: { + return lto::LTO::LTOK_UnifiedRegular; + } + case LTOKind::UnifiedThin: { + return lto::LTO::LTOK_UnifiedThin; + } + } +} lto::Config BitcodeCompiler::createConfig() { lto::Config c; @@ -88,6 +101,7 @@ lto::Config BitcodeCompiler::createConfig() { c.PGOWarnMismatch = ctx.config.ltoPGOWarnMismatch; c.TimeTraceEnabled = ctx.config.timeTraceEnabled; c.TimeTraceGranularity = ctx.config.timeTraceGranularity; + c.UseDefaultPipeline = ctx.config.useDefaultPipeline; if (ctx.config.emit == EmitKind::LLVM) { c.PostInternalizeModuleHook = [this](size_t task, const Module &m) { @@ -126,8 +140,9 @@ BitcodeCompiler::BitcodeCompiler(COFFLinkerContext &c) : ctx(c) { llvm::heavyweight_hardware_concurrency(ctx.config.thinLTOJobs)); } + lto::LTO::LTOKind kind = toLTOKind(ctx.config.ltoKind); ltoObj = std::make_unique(createConfig(), backend, - ctx.config.ltoPartitions); + ctx.config.ltoPartitions, kind); } BitcodeCompiler::~BitcodeCompiler() = default;