forked from OSchip/llvm-project
[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
This commit is contained in:
parent
15787ccd45
commit
dabac5feec
|
@ -1680,34 +1680,42 @@ static uint8_t mapVisibility(GlobalValue::VisibilityTypes gvVisibility) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
static Symbol *createBitcodeSymbol(const std::vector<bool> &keptComdats,
|
static void
|
||||||
const lto::InputFile::Symbol &objSym,
|
createBitcodeSymbol(Symbol *&sym, const std::vector<bool> &keptComdats,
|
||||||
BitcodeFile &f) {
|
const lto::InputFile::Symbol &objSym, BitcodeFile &f) {
|
||||||
StringRef name = saver.save(objSym.getName());
|
|
||||||
uint8_t binding = objSym.isWeak() ? STB_WEAK : STB_GLOBAL;
|
uint8_t binding = objSym.isWeak() ? STB_WEAK : STB_GLOBAL;
|
||||||
uint8_t type = objSym.isTLS() ? STT_TLS : STT_NOTYPE;
|
uint8_t type = objSym.isTLS() ? STT_TLS : STT_NOTYPE;
|
||||||
uint8_t visibility = mapVisibility(objSym.getVisibility());
|
uint8_t visibility = mapVisibility(objSym.getVisibility());
|
||||||
bool canOmitFromDynSym = objSym.canBeOmittedFromSymbolTable();
|
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();
|
int c = objSym.getComdatIndex();
|
||||||
if (objSym.isUndefined() || (c != -1 && !keptComdats[c])) {
|
if (objSym.isUndefined() || (c != -1 && !keptComdats[c])) {
|
||||||
Undefined newSym(&f, name, binding, visibility, type);
|
Undefined newSym(&f, name, binding, visibility, type);
|
||||||
if (canOmitFromDynSym)
|
if (canOmitFromDynSym)
|
||||||
newSym.exportDynamic = false;
|
newSym.exportDynamic = false;
|
||||||
Symbol *ret = symtab->addSymbol(newSym);
|
sym->resolve(newSym);
|
||||||
ret->referenced = true;
|
sym->referenced = true;
|
||||||
return ret;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objSym.isCommon())
|
if (objSym.isCommon()) {
|
||||||
return symtab->addSymbol(
|
sym->resolve(CommonSymbol{&f, name, binding, visibility, STT_OBJECT,
|
||||||
CommonSymbol{&f, name, binding, visibility, STT_OBJECT,
|
objSym.getCommonAlignment(),
|
||||||
objSym.getCommonAlignment(), objSym.getCommonSize()});
|
objSym.getCommonSize()});
|
||||||
|
} else {
|
||||||
Defined newSym(&f, name, binding, visibility, type, 0, 0, nullptr);
|
Defined newSym(&f, name, binding, visibility, type, 0, 0, nullptr);
|
||||||
if (canOmitFromDynSym)
|
if (canOmitFromDynSym)
|
||||||
newSym.exportDynamic = false;
|
newSym.exportDynamic = false;
|
||||||
return symtab->addSymbol(newSym);
|
sym->resolve(newSym);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void BitcodeFile::parse() {
|
template <class ELFT> void BitcodeFile::parse() {
|
||||||
|
@ -1719,10 +1727,11 @@ template <class ELFT> void BitcodeFile::parse() {
|
||||||
.second);
|
.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
symbols.assign(obj->symbols().size(), nullptr);
|
symbols.resize(obj->symbols().size());
|
||||||
for (auto it : llvm::enumerate(obj->symbols()))
|
for (auto it : llvm::enumerate(obj->symbols())) {
|
||||||
symbols[it.index()] =
|
Symbol *&sym = symbols[it.index()];
|
||||||
createBitcodeSymbol<ELFT>(keptComdats, it.value(), *this);
|
createBitcodeSymbol<ELFT>(sym, keptComdats, it.value(), *this);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto l : obj->getDependentLibraries())
|
for (auto l : obj->getDependentLibraries())
|
||||||
addDependentLibrary(l, this);
|
addDependentLibrary(l, this);
|
||||||
|
@ -1730,9 +1739,11 @@ template <class ELFT> void BitcodeFile::parse() {
|
||||||
|
|
||||||
void BitcodeFile::parseLazy() {
|
void BitcodeFile::parseLazy() {
|
||||||
SymbolTable &symtab = *elf::symtab;
|
SymbolTable &symtab = *elf::symtab;
|
||||||
for (const lto::InputFile::Symbol &sym : obj->symbols())
|
symbols.resize(obj->symbols().size());
|
||||||
if (!sym.isUndefined())
|
for (auto it : llvm::enumerate(obj->symbols()))
|
||||||
symtab.addSymbol(LazyObject{*this, saver.save(sym.getName())});
|
if (!it.value().isUndefined())
|
||||||
|
symbols[it.index()] =
|
||||||
|
symtab.addSymbol(LazyObject{*this, saver.save(it.value().getName())});
|
||||||
}
|
}
|
||||||
|
|
||||||
void BinaryFile::parse() {
|
void BinaryFile::parse() {
|
||||||
|
|
Loading…
Reference in New Issue