[lld] r369694 - [COFF] Add libcall symbols to the link when LTO is being used

Amy Huang via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 22 12:40:07 PDT 2019


Author: akhuang
Date: Thu Aug 22 12:40:07 2019
New Revision: 369694

URL: http://llvm.org/viewvc/llvm-project?rev=369694&view=rev
Log:
[COFF] Add libcall symbols to the link when LTO is being used

Added:
    lld/trunk/test/COFF/Inputs/libcall-archive.ll
    lld/trunk/test/COFF/Inputs/libcall-archive.s
    lld/trunk/test/COFF/libcall-archive.ll
Modified:
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/SymbolTable.cpp
    lld/trunk/COFF/SymbolTable.h
    lld/trunk/COFF/Symbols.cpp
    lld/trunk/COFF/Symbols.h

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=369694&r1=369693&r2=369694&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Thu Aug 22 12:40:07 2019
@@ -1055,6 +1055,12 @@ void LinkerDriver::maybeExportMinGWSymbo
   });
 }
 
+static const char *libcallRoutineNames[] = {
+#define HANDLE_LIBCALL(code, name) name,
+#include "llvm/IR/RuntimeLibcalls.def"
+#undef HANDLE_LIBCALL
+};
+
 void LinkerDriver::link(ArrayRef<const char *> argsArr) {
   // Needed for LTO.
   InitializeAllTargetInfos();
@@ -1758,6 +1764,15 @@ void LinkerDriver::link(ArrayRef<const c
           u->weakAlias = symtab->addUndefined(to);
     }
 
+    // If any inputs are bitcode files, the LTO code generator may create
+    // references to library functions that are not explicit in the bitcode
+    // file's symbol table. If any of those library functions are defined in a
+    // bitcode file in an archive member, we need to arrange to use LTO to
+    // compile those archive members by adding them to the link beforehand.
+    if (!BitcodeFile::instances.empty())
+      for (const char *s : libcallRoutineNames)
+        symtab->addLibcall(s);
+
     // Windows specific -- if __load_config_used can be resolved, resolve it.
     if (symtab->findUnderscore("_load_config_used"))
       addUndefined(mangle("_load_config_used"));

Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=369694&r1=369693&r2=369694&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Thu Aug 22 12:40:07 2019
@@ -584,6 +584,18 @@ Symbol *SymbolTable::addImportThunk(Stri
   return nullptr;
 }
 
+void SymbolTable::addLibcall(StringRef name) {
+  Symbol *sym = findUnderscore(name);
+  if (!sym)
+    return;
+
+  if (Lazy *l = dyn_cast<Lazy>(sym)) {
+    MemoryBufferRef mb = l->getMemberBuffer();
+    if (identify_magic(mb.getBuffer()) == llvm::file_magic::bitcode)
+      addUndefined(sym->getName());
+  }
+}
+
 std::vector<Chunk *> SymbolTable::getChunks() {
   std::vector<Chunk *> res;
   for (ObjFile *file : ObjFile::instances) {

Modified: lld/trunk/COFF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.h?rev=369694&r1=369693&r2=369694&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.h (original)
+++ lld/trunk/COFF/SymbolTable.h Thu Aug 22 12:40:07 2019
@@ -100,6 +100,7 @@ public:
   Symbol *addImportData(StringRef n, ImportFile *f);
   Symbol *addImportThunk(StringRef name, DefinedImportData *s,
                          uint16_t machine);
+  void addLibcall(StringRef name);
 
   void reportDuplicate(Symbol *existing, InputFile *newFile);
 

Modified: lld/trunk/COFF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.cpp?rev=369694&r1=369693&r2=369694&view=diff
==============================================================================
--- lld/trunk/COFF/Symbols.cpp (original)
+++ lld/trunk/COFF/Symbols.cpp Thu Aug 22 12:40:07 2019
@@ -118,5 +118,14 @@ Defined *Undefined::getWeakAlias() {
       return d;
   return nullptr;
 }
+
+MemoryBufferRef Lazy::getMemberBuffer() {
+  Archive::Child c =
+    CHECK(sym.getMember(),
+          "could not get the member for symbol " + toCOFFString(sym));
+  return CHECK(c.getMemoryBufferRef(),
+      "could not get the buffer for the member defining symbol " +
+      toCOFFString(sym));
+}
 } // namespace coff
 } // namespace lld

Modified: lld/trunk/COFF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.h?rev=369694&r1=369693&r2=369694&view=diff
==============================================================================
--- lld/trunk/COFF/Symbols.h (original)
+++ lld/trunk/COFF/Symbols.h Thu Aug 22 12:40:07 2019
@@ -265,6 +265,8 @@ public:
 
   static bool classof(const Symbol *s) { return s->kind() == LazyKind; }
 
+  MemoryBufferRef getMemberBuffer();
+
   ArchiveFile *file;
 
 private:

Added: lld/trunk/test/COFF/Inputs/libcall-archive.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/libcall-archive.ll?rev=369694&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/libcall-archive.ll (added)
+++ lld/trunk/test/COFF/Inputs/libcall-archive.ll Thu Aug 22 12:40:07 2019
@@ -0,0 +1,6 @@
+target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
+target triple = "i686-unknown-windows"
+
+define void @memcpy() {
+  ret void
+}

Added: lld/trunk/test/COFF/Inputs/libcall-archive.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/libcall-archive.s?rev=369694&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/libcall-archive.s (added)
+++ lld/trunk/test/COFF/Inputs/libcall-archive.s Thu Aug 22 12:40:07 2019
@@ -0,0 +1,2 @@
+.globl ___sync_val_compare_and_swap_8
+___sync_val_compare_and_swap_8:

Added: lld/trunk/test/COFF/libcall-archive.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/libcall-archive.ll?rev=369694&view=auto
==============================================================================
--- lld/trunk/test/COFF/libcall-archive.ll (added)
+++ lld/trunk/test/COFF/libcall-archive.ll Thu Aug 22 12:40:07 2019
@@ -0,0 +1,22 @@
+; REQUIRES: x86
+; RUN: rm -f %t.a
+; RUN: llvm-as -o %t.obj %s
+; RUN: llvm-as -o %t2.obj %S/Inputs/libcall-archive.ll
+; RUN: llvm-mc -filetype=obj -triple=i686-unknown-windows -o %t3.obj %S/Inputs/libcall-archive.s
+; RUN: llvm-ar rcs %t.a %t2.obj %t3.obj
+; RUN: lld-link -out:%t.exe -subsystem:console -entry:start -safeseh:no -lldmap:- %t.obj %t.a | FileCheck %s
+
+; CHECK-NOT: ___sync_val_compare_and_swap_8
+; CHECK: _start
+; CHECK: _memcpy
+
+target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
+target triple = "i686-unknown-windows"
+
+define void @start(i8* %a, i8* %b) {
+entry:
+  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 1024, i1 false)
+  ret void
+}
+
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1)




More information about the llvm-commits mailing list