llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld

@llvm/pr-subscribers-clang-codegen

Author: Daniel Thornburgh (mysterymath)

<details>
<summary>Changes</summary>

This reverts commit 1ec7e86b3a779df2a0af3f37e58c8f5b3a398d7f after issue #<!-- 
-->190072 was fixed.

---

Patch is 45.27 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/190642.diff


25 Files Affected:

- (modified) clang/lib/CodeGen/BackendUtil.cpp (+7-5) 
- (modified) lld/COFF/InputFiles.cpp (+1-4) 
- (modified) lld/COFF/LTO.cpp (+4) 
- (modified) lld/COFF/LTO.h (+1) 
- (modified) lld/COFF/SymbolTable.cpp (+24) 
- (modified) lld/ELF/Driver.cpp (+19) 
- (modified) lld/ELF/LTO.cpp (+4) 
- (modified) lld/ELF/LTO.h (+1) 
- (added) lld/test/COFF/lto-libcall-archive-bitcode.test (+51) 
- (added) lld/test/ELF/lto/libcall-archive-bitcode.test (+54) 
- (added) lld/test/wasm/lto/libcall-archive-bitcode.ll (+56) 
- (modified) lld/wasm/LTO.cpp (+4) 
- (modified) lld/wasm/LTO.h (+1) 
- (modified) lld/wasm/SymbolTable.cpp (+23) 
- (modified) llvm/docs/ReleaseNotes.md (+7) 
- (modified) llvm/include/llvm/LTO/LTO.h (+25-4) 
- (modified) llvm/include/llvm/LTO/LTOBackend.h (+12-10) 
- (modified) llvm/lib/LTO/LTO.cpp (+52-19) 
- (modified) llvm/lib/LTO/LTOBackend.cpp (+27-7) 
- (modified) llvm/lib/LTO/LTOCodeGenerator.cpp (+2-2) 
- (modified) llvm/lib/LTO/ThinLTOCodeGenerator.cpp (+3-1) 
- (added) llvm/test/LTO/Resolution/X86/libcall-external.ll (+25) 
- (added) llvm/test/LTO/Resolution/X86/libcall-in-thin-link.ll (+35) 
- (added) llvm/test/LTO/Resolution/X86/libcall-in-tu.ll (+34) 
- (modified) llvm/tools/llvm-lto2/llvm-lto2.cpp (+16) 


``````````diff
diff --git a/clang/lib/CodeGen/BackendUtil.cpp 
b/clang/lib/CodeGen/BackendUtil.cpp
index 5b8b4083c2ac0..74c8bf1c670da 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1410,12 +1410,14 @@ runThinLTOBackend(CompilerInstance &CI, 
ModuleSummaryIndex *CombinedIndex,
 
   // FIXME: Both ExecuteAction and thinBackend set up optimization remarks for
   // the same context.
+  // FIXME: This does not yet set the list of bitcode libfuncs that it isn't
+  // safe to call. This precludes bitcode libc in distributed ThinLTO.
   finalizeLLVMOptimizationRemarks(M->getContext());
-  if (Error E =
-          thinBackend(Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
-                      ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
-                      /*ModuleMap=*/nullptr, Conf.CodeGenOnly,
-                      /*IRAddStream=*/nullptr, CGOpts.CmdArgs)) {
+  if (Error E = thinBackend(
+          Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
+          ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
+          /*ModuleMap=*/nullptr, Conf.CodeGenOnly, /*BitcodeLibFuncs=*/{},
+          /*IRAddStream=*/nullptr, CGOpts.CmdArgs)) {
     handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
       errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';
     });
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index e797da6effb35..9040d9653d2b2 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -25,7 +25,6 @@
 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
 #include "llvm/IR/Mangler.h"
-#include "llvm/IR/RuntimeLibcalls.h"
 #include "llvm/LTO/LTO.h"
 #include "llvm/Object/Binary.h"
 #include "llvm/Object/COFF.h"
@@ -1394,8 +1393,6 @@ void BitcodeFile::parse() {
     // FIXME: Check nodeduplicate
     comdat[i] =
         symtab.addComdat(this, saver.save(obj->getComdatTable()[i].first));
-  Triple tt(obj->getTargetTriple());
-  RTLIB::RuntimeLibcallsInfo libcalls(tt);
   for (const lto::InputFile::Symbol &objSym : obj->symbols()) {
     StringRef symName = saver.save(objSym.getName());
     int comdatIndex = objSym.getComdatIndex();
@@ -1445,7 +1442,7 @@ void BitcodeFile::parse() {
           symtab.addRegular(this, symName, nullptr, fakeSC, 0, 
objSym.isWeak());
     }
     symbols.push_back(sym);
-    if (objSym.isUsed() || objSym.isLibcall(libcalls))
+    if (objSym.isUsed())
       symtab.ctx.config.gcroot.push_back(sym);
   }
   directives = saver.save(obj->getCOFFLinkerOpts());
diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp
index 2d38a13830dad..445ea52e995da 100644
--- a/lld/COFF/LTO.cpp
+++ b/lld/COFF/LTO.cpp
@@ -288,3 +288,7 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
 
   return ret;
 }
+
+void BitcodeCompiler::setBitcodeLibFuncs(ArrayRef<StringRef> bitcodeLibFuncs) {
+  ltoObj->setBitcodeLibFuncs(bitcodeLibFuncs);
+}
diff --git a/lld/COFF/LTO.h b/lld/COFF/LTO.h
index 6826251b5ffa7..73e855e567b09 100644
--- a/lld/COFF/LTO.h
+++ b/lld/COFF/LTO.h
@@ -45,6 +45,7 @@ class BitcodeCompiler {
 
   void add(BitcodeFile &f);
   std::vector<InputFile *> compile();
+  void setBitcodeLibFuncs(ArrayRef<StringRef> bitcodeLibFuncs);
 
 private:
   std::unique_ptr<llvm::lto::LTO> ltoObj;
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index 38a43390c15ab..fef9bc54fd8a6 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -1437,13 +1437,37 @@ void SymbolTable::compileBitcodeFiles() {
   if (bitcodeFileInstances.empty())
     return;
 
+  // Collect the bitcode library functions that are not safe to call because
+  // they were not yet brought in the link. (Such symbols are lazy.)
+  llvm::BumpPtrAllocator alloc;
+  llvm::StringSaver saver(alloc);
+  SmallVector<StringRef> bitcodeLibFuncs;
+  // Triple must be captured before the bitcode is moved into the compiler.
+  // Note that the below assumes that the set of possible libfuncs is roughly
+  // equivalent for all bitcode translation units.
+  llvm::Triple tt =
+      llvm::Triple(bitcodeFileInstances.front()->obj->getTargetTriple());
+  for (StringRef libFunc : lto::LTO::getLibFuncSymbols(tt, saver)) {
+    if (Symbol *sym = find(libFunc)) {
+      if (auto *l = dyn_cast<LazyArchive>(sym)) {
+        if (isBitcode(l->getMemberBuffer()))
+          bitcodeLibFuncs.push_back(libFunc);
+      } else if (auto *o = dyn_cast<LazyObject>(sym)) {
+        if (isBitcode(o->file->mb))
+          bitcodeLibFuncs.push_back(libFunc);
+      }
+    }
+  }
+
   ScopedTimer t(ctx.ltoTimer);
   lto.reset(new BitcodeCompiler(ctx));
+  lto->setBitcodeLibFuncs(bitcodeLibFuncs);
   {
     llvm::TimeTraceScope addScope("Add bitcode file instances");
     for (BitcodeFile *f : bitcodeFileInstances)
       lto->add(*f);
   }
+
   for (InputFile *newObj : lto->compile()) {
     ObjFile *obj = cast<ObjFile>(newObj);
     obj->parse();
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 949314fd70ed2..09aa6af5ee2c7 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2774,8 +2774,27 @@ static void markBuffersAsDontNeed(Ctx &ctx, bool 
skipLinkedOutput) {
 template <class ELFT>
 void LinkerDriver::compileBitcodeFiles(bool skipLinkedOutput) {
   llvm::TimeTraceScope timeScope("LTO");
+
+  // Collect the bitcode library functions that are not safe to call because
+  // they were not yet brought in the link. (Such symbols are lazy.)
+  llvm::BumpPtrAllocator alloc;
+  llvm::StringSaver saver(alloc);
+  SmallVector<StringRef> bitcodeLibFuncs;
+  if (!ctx.bitcodeFiles.empty()) {
+    // Triple must be captured before the bitcode is moved into the compiler.
+    // Note that the below assumes that the set of possible libfuncs is roughly
+    // equivalent for all bitcode translation units.
+    llvm::Triple tt =
+        llvm::Triple(ctx.bitcodeFiles.front()->obj->getTargetTriple());
+    for (StringRef libFunc : lto::LTO::getLibFuncSymbols(tt, saver))
+      if (Symbol *sym = ctx.symtab->find(libFunc);
+          sym && sym->isLazy() && isa<BitcodeFile>(sym->file))
+        bitcodeLibFuncs.push_back(libFunc);
+  }
+
   // Compile bitcode files and replace bitcode symbols.
   lto.reset(new BitcodeCompiler(ctx));
+  lto->setBitcodeLibFuncs(bitcodeLibFuncs);
   for (BitcodeFile *file : ctx.bitcodeFiles)
     lto->add(*file);
 
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index 352848af1551d..7b0fe2001439e 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -436,3 +436,7 @@ SmallVector<std::unique_ptr<InputFile>, 0> 
BitcodeCompiler::compile() {
   }
   return ret;
 }
+
+void BitcodeCompiler::setBitcodeLibFuncs(ArrayRef<StringRef> bitcodeLibFuncs) {
+  ltoObj->setBitcodeLibFuncs(bitcodeLibFuncs);
+}
diff --git a/lld/ELF/LTO.h b/lld/ELF/LTO.h
index acf3bcff7f2f1..c8cb2156d90ca 100644
--- a/lld/ELF/LTO.h
+++ b/lld/ELF/LTO.h
@@ -43,6 +43,7 @@ class BitcodeCompiler {
 
   void add(BitcodeFile &f);
   SmallVector<std::unique_ptr<InputFile>, 0> compile();
+  void setBitcodeLibFuncs(ArrayRef<StringRef> bitcodeLibFuncs);
 
 private:
   Ctx &ctx;
diff --git a/lld/test/COFF/lto-libcall-archive-bitcode.test 
b/lld/test/COFF/lto-libcall-archive-bitcode.test
new file mode 100644
index 0000000000000..bd172f1ff3955
--- /dev/null
+++ b/lld/test/COFF/lto-libcall-archive-bitcode.test
@@ -0,0 +1,51 @@
+; REQUIRES: x86
+
+; RUN: rm -rf %t && split-file %s %t && cd %t
+; RUN: llvm-as main.ll -o main.obj
+; RUN: llvm-as puts.ll -o puts.obj
+; RUN: llvm-mc -filetype=obj -triple=x86_64-pc-windows-msvc printf.s -o 
printf.obj
+; RUN: llvm-ar rcs libc.lib puts.obj printf.obj
+
+;; Ensure that no printf->puts translation occurs during LTO because puts is in
+;; bitcode, but was not brought into the link. This would fail the link by
+;; extracting bitcode after LTO.
+; RUN: lld-link -out:out.exe -entry:main -subsystem:console -lldmap:- 
-nodefaultlib main.obj libc.lib | FileCheck %s
+
+;; Test the same behavior with lazy objects.
+; RUN: lld-link -out:out-lazy.exe -entry:main -subsystem:console -lldmap:- 
-nodefaultlib main.obj /start-lib puts.obj /end-lib printf.obj | FileCheck %s
+
+;; Test that translation DOES occur when puts is extracted and brought into 
the link.
+; RUN: lld-link -out:out-extracted.exe -entry:main -subsystem:console 
-lldmap:- -nodefaultlib main.obj puts.obj printf.obj | FileCheck %s 
--check-prefix=EXTRACTED
+
+; CHECK-NOT: puts
+; CHECK: printf
+
+; EXTRACTED: printf
+; EXTRACTED: puts
+
+;--- puts.ll
+target datalayout = 
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+define i32 @puts(ptr nocapture readonly %0) noinline {
+  call void asm sideeffect "", ""()
+  ret i32 0
+}
+
+;--- printf.s
+.globl printf
+printf:
+  ret
+
+;--- main.ll
+target datalayout = 
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+@str = constant [5 x i8] c"foo\0A\00"
+
+define i32 @main() {
+  %call = call i32 (ptr, ...) @printf(ptr @str)
+  ret i32 0
+}
+
+declare i32 @printf(ptr, ...)
diff --git a/lld/test/ELF/lto/libcall-archive-bitcode.test 
b/lld/test/ELF/lto/libcall-archive-bitcode.test
new file mode 100644
index 0000000000000..00726a2e6aeb5
--- /dev/null
+++ b/lld/test/ELF/lto/libcall-archive-bitcode.test
@@ -0,0 +1,54 @@
+; REQUIRES: x86
+
+; RUN: rm -rf %t && split-file %s %t && cd %t
+; RUN: llvm-as main.ll -o main.o
+; RUN: llvm-as puts.ll -o puts.o
+; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnu printf.s -o 
printf.o
+; RUN: llvm-ar rcs libc.a puts.o printf.o
+
+;; Ensure that no printf->puts translation occurs during LTO because puts is in
+;; bitcode, but was not brought into the link. This would fail the link by
+;; extracting bitcode after LTO.
+; RUN: ld.lld -o out main.o libc.a
+; RUN: llvm-nm out | FileCheck %s
+
+;; Test the same behavior with lazy objects.
+; RUN: ld.lld -o out-lazy main.o --start-lib puts.o --end-lib printf.o
+; RUN: llvm-nm out-lazy | FileCheck %s
+
+;; Test that translation DOES occur when puts is extracted and brought into 
the link.
+; RUN: ld.lld -o out-extracted main.o puts.o printf.o
+; RUN: llvm-nm out-extracted | FileCheck %s --check-prefix=EXTRACTED
+
+; CHECK-NOT: puts
+; CHECK: printf
+
+; EXTRACTED: printf
+; EXTRACTED: puts
+
+;--- puts.ll
+target datalayout = 
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @puts(ptr nocapture readonly %0) noinline {
+  call void asm sideeffect "", ""()
+  ret i32 0
+}
+
+;--- printf.s
+.globl printf
+printf:
+  ret
+
+;--- main.ll
+target datalayout = 
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@str = constant [5 x i8] c"foo\0A\00"
+
+define i32 @_start() {
+  %call = call i32 (ptr, ...) @printf(ptr @str)
+  ret i32 0
+}
+
+declare i32 @printf(ptr, ...)
diff --git a/lld/test/wasm/lto/libcall-archive-bitcode.ll 
b/lld/test/wasm/lto/libcall-archive-bitcode.ll
new file mode 100644
index 0000000000000..3b640efc1091f
--- /dev/null
+++ b/lld/test/wasm/lto/libcall-archive-bitcode.ll
@@ -0,0 +1,56 @@
+; REQUIRES: x86
+
+; RUN: rm -rf %t && split-file %s %t && cd %t
+; RUN: llvm-as main.ll -o main.o
+; RUN: llvm-as puts.ll -o puts.o
+; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown printf.s -o 
printf.o
+; RUN: llvm-ar rcs libc.a puts.o printf.o
+
+;; Ensure that no printf->puts translation occurs during LTO because puts is in
+;; bitcode, but was not brought into the link. This would fail the link by
+;; extracting bitcode after LTO.
+; RUN: wasm-ld -o out.wasm main.o libc.a
+; RUN: obj2yaml out.wasm | FileCheck %s
+
+;; Test the same behavior with lazy objects.
+; RUN: wasm-ld -o out-lazy.wasm main.o --start-lib puts.o --end-lib printf.o
+; RUN: obj2yaml out-lazy.wasm | FileCheck %s
+
+;; Test that translation DOES occur when puts is extracted and brought into 
the link.
+; RUN: wasm-ld -o out-extracted.wasm main.o puts.o printf.o
+; RUN: obj2yaml out-extracted.wasm | FileCheck %s --check-prefix=EXTRACTED
+
+; CHECK-NOT: Name: puts
+; CHECK:     Name: printf
+
+; EXTRACTED: Name: puts
+; EXTRACTED-NOT: Name: printf
+
+;--- puts.ll
+target datalayout = 
"e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
+target triple = "wasm32-unknown-unknown"
+
+define i32 @puts(ptr nocapture readonly %0) noinline {
+  call void asm sideeffect "", ""()
+  ret i32 0
+}
+
+;--- printf.s
+.globl printf
+printf:
+  .functype printf (i32, i32) -> (i32)
+  i32.const 0
+  end_function
+
+;--- main.ll
+target datalayout = 
"e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
+target triple = "wasm32-unknown-unknown"
+
+@str = constant [5 x i8] c"foo\0A\00"
+
+define i32 @_start() {
+  %call = call i32 (ptr, ...) @printf(ptr @str)
+  ret i32 0
+}
+
+declare i32 @printf(ptr, ...)
\ No newline at end of file
diff --git a/lld/wasm/LTO.cpp b/lld/wasm/LTO.cpp
index 9fcb95b84b545..2c068bf518905 100644
--- a/lld/wasm/LTO.cpp
+++ b/lld/wasm/LTO.cpp
@@ -195,6 +195,10 @@ static void thinLTOCreateEmptyIndexFiles() {
   }
 }
 
+void BitcodeCompiler::setBitcodeLibFuncs(ArrayRef<StringRef> bitcodeLibFuncs) {
+  ltoObj->setBitcodeLibFuncs(bitcodeLibFuncs);
+}
+
 // Merge all the bitcode files we have seen, codegen the result
 // and return the resulting objects.
 SmallVector<InputFile *, 0> BitcodeCompiler::compile() {
diff --git a/lld/wasm/LTO.h b/lld/wasm/LTO.h
index 21b1d59024663..6fa110d6099bf 100644
--- a/lld/wasm/LTO.h
+++ b/lld/wasm/LTO.h
@@ -46,6 +46,7 @@ class BitcodeCompiler {
 
   void add(BitcodeFile &f);
   SmallVector<InputFile *, 0> compile();
+  void setBitcodeLibFuncs(ArrayRef<StringRef> bitcodeLibFuncs);
 
 private:
   std::unique_ptr<llvm::lto::LTO> ltoObj;
diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index 05e653ea23eda..93d3e5f71a3e5 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -82,8 +82,31 @@ void SymbolTable::compileBitcodeFiles() {
   // Prevent further LTO objects being included
   BitcodeFile::doneLTO = true;
 
+  // Collect the bitcode library functions that are not safe to call because
+  // they were not yet brought in the link. (Such symbols are lazy.)
+  llvm::BumpPtrAllocator alloc;
+  llvm::StringSaver saver(alloc);
+  SmallVector<StringRef> bitcodeLibFuncs;
+  if (!ctx.bitcodeFiles.empty()) {
+    // Triple must be captured before the bitcode is moved into the compiler.
+    // Note that the below assumes that the set of possible libfuncs is
+    // equivalent for all bitcode translation units.
+    llvm::Triple tt =
+        llvm::Triple(ctx.bitcodeFiles.front()->obj->getTargetTriple());
+    for (StringRef libFunc : llvm::lto::LTO::getLibFuncSymbols(tt, saver)) {
+      if (Symbol *sym = find(libFunc)) {
+        if (auto *lazy = dyn_cast<LazySymbol>(sym)) {
+          if (isa<BitcodeFile>(lazy->getFile()))
+            bitcodeLibFuncs.push_back(libFunc);
+        }
+      }
+    }
+  }
+
   // Compile bitcode files and replace bitcode symbols.
   lto.reset(new BitcodeCompiler);
+  lto->setBitcodeLibFuncs(bitcodeLibFuncs);
+
   for (BitcodeFile *f : ctx.bitcodeFiles)
     lto->add(*f);
 
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index d0d8b9f4ddabc..701b386dba73e 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -101,6 +101,13 @@ Changes to LLVM infrastructure
     this may fail if symlink permissions are not available.
   * Added ``readlink``, which reads the target of a symbolic link.
 
+* Bitcode libraries can now implement compiler-managed library functions
+  (libcalls) without causing incorrect API manipulation or undefined references
+  ([#177046](https://github.com/llvm/llvm-project/pull/125687)). Note that
+  there are still issues with invalid compiler reasoning about some functions
+  in bitcode, e.g. `malloc`. Not yet supported on MachO or when using
+  distributed ThinLTO. 
+
 Changes to building LLVM
 ------------------------
 
diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h
index 3fec06b8bd78d..aba2661e81c47 100644
--- a/llvm/include/llvm/LTO/LTO.h
+++ b/llvm/include/llvm/LTO/LTO.h
@@ -179,7 +179,8 @@ class InputFile {
     // may emit references to. Such symbols must be considered external, as
     // removing them or modifying their interfaces would invalidate the code
     // generator's knowledge about them.
-    bool isLibcall(const RTLIB::RuntimeLibcallsInfo &Libcalls) const;
+    bool isLibcall(const TargetLibraryInfo &TLI,
+                   const RTLIB::RuntimeLibcallsInfo &Libcalls) const;
   };
 
   /// A range over the symbols in this InputFile.
@@ -308,7 +309,8 @@ class ThinBackendProc {
 using ThinBackendFunction = std::function<std::unique_ptr<ThinBackendProc>(
     const Config &C, ModuleSummaryIndex &CombinedIndex,
     const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
-    AddStreamFn AddStream, FileCache Cache)>;
+    AddStreamFn AddStream, FileCache Cache,
+    ArrayRef<StringRef> BitcodeLibFuncs)>;
 
 /// This type defines the behavior following the thin-link phase during 
ThinLTO.
 /// It encapsulates a backend function and a strategy for thread pool
@@ -323,10 +325,11 @@ struct ThinBackend {
   std::unique_ptr<ThinBackendProc> operator()(
       const Config &Conf, ModuleSummaryIndex &CombinedIndex,
       const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
-      AddStreamFn AddStream, FileCache Cache) {
+      AddStreamFn AddStream, FileCache Cache,
+      ArrayRef<StringRef> BitcodeLibFuncs) {
     assert(isValid() && "Invalid backend function");
     return Func(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
-                std::move(AddStream), std::move(Cache));
+                std::move(AddStream), std::move(Cache), BitcodeLibFuncs);
   }
   ThreadPoolStrategy getParallelism() const { return Parallelism; }
   bool isValid() const { return static_cast<bool>(Func); }
@@ -446,6 +449,11 @@ class LTO {
   LLVM_ABI Error add(std::unique_ptr<InputFile> Obj,
                      ArrayRef<SymbolResolution> Res);
 
+  /// Set the list of functions implemented in bitcode that were not extracted
+  /// from an archive. Such functions may not be referenced, as they have
+  /// lost their opportunity to be defined.
+  LLVM_ABI void setBitcodeLibFuncs(ArrayRef<StringRef> BitcodeLibFuncs);
+
   /// Returns an upper bound on the number of tasks that the client may expect.
   /// This may only be called after all IR object files have been added. For a
   /// full description of tasks see LTOBackend.h.
@@ -466,6 +474,14 @@ class LTO {
   LLVM_ABI static SmallVector<const char *>
   getRuntimeLibcallSymbols(const Triple &TT);
 
+  /// Static method that returns a list of library function symbols that can be
+  /// generated by LTO but might not be visible from bitcode symbol table.
+  /// Unlike the runtime libcalls, the linker can report to the code generator
+  /// which of these are actually available in the link, and the code generator
+  /// can then only reference that set of symbols.
+  LLVM_ABI static SmallVector<StringRef>
+  getLibFuncSymbols(const Triple &TT, llvm::StringSaver &Saver);
+
 protected:
   // Called at the start of run().
   virtual Error serializeInputsForDistribution() { return Error::success(); }
@@ -657,6 +673,11 @@ class LTO {
   // Setup optimization remarks according to the provided configuration.
   Error setupOptimizationRemarks();
 
+  // LibFuncs that were implemented in bitcode but were not extracted
+  // from their libraries. Such functions cannot safely be called, since
+  // they have lost their opportunity to be defined.
+  SmallVector<StringRef> BitcodeLibFuncs;
+
 public:
   /// Helper to emit an optimization remark during the LTO link when outside of
   /// the standard optimization pass pipeline.
diff --git a/llvm/include/llvm/LTO/LTOBackend.h 
b/llvm/include/llvm/LTO/LTOBackend.h
index 48ad5aa64f61f..4bb38529ec754 100644
--- a/llvm/include/llvm/LTO/LTOBackend.h
+++ b/llvm/include/llvm/LTO/LTOBackend.h
@@ -39,13 +39,15 @@ LLVM_ABI bool opt(const Config &Conf, TargetMachine *TM, 
unsigned Task,
                   Module &Mod, bool IsThinLTO,
                   ModuleSummaryIndex *ExportSummary,
                   const ModuleSummaryIndex *ImportSummary,
-                  const std::vector<uint8_t> &CmdArgs);
+                  con...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/190642
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to