[lld] 1ff1d50 - [ELF] Make InputFile smaller
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 14 20:55:39 PST 2021
Author: Fangrui Song
Date: 2021-12-14T20:55:32-08:00
New Revision: 1ff1d50d9f461e005085db5ec94d21f15d701a90
URL: https://github.com/llvm/llvm-project/commit/1ff1d50d9f461e005085db5ec94d21f15d701a90
DIFF: https://github.com/llvm/llvm-project/commit/1ff1d50d9f461e005085db5ec94d21f15d701a90.diff
LOG: [ELF] Make InputFile smaller
sizeof(ObjFile<ELF64LE>) is decreased from 344 to 272 on an ELF64 system.
In a large link with 30000 ObjFiles, this may be 2+MiB saving.
Change std::vector members to SmallVector, and std::string members to
SmallString<0> (these members typically don't benefit from small string optimization).
On Linux x86-64 the lld executable is ~6k smaller.
Added:
Modified:
lld/ELF/Config.h
lld/ELF/InputFiles.cpp
lld/ELF/InputFiles.h
lld/ELF/InputSection.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index c660a8e67c211..f0f8eb86f44c4 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -30,7 +30,7 @@ namespace elf {
class InputFile;
class InputSectionBase;
-enum ELFKind {
+enum ELFKind : uint8_t {
ELFNoneKind,
ELF32LEKind,
ELF32BEKind,
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 90a4eb018b4d0..63f83a486d3cc 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -59,11 +59,11 @@ std::string lld::toString(const InputFile *f) {
if (f->toStringCache.empty()) {
if (f->archiveName.empty())
- f->toStringCache = std::string(f->getName());
+ f->toStringCache = f->getName();
else
- f->toStringCache = (f->archiveName + "(" + f->getName() + ")").str();
+ (f->archiveName + "(" + f->getName() + ")").toVector(f->toStringCache);
}
- return f->toStringCache;
+ return std::string(f->toStringCache);
}
static ELFKind getELFKind(MemoryBufferRef mb, StringRef archiveName) {
@@ -384,7 +384,7 @@ template <class ELFT> void ELFFileBase::init() {
fatal(toString(this) + ": invalid sh_info in symbol table");
elfSyms = reinterpret_cast<const void *>(eSyms.data());
- numELFSyms = eSyms.size();
+ numELFSyms = uint32_t(eSyms.size());
stringTable = CHECK(obj.getStringTableForSymtab(*symtabSec, sections), this);
}
@@ -1642,7 +1642,7 @@ static uint8_t getOsAbi(const Triple &t) {
BitcodeFile::BitcodeFile(MemoryBufferRef mb, StringRef archiveName,
uint64_t offsetInArchive)
: InputFile(BitcodeKind, mb) {
- this->archiveName = std::string(archiveName);
+ this->archiveName = archiveName;
std::string path = mb.getBufferIdentifier().str();
if (config->thinLTOIndexOnly)
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 5bbfb7656e472..ec6f1a7ad7a25 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -54,8 +54,15 @@ void parseFile(InputFile *file);
// The root class of input files.
class InputFile {
+private:
+ // Cache for getNameForScript().
+ mutable SmallString<0> nameForScriptCache;
+
+protected:
+ SmallVector<InputSectionBase *, 0> sections;
+
public:
- enum Kind {
+ enum Kind : uint8_t {
ObjKind,
SharedKind,
LazyObjKind,
@@ -96,27 +103,40 @@ class InputFile {
// If not empty, this stores the name of the archive containing this file.
// We use this string for creating error messages.
- std::string archiveName;
+ SmallString<0> archiveName;
+
+ // Cache for toString(). Only toString() should use this member.
+ mutable SmallString<0> toStringCache;
+
+ SmallVector<Symbol *, 0> symbols;
+
+ // Index of MIPS GOT built for this file.
+ llvm::Optional<uint32_t> mipsGotIndex;
+
+ // outSecOff of .got2 in the current file. This is used by PPC32 -fPIC/-fPIE
+ // to compute offsets in PLT call stubs.
+ uint32_t ppc32Got2OutSecOff = 0;
+
+ // groupId is used for --warn-backrefs which is an optional error
+ // checking feature. All files within the same --{start,end}-group or
+ // --{start,end}-lib get the same group ID. Otherwise, each file gets a new
+ // group ID. For more info, see checkDependency() in SymbolTable.cpp.
+ uint32_t groupId;
+ static bool isInGroup;
+ static uint32_t nextGroupId;
// If this is an architecture-specific file, the following members
// have ELF type (i.e. ELF{32,64}{LE,BE}) and target machine type.
- ELFKind ekind = ELFNoneKind;
uint16_t emachine = llvm::ELF::EM_NONE;
+ const Kind fileKind;
+ ELFKind ekind = ELFNoneKind;
uint8_t osabi = 0;
uint8_t abiVersion = 0;
-
- // Cache for toString(). Only toString() should use this member.
- mutable std::string toStringCache;
-
- std::string getSrcMsg(const Symbol &sym, InputSectionBase &sec,
- uint64_t offset);
-
// True if this is an argument for --just-symbols. Usually false.
bool justSymbols = false;
- // outSecOff of .got2 in the current file. This is used by PPC32 -fPIC/-fPIE
- // to compute offsets in PLT call stubs.
- uint32_t ppc32Got2OutSecOff = 0;
+ std::string getSrcMsg(const Symbol &sym, InputSectionBase &sec,
+ uint64_t offset);
// On PPC64 we need to keep track of which files contain small code model
// relocations that access the .toc section. To minimize the chance of a
@@ -133,28 +153,8 @@ class InputFile {
// R_PPC64_TLSLD. Disable TLS relaxation to avoid bad code generation.
bool ppc64DisableTLSRelax = false;
- // groupId is used for --warn-backrefs which is an optional error
- // checking feature. All files within the same --{start,end}-group or
- // --{start,end}-lib get the same group ID. Otherwise, each file gets a new
- // group ID. For more info, see checkDependency() in SymbolTable.cpp.
- uint32_t groupId;
- static bool isInGroup;
- static uint32_t nextGroupId;
-
- // Index of MIPS GOT built for this file.
- llvm::Optional<size_t> mipsGotIndex;
-
- std::vector<Symbol *> symbols;
-
protected:
InputFile(Kind k, MemoryBufferRef m);
- std::vector<InputSectionBase *> sections;
-
-private:
- const Kind fileKind;
-
- // Cache for getNameForScript().
- mutable std::string nameForScriptCache;
};
class ELFFileBase : public InputFile {
@@ -190,7 +190,7 @@ class ELFFileBase : public InputFile {
template <typename ELFT> void init();
const void *elfSyms = nullptr;
- size_t numELFSyms = 0;
+ uint32_t numELFSyms = 0;
uint32_t firstGlobal = 0;
StringRef stringTable;
};
@@ -207,7 +207,7 @@ template <class ELFT> class ObjFile : public ELFFileBase {
}
ObjFile(MemoryBufferRef m, StringRef archiveName) : ELFFileBase(ObjKind, m) {
- this->archiveName = std::string(archiveName);
+ this->archiveName = archiveName;
}
void parse(bool ignoreComdats = false);
@@ -231,6 +231,17 @@ template <class ELFT> class ObjFile : public ELFFileBase {
llvm::Optional<llvm::DILineInfo> getDILineInfo(InputSectionBase *, uint64_t);
llvm::Optional<std::pair<std::string, unsigned>> getVariableLoc(StringRef name);
+ // Name of source file obtained from STT_FILE symbol value,
+ // or empty string if there is no such symbol in object file
+ // symbol table.
+ StringRef sourceFile;
+
+ // Pointer to this input file's .llvm_addrsig section, if it has one.
+ const Elf_Shdr *addrsigSec = nullptr;
+
+ // SHT_LLVM_CALL_GRAPH_PROFILE section index.
+ uint32_t cgProfileSectionIndex = 0;
+
// MIPS GP0 value defined by this file. This value represents the gp value
// used to create the relocatable object and required to support
// R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations.
@@ -238,11 +249,6 @@ template <class ELFT> class ObjFile : public ELFFileBase {
uint32_t andFeatures = 0;
- // Name of source file obtained from STT_FILE symbol value,
- // or empty string if there is no such symbol in object file
- // symbol table.
- StringRef sourceFile;
-
// True if the file defines functions compiled with
// -fsplit-stack. Usually false.
bool splitStack = false;
@@ -251,12 +257,6 @@ template <class ELFT> class ObjFile : public ELFFileBase {
// but had one or more functions with the no_split_stack attribute.
bool someNoSplitStack = false;
- // Pointer to this input file's .llvm_addrsig section, if it has one.
- const Elf_Shdr *addrsigSec = nullptr;
-
- // SHT_LLVM_CALL_GRAPH_PROFILE section index.
- uint32_t cgProfileSectionIndex = 0;
-
// Get cached DWARF information.
DWARFCache *getDwarf();
@@ -306,7 +306,7 @@ class LazyObjFile : public InputFile {
LazyObjFile(MemoryBufferRef m, StringRef archiveName,
uint64_t offsetInArchive)
: InputFile(LazyObjKind, m), offsetInArchive(offsetInArchive) {
- this->archiveName = std::string(archiveName);
+ this->archiveName = archiveName;
}
static bool classof(const InputFile *f) { return f->kind() == LazyObjKind; }
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index a9185f8d8a98a..b2f63799337e0 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -325,7 +325,7 @@ std::string InputSectionBase::getObjMsg(uint64_t off) {
std::string archive;
if (!file->archiveName.empty())
- archive = " in archive " + file->archiveName;
+ archive = (" in archive " + file->archiveName).str();
// Find a symbol that encloses a given location.
for (Symbol *b : file->getSymbols())
More information about the llvm-commits
mailing list