[lld] ab9b3c8 - [lld] A Unified LTO Bitcode Frontend

Matthew Voss via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 18 16:20:49 PDT 2023


Author: Matthew Voss
Date: 2023-07-18T16:13:58-07:00
New Revision: ab9b3c84a588f86e7f66eeb577bea7155817ff06

URL: https://github.com/llvm/llvm-project/commit/ab9b3c84a588f86e7f66eeb577bea7155817ff06
DIFF: https://github.com/llvm/llvm-project/commit/ab9b3c84a588f86e7f66eeb577bea7155817ff06.diff

LOG: [lld] A Unified LTO Bitcode Frontend

The unified LTO pipeline creates a single LTO bitcode structure that can
be used by Thin or Full LTO. This means that the LTO mode can be chosen
at link time and that all LTO bitcode produced by the pipeline is
compatible, from an optimization perspective. This makes the behavior of
LTO a bit more predictable by normalizing the set of LTO features
supported by each LTO bitcode file.

Example usage:

clang -flto -funified-lto -fuse-ld=lld foo.c

clang -flto=thin -funified-lto -fuse-ld=lld foo.c

clang -c -flto -funified-lto foo.c  # -flto={full,thin} are identical in
terms of compilation actions
clang -flto=thin -fuse-ld=lld foo.o # pass --lto=thin to ld.lld

clang -c -flto -funified-lto foo.c clang -flto -fuse-ld=lld foo.o

The RFC discussing the details and rational for this change is here:
https://discourse.llvm.org/t/rfc-a-unified-lto-bitcode-frontend/61774

Differential Revision: https://reviews.llvm.org/D123805

Added: 
    lld/test/ELF/lto/unified-lto.ll

Modified: 
    lld/ELF/Config.h
    lld/ELF/Driver.cpp
    lld/ELF/LTO.cpp
    lld/ELF/Options.td

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 797b7720a38fe5..bbf2d201564581 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -96,6 +96,9 @@ enum class SeparateSegmentKind { None, Code, Loadable };
 // 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;
@@ -415,6 +418,9 @@ struct Config {
   // 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.

diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 26283e1fac0969..4e3ab2cc425a14 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1489,6 +1489,19 @@ static void readConfigs(opt::InputArgList &args) {
     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

diff  --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index 9d927b0ecfda91..e8bfa903726d0e 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -206,8 +206,13 @@ BitcodeCompiler::BitcodeCompiler() {
         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())

diff  --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 5de93f025856f2..0d5c6c3d80a106 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -577,6 +577,9 @@ def: JoinedOrSeparate<["-"], "u">, Alias<undefined>, HelpText<"Alias for --undef
 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">,

diff  --git a/lld/test/ELF/lto/unified-lto.ll b/lld/test/ELF/lto/unified-lto.ll
new file mode 100644
index 00000000000000..50d960616c8f22
--- /dev/null
+++ b/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 %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
+}


        


More information about the llvm-commits mailing list