[PATCH] D88944: [ELF] Skip repeated libraries.

Igor Kudrin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 6 22:04:31 PDT 2020


ikudrin created this revision.
ikudrin added reviewers: bd1976llvm, MaskRay.
ikudrin added projects: LLVM, lld.
Herald added subscribers: arichardson, emaste.
Herald added a reviewer: espindola.
ikudrin requested review of this revision.

If a library is added in the link several times, there is no need to process it more than once, because LLD is able to resolve back refs. The optimization is especially useful for the dependent libraries feature, where the same library may be referenced many times in input files.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D88944

Files:
  lld/ELF/Driver.cpp
  lld/ELF/Driver.h
  lld/test/ELF/print-archive-stats.s
  lld/test/ELF/skip-repeated-libs.s


Index: lld/test/ELF/skip-repeated-libs.s
===================================================================
--- /dev/null
+++ lld/test/ELF/skip-repeated-libs.s
@@ -0,0 +1,26 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
+# RUN: echo ".global foo; foo:" | \
+# RUN:   llvm-mc -filetype=obj -triple=x86_64 - -o %t1.o
+# RUN: rm -f %t1.a && llvm-ar rc %t1.a %t1.o
+
+## The linker can resolve backrefs, so the repeated adding of the library can be skipped.
+# RUN: ld.lld %t1.a %t1.a %t.o -o /dev/null --verbose 2>&1 | FileCheck %s
+# CHECK:     {{.*}}1.a
+# CHECK-NOT: {{.*}}1.a
+
+## If the repeated definition is given after -whole-archive, it should not be skipped.
+# RUN: ld.lld %t1.a -whole-archive %t1.a %t.o -o /dev/null --verbose 2>&1 | FileCheck %s --check-prefix=WHA
+# WHA:      {{.*}}1.a
+# WHA-NEXT: {{.*}}1.a
+
+## If, for any reason, the second definition is given after -format binary,
+## it should not be skipped.
+# RUN: ld.lld %t.o %t1.a -format binary %t1.a -o %t
+# RUN: llvm-nm %t | FileCheck --check-prefix=BINARY %s
+# BINARY: D _binary_{{.+}}1_a_start
+
+  .global _start
+_start:
+  call foo
Index: lld/test/ELF/print-archive-stats.s
===================================================================
--- lld/test/ELF/print-archive-stats.s
+++ lld/test/ELF/print-archive-stats.s
@@ -20,7 +20,8 @@
 # RUN: ld.lld %t.o %tweak.a %t1.a --print-archive-stats=- -o /dev/null | diff %t.txt -
 
 ## The second %t1.a has 0 fetched member.
-# RUN: ld.lld %t.o %tweak.a %t1.a %t1.a --print-archive-stats=- -o /dev/null | \
+## Note: --warn-backrefs disables the optimization which skips repeated archives.
+# RUN: ld.lld %t.o %tweak.a %t1.a %t1.a --print-archive-stats=- --warn-backrefs -o /dev/null | \
 # RUN:   FileCheck --check-prefix=CHECK2 %s
 # CHECK2:      members	fetched	archive
 # CHECK2-NEXT: 1	0	{{.*}}weak.a
Index: lld/ELF/Driver.h
===================================================================
--- lld/ELF/Driver.h
+++ lld/ELF/Driver.h
@@ -46,6 +46,8 @@
   std::unique_ptr<BitcodeCompiler> lto;
 
   std::vector<InputFile *> files;
+
+  llvm::StringSet<> addedLibraries;
 };
 
 // Parses command line options.
Index: lld/ELF/Driver.cpp
===================================================================
--- lld/ELF/Driver.cpp
+++ lld/ELF/Driver.cpp
@@ -201,6 +201,13 @@
 void LinkerDriver::addFile(StringRef path, bool withLOption) {
   using namespace sys::fs;
 
+  // If we have already added the file as a library, no need to do that again.
+  // However, there are a few cases when the file might be processed in
+  // a different way and the optimization should be avoided.
+  if (!config->warnBackrefs && !config->formatBinary && !inWholeArchive &&
+      addedLibraries.contains(path))
+    return;
+
   Optional<MemoryBufferRef> buffer = readFile(path);
   if (!buffer.hasValue())
     return;
@@ -216,6 +223,11 @@
     readLinkerScript(mbref);
     return;
   case file_magic::archive: {
+    // The optimization is incompatible with --warn-backrefs; do not waste time
+    // filling the set in that case.
+    if (!config->warnBackrefs)
+      addedLibraries.insert(path);
+
     // Handle -whole-archive.
     if (inWholeArchive) {
       for (const auto &p : getArchiveMembers(mbref))


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D88944.296597.patch
Type: text/x-patch
Size: 3268 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201007/584bb84e/attachment.bin>


More information about the llvm-commits mailing list