[lld] dabac5f - [ELF][LTO] Cache symbol table of lazy BitcodeFile

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 30 12:03:33 PST 2021


Author: Fangrui Song
Date: 2021-12-30T12:03:29-08:00
New Revision: dabac5feecdde0441b22a19088ac7384e4763dd1

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

LOG: [ELF][LTO] Cache symbol table of lazy BitcodeFile

Similar to D62188: a BitcodeFile's symbol table may be iterated twice, once in
--start-lib (lazy) state, and once in the non-lazy state. This patch
makes `parseLazy` save `symbols[i]` so that the non-lazy state does not need to
re-insert to the global symbol table. Avoiding a redundant `saver.save` may save
memory.

`Maximum resident set size (kbytes)` for a large --thinlto-index-only link:

* without the patch: 10164000
* with the patch: 10095716 (0.6% decrease)

Note: we can remove `saver.save` if `BitcodeCompiler::add` does not transfer the ownership
of `f.obj` in `checkError(ltoObj->add(std::move(f.obj), resols));`.

Reviewed By: tejohnson

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

Added: 
    

Modified: 
    lld/ELF/InputFiles.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index dd7fd954bc51..04fa48f63c03 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -1680,34 +1680,42 @@ static uint8_t mapVisibility(GlobalValue::VisibilityTypes gvVisibility) {
 }
 
 template <class ELFT>
-static Symbol *createBitcodeSymbol(const std::vector<bool> &keptComdats,
-                                   const lto::InputFile::Symbol &objSym,
-                                   BitcodeFile &f) {
-  StringRef name = saver.save(objSym.getName());
+static void
+createBitcodeSymbol(Symbol *&sym, const std::vector<bool> &keptComdats,
+                    const lto::InputFile::Symbol &objSym, BitcodeFile &f) {
   uint8_t binding = objSym.isWeak() ? STB_WEAK : STB_GLOBAL;
   uint8_t type = objSym.isTLS() ? STT_TLS : STT_NOTYPE;
   uint8_t visibility = mapVisibility(objSym.getVisibility());
   bool canOmitFromDynSym = objSym.canBeOmittedFromSymbolTable();
 
+  StringRef name;
+  if (sym) {
+    name = sym->getName();
+  } else {
+    name = saver.save(objSym.getName());
+    sym = symtab->insert(name);
+  }
+
   int c = objSym.getComdatIndex();
   if (objSym.isUndefined() || (c != -1 && !keptComdats[c])) {
     Undefined newSym(&f, name, binding, visibility, type);
     if (canOmitFromDynSym)
       newSym.exportDynamic = false;
-    Symbol *ret = symtab->addSymbol(newSym);
-    ret->referenced = true;
-    return ret;
+    sym->resolve(newSym);
+    sym->referenced = true;
+    return;
   }
 
-  if (objSym.isCommon())
-    return symtab->addSymbol(
-        CommonSymbol{&f, name, binding, visibility, STT_OBJECT,
-                     objSym.getCommonAlignment(), objSym.getCommonSize()});
-
-  Defined newSym(&f, name, binding, visibility, type, 0, 0, nullptr);
-  if (canOmitFromDynSym)
-    newSym.exportDynamic = false;
-  return symtab->addSymbol(newSym);
+  if (objSym.isCommon()) {
+    sym->resolve(CommonSymbol{&f, name, binding, visibility, STT_OBJECT,
+                              objSym.getCommonAlignment(),
+                              objSym.getCommonSize()});
+  } else {
+    Defined newSym(&f, name, binding, visibility, type, 0, 0, nullptr);
+    if (canOmitFromDynSym)
+      newSym.exportDynamic = false;
+    sym->resolve(newSym);
+  }
 }
 
 template <class ELFT> void BitcodeFile::parse() {
@@ -1719,10 +1727,11 @@ template <class ELFT> void BitcodeFile::parse() {
             .second);
   }
 
-  symbols.assign(obj->symbols().size(), nullptr);
-  for (auto it : llvm::enumerate(obj->symbols()))
-    symbols[it.index()] =
-        createBitcodeSymbol<ELFT>(keptComdats, it.value(), *this);
+  symbols.resize(obj->symbols().size());
+  for (auto it : llvm::enumerate(obj->symbols())) {
+    Symbol *&sym = symbols[it.index()];
+    createBitcodeSymbol<ELFT>(sym, keptComdats, it.value(), *this);
+  }
 
   for (auto l : obj->getDependentLibraries())
     addDependentLibrary(l, this);
@@ -1730,9 +1739,11 @@ template <class ELFT> void BitcodeFile::parse() {
 
 void BitcodeFile::parseLazy() {
   SymbolTable &symtab = *elf::symtab;
-  for (const lto::InputFile::Symbol &sym : obj->symbols())
-    if (!sym.isUndefined())
-      symtab.addSymbol(LazyObject{*this, saver.save(sym.getName())});
+  symbols.resize(obj->symbols().size());
+  for (auto it : llvm::enumerate(obj->symbols()))
+    if (!it.value().isUndefined())
+      symbols[it.index()] =
+          symtab.addSymbol(LazyObject{*this, saver.save(it.value().getName())});
 }
 
 void BinaryFile::parse() {


        


More information about the llvm-commits mailing list