// For -z *stack
enum class GnuStackKind { None, Exec, NoExec };
+// For --lto=
+enum LtoKind : uint8_t {UnifiedThin, UnifiedRegular, Default};
+
struct SymbolVersion {
llvm::StringRef name;
bool isExternCpp;
// not supported on Android 11 & 12.
bool androidMemtagStack;
+ // When using a unified pre-link LTO pipeline, specify the backend LTO mode.
+ LtoKind ltoKind = LtoKind::Default;
+
unsigned threadCount;
// If an input file equals a key, remap it to the value.
config->mllvmOpts.emplace_back(arg->getValue());
}
+ config->ltoKind = LtoKind::Default;
+ if (auto *arg = args.getLastArg(OPT_lto)) {
+ StringRef s = arg->getValue();
+ if (s == "thin")
+ config->ltoKind = LtoKind::UnifiedThin;
+ else if (s == "full")
+ config->ltoKind = LtoKind::UnifiedRegular;
+ else if (s == "default")
+ config->ltoKind = LtoKind::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
config->thinLTOEmitImportsFiles);
}
- ltoObj = std::make_unique<lto::LTO>(createConfig(), backend,
- config->ltoPartitions);
+ constexpr llvm::lto::LTO::LTOKind ltoModes[3] =
+ {llvm::lto::LTO::LTOKind::LTOK_UnifiedThin,
+ llvm::lto::LTO::LTOKind::LTOK_UnifiedRegular,
+ llvm::lto::LTO::LTOKind::LTOK_Default};
+ ltoObj = std::make_unique<lto::LTO>(
+ createConfig(), backend, config->ltoPartitions,
+ ltoModes[config->ltoKind]);
// Initialize usedStartStop.
if (ctx.bitcodeFiles.empty())
def: Flag<["-"], "V">, Alias<v>, HelpText<"Alias for -v">;
// LTO-related options.
+
+def lto: JJ<"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">,
--- /dev/null
+; 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 %t0 | FileCheck %s --check-prefix=FULL
+; RUN: ld.lld --lto=thin %t0.o -o %t0
+; RUN: llvm-readelf -s %t0 | FileCheck %s --check-prefix=THIN
+; RUN: ld.lld --lto=default %t0.o -o %t0
+; RUN: llvm-readelf -s %t0 | FileCheck %s --check-prefix=THIN
+; RUN: ld.lld --lto=default %t1.o -o %t1
+; RUN: llvm-readelf -s %t1 | FileCheck %s --check-prefix=THIN
+; RUN: ld.lld %t0.o -o %t0 2>&1 | count 0
+; RUN: llvm-readelf -s %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
+}