[lld] b5a0f0f - [ELF] Add ELFFileBase::{elfShdrs,numELFShdrs} to avoid duplicate llvm::object::ELFFile::sections()
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 24 17:10:45 PST 2021
Author: Fangrui Song
Date: 2021-12-24T17:10:38-08:00
New Revision: b5a0f0f397c778cc7db71754c1b9c939f669568e
URL: https://github.com/llvm/llvm-project/commit/b5a0f0f397c778cc7db71754c1b9c939f669568e
DIFF: https://github.com/llvm/llvm-project/commit/b5a0f0f397c778cc7db71754c1b9c939f669568e.diff
LOG: [ELF] Add ELFFileBase::{elfShdrs,numELFShdrs} to avoid duplicate llvm::object::ELFFile::sections()
This mainly avoid `relsOrRelas` cost in `InputSectionBase::relocate`.
`llvm::object::ELFFile::sections()` has redundant and expensive checks.
Added:
Modified:
lld/ELF/DWARF.cpp
lld/ELF/Driver.cpp
lld/ELF/InputFiles.cpp
lld/ELF/InputFiles.h
lld/ELF/InputSection.cpp
lld/ELF/Relocations.cpp
Removed:
################################################################################
diff --git a/lld/ELF/DWARF.cpp b/lld/ELF/DWARF.cpp
index 4d84c09a0185..789820ba7a8e 100644
--- a/lld/ELF/DWARF.cpp
+++ b/lld/ELF/DWARF.cpp
@@ -27,8 +27,7 @@ using namespace lld::elf;
template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *obj) {
// Get the ELF sections to retrieve sh_flags. See the SHF_GROUP comment below.
- ArrayRef<typename ELFT::Shdr> objSections =
- CHECK(obj->getObj().sections(), obj);
+ ArrayRef<typename ELFT::Shdr> objSections = obj->template getELFShdrs<ELFT>();
assert(objSections.size() == obj->getSections().size());
for (auto it : llvm::enumerate(obj->getSections())) {
InputSectionBase *sec = it.value();
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index e4d3e1d50b0f..19266cb280b9 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -846,14 +846,13 @@ static bool
processCallGraphRelocations(SmallVector<uint32_t, 32> &symbolIndices,
ArrayRef<typename ELFT::CGProfile> &cgProfile,
ObjFile<ELFT> *inputObj) {
- symbolIndices.clear();
- const ELFFile<ELFT> &obj = inputObj->getObj();
- ArrayRef<Elf_Shdr_Impl<ELFT>> objSections =
- CHECK(obj.sections(), "could not retrieve object sections");
-
if (inputObj->cgProfileSectionIndex == SHN_UNDEF)
return false;
+ ArrayRef<Elf_Shdr_Impl<ELFT>> objSections =
+ inputObj->template getELFShdrs<ELFT>();
+ symbolIndices.clear();
+ const ELFFile<ELFT> &obj = inputObj->getObj();
cgProfile =
check(obj.template getSectionContentsAsArray<typename ELFT::CGProfile>(
objSections[inputObj->cgProfileSectionIndex]));
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 964898fb790e..0badf2c55e5b 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -370,6 +370,8 @@ template <class ELFT> void ELFFileBase::init() {
abiVersion = obj.getHeader().e_ident[llvm::ELF::EI_ABIVERSION];
ArrayRef<Elf_Shdr> sections = CHECK(obj.sections(), this);
+ elfShdrs = sections.data();
+ numELFShdrs = sections.size();
// Find a symbol table.
bool isDSO =
@@ -477,8 +479,7 @@ bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &sec, StringRef name) {
// When the option is given, we link "just symbols". The section table is
// initialized with null pointers.
template <class ELFT> void ObjFile<ELFT>::initializeJustSymbols() {
- ArrayRef<Elf_Shdr> sections = CHECK(this->getObj().sections(), this);
- this->sections.resize(sections.size());
+ sections.resize(numELFShdrs);
}
// An ELF object file may contain a `.deplibs` section. If it exists, the
@@ -544,7 +545,7 @@ template <class ELFT>
void ObjFile<ELFT>::initializeSections(bool ignoreComdats) {
const ELFFile<ELFT> &obj = this->getObj();
- ArrayRef<Elf_Shdr> objSections = CHECK(obj.sections(), this);
+ ArrayRef<Elf_Shdr> objSections = getELFShdrs<ELFT>();
StringRef shstrtab = CHECK(obj.getSectionStringTable(objSections), this);
uint64_t size = objSections.size();
this->sections.resize(size);
@@ -1410,7 +1411,7 @@ template <class ELFT> void SharedFile::parse() {
ArrayRef<Elf_Dyn> dynamicTags;
const ELFFile<ELFT> obj = this->getObj<ELFT>();
- ArrayRef<Elf_Shdr> sections = CHECK(obj.sections(), this);
+ ArrayRef<Elf_Shdr> sections = getELFShdrs<ELFT>();
const Elf_Shdr *versymSec = nullptr;
const Elf_Shdr *verdefSec = nullptr;
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 6111df521840..f58e76e48433 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -189,6 +189,10 @@ class ELFFileBase : public InputFile {
.slice(firstGlobal);
}
+ template <typename ELFT> typename ELFT::ShdrRange getELFShdrs() const {
+ return typename ELFT::ShdrRange(
+ reinterpret_cast<const typename ELFT::Shdr *>(elfShdrs), numELFShdrs);
+ }
template <typename ELFT> typename ELFT::SymRange getELFSyms() const {
return typename ELFT::SymRange(
reinterpret_cast<const typename ELFT::Sym *>(elfSyms), numELFSyms);
@@ -201,7 +205,9 @@ class ELFFileBase : public InputFile {
// Initializes this class's member variables.
template <typename ELFT> void init();
+ const void *elfShdrs = nullptr;
const void *elfSyms = nullptr;
+ uint32_t numELFShdrs = 0;
uint32_t numELFSyms = 0;
uint32_t firstGlobal = 0;
StringRef stringTable;
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index e3871260fe5b..33a42ff3f4a5 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -163,16 +163,16 @@ template <class ELFT> RelsOrRelas<ELFT> InputSectionBase::relsOrRelas() const {
if (relSecIdx == 0)
return {};
RelsOrRelas<ELFT> ret;
- const ELFFile<ELFT> obj = cast<ELFFileBase>(file)->getObj<ELFT>();
- typename ELFT::Shdr shdr = cantFail(obj.sections())[relSecIdx];
+ typename ELFT::Shdr shdr =
+ cast<ELFFileBase>(file)->getELFShdrs<ELFT>()[relSecIdx];
if (shdr.sh_type == SHT_REL) {
ret.rels = makeArrayRef(reinterpret_cast<const typename ELFT::Rel *>(
- obj.base() + shdr.sh_offset),
+ file->mb.getBufferStart() + shdr.sh_offset),
shdr.sh_size / sizeof(typename ELFT::Rel));
} else {
assert(shdr.sh_type == SHT_RELA);
ret.relas = makeArrayRef(reinterpret_cast<const typename ELFT::Rela *>(
- obj.base() + shdr.sh_offset),
+ file->mb.getBufferStart() + shdr.sh_offset),
shdr.sh_size / sizeof(typename ELFT::Rela));
}
return ret;
@@ -433,8 +433,7 @@ void InputSection::copyRelocations(uint8_t *buf, ArrayRef<RelTy> rels) {
sec->name != ".gcc_except_table" && sec->name != ".got2" &&
sec->name != ".toc") {
uint32_t secIdx = cast<Undefined>(sym).discardedSecIdx;
- Elf_Shdr_Impl<ELFT> sec =
- CHECK(file->getObj().sections(), file)[secIdx];
+ Elf_Shdr_Impl<ELFT> sec = file->template getELFShdrs<ELFT>()[secIdx];
warn("relocation refers to a discarded section: " +
CHECK(file->getObj().getSectionName(sec), file) +
"\n>>> referenced by " + getObjMsg(p->r_offset));
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 38e0d84e6271..23612ec48ded 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -472,8 +472,8 @@ static std::string maybeReportDiscarded(Undefined &sym) {
if (!file || !sym.discardedSecIdx ||
file->getSections()[sym.discardedSecIdx] != &InputSection::discarded)
return "";
- ArrayRef<Elf_Shdr_Impl<ELFT>> objSections =
- CHECK(file->getObj().sections(), file);
+ ArrayRef<typename ELFT::Shdr> objSections =
+ file->template getELFShdrs<ELFT>();
std::string msg;
if (sym.type == ELF::STT_SECTION) {
More information about the llvm-commits
mailing list