Index: lld/ELF/Config.h =================================================================== --- lld/ELF/Config.h +++ lld/ELF/Config.h @@ -18,6 +18,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/LTO/LTO.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/CachePruning.h" #include "llvm/Support/CodeGen.h" @@ -414,6 +415,8 @@ // this means to map the primary and thread stacks as PROT_MTE. Note: This is // not supported on Android 11 & 12. bool androidMemtagStack; + // When using a unified pre-link LTO pipeline, specify the backend LTO mode. + llvm::lto::LTO::LTOKind forceLTOMode = llvm::lto::LTO::LTOK_Default; unsigned threadCount; Index: lld/ELF/Driver.cpp =================================================================== --- lld/ELF/Driver.cpp +++ lld/ELF/Driver.cpp @@ -1489,6 +1489,19 @@ config->mllvmOpts.emplace_back(arg->getValue()); } + config->forceLTOMode = llvm::lto::LTO::LTOK_Default; + if (auto *arg = args.getLastArg(OPT_lto)) { + StringRef s = arg->getValue(); + if (s == "thin") + config->forceLTOMode = llvm::lto::LTO::LTOK_UnifiedThin; + else if (s == "full") + config->forceLTOMode = llvm::lto::LTO::LTOK_UnifiedRegular; + else if (s == "default") + config->forceLTOMode = llvm::lto::LTO::LTOK_Default; + else + error("unknown LTO mode: " + s); + } + // --threads= takes a positive integer and provides the default value for // --thinlto-jobs=. If unspecified, cap the number of threads since // overhead outweighs optimization for used parallel algorithms for the Index: lld/ELF/LTO.cpp =================================================================== --- lld/ELF/LTO.cpp +++ lld/ELF/LTO.cpp @@ -206,8 +206,8 @@ config->thinLTOEmitImportsFiles); } - ltoObj = std::make_unique(createConfig(), backend, - config->ltoPartitions); + ltoObj = std::make_unique( + createConfig(), backend, config->ltoPartitions, config->forceLTOMode); // Initialize usedStartStop. if (ctx.bitcodeFiles.empty()) Index: lld/ELF/Options.td =================================================================== --- lld/ELF/Options.td +++ lld/ELF/Options.td @@ -577,6 +577,9 @@ def: Flag<["-"], "V">, Alias, HelpText<"Alias for -v">; // LTO-related options. + +def lto: J<"lto=">, HelpText<"Set LTO backend">, + MetaVarName<"[full,thin]">; def lto_aa_pipeline: JJ<"lto-aa-pipeline=">, HelpText<"AA pipeline to run during LTO. Used in conjunction with -lto-newpm-passes">; def lto_debug_pass_manager: FF<"lto-debug-pass-manager">, Index: lld/test/ELF/lto/unified-lto.ll =================================================================== --- /dev/null +++ lld/test/ELF/lto/unified-lto.ll @@ -0,0 +1,35 @@ +; REQUIRES: x86 +; RUN: opt -thinlto-bc -thinlto-split-lto-unit -unified-lto %s -o %t0.o +; RUN: opt -thinlto-bc -thinlto-split-lto-unit %s -o %t1.o +; RUN: ld.lld --lto=full %t0.o -o %t0 +; RUN: llvm-readelf -s --symbols %t0 | FileCheck %s --check-prefix=FULL +; RUN: ld.lld --lto=thin %t0.o -o %t0 +; RUN: llvm-readelf -s --symbols %t0 | FileCheck %s --check-prefix=THIN +; RUN: ld.lld --lto=default %t0.o -o %t0 +; RUN: llvm-readelf -s --symbols %t0 | FileCheck %s --check-prefix=THIN +; RUN: ld.lld --lto=default %t1.o -o %t1 +; RUN: llvm-readelf -s --symbols %t1 | FileCheck %s --check-prefix=THIN +; RUN: ld.lld %t0.o -o %t0 2>&1 | count 0 +; RUN: llvm-readelf -s --symbols %t0 | FileCheck %s --check-prefix=THIN +; RUN: not ld.lld --lto=unknown %t1.o -o /dev/null 2>&1 | \ +; RUN: FileCheck --implicit-check-not=error: --check-prefix=ERR %s +; ERR: error: unknown LTO mode: unknown + +; FULL: Symbol table '.symtab' contains 3 entries: +; FULL-NEXT: Num: Value Size Type Bind Vis Ndx Name +; FULL-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND +; FULL-NEXT: 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS ld-temp.o +; FULL-NEXT: 2: 0000000000201120 1 FUNC GLOBAL DEFAULT 1 _start + +; THIN: Symbol table '.symtab' contains 3 entries: +; THIN-NEXT: Num: Value Size Type Bind Vis Ndx Name +; THIN-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND +; THIN-NEXT: 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS unified-lto.ll +; THIN-NEXT: 2: 0000000000201120 1 FUNC GLOBAL DEFAULT 1 _start + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + +define void @_start() { + ret void +}