From 1ff1d50d9f461e005085db5ec94d21f15d701a90 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 14 Dec 2021 20:55:32 -0800 Subject: [PATCH] [ELF] Make InputFile smaller sizeof(ObjFile) 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. --- lld/ELF/Config.h | 2 +- lld/ELF/InputFiles.cpp | 10 +++--- lld/ELF/InputFiles.h | 94 ++++++++++++++++++++++++------------------------ lld/ELF/InputSection.cpp | 2 +- 4 files changed, 54 insertions(+), 54 deletions(-) diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index c660a8e..f0f8eb8 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 90a4eb0..63f83a4 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 void ELFFileBase::init() { fatal(toString(this) + ": invalid sh_info in symbol table"); elfSyms = reinterpret_cast(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 5bbfb76..ec6f1a7 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 sections; + public: - enum Kind { + enum Kind : uint8_t { ObjKind, SharedKind, LazyObjKind, @@ -96,27 +103,40 @@ public: // 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 symbols; + + // Index of MIPS GOT built for this file. + llvm::Optional 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 @@ public: // 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 mipsGotIndex; - - std::vector symbols; - protected: InputFile(Kind k, MemoryBufferRef m); - std::vector sections; - -private: - const Kind fileKind; - - // Cache for getNameForScript(). - mutable std::string nameForScriptCache; }; class ELFFileBase : public InputFile { @@ -190,7 +190,7 @@ protected: template void init(); const void *elfSyms = nullptr; - size_t numELFSyms = 0; + uint32_t numELFSyms = 0; uint32_t firstGlobal = 0; StringRef stringTable; }; @@ -207,7 +207,7 @@ public: } 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 @@ public: llvm::Optional getDILineInfo(InputSectionBase *, uint64_t); llvm::Optional> 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 @@ public: 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 @@ public: // 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 @@ public: 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 a9185f8..b2f6379 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()) -- 2.7.4