[lld] [ELF] Reuse SHT_GROUP selection verdicts in initializeSections. NFC (PR #207437)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 3 10:42:50 PDT 2026
https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/207437
For each SHT_GROUP section, the parallel initializeSections re-derives
what the serial parse() already decided
(https://reviews.llvm.org/D130810).
Record the kept group section indices during parse() so that we can save
the work (xxh3 string hash and DenseMap lookup) in the parallel
initializeSections().
In a clang-relassert --threads=8 benchmark, "Initialize sections"
decreases from 39.0 to 30.6.
>From 3944d0947bb41a1fe0caae22a63c444444ab8bfb Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Fri, 3 Jul 2026 09:43:41 -0700
Subject: [PATCH] [ELF] Reuse SHT_GROUP selection verdicts in
initializeSections. NFC
For each SHT_GROUP section, the parallel initializeSections re-derives
what the serial parse() already decided
(https://reviews.llvm.org/D130810).
Record the kept group section indices during parse() so that we can save
the work (xxh3 string hash and DenseMap lookup) in the parallel
initializeSections().
In a clang-relassert --threads=8 benchmark, "Initialize sections"
decreases from 39.0 to 30.6.
---
lld/ELF/InputFiles.cpp | 17 +++++++++--------
lld/ELF/InputFiles.h | 4 ++++
2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 2f544f0fe0958..102bd384220a5 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -604,6 +604,7 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
.try_emplace(CachedHashStringRef(signature), this)
.second;
if (keepGroup) {
+ keptGroups.push_back(i);
if (!ctx.arg.resolveGroups)
sections[i] = createInputSection(
i, sec, check(obj.getSectionName(sec, shstrtab)));
@@ -769,6 +770,7 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
StringRef shstrtab = CHECK2(obj.getSectionStringTable(objSections), this);
uint64_t size = objSections.size();
SmallVector<ArrayRef<Elf_Word>, 0> selectedGroups;
+ size_t keptIdx = 0;
AArch64BuildAttrSubsections aarch64BAsubSections;
bool hasAArch64BuildAttributes = false;
for (size_t i = 0; i != size; ++i) {
@@ -826,14 +828,13 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
case SHT_GROUP: {
if (!ctx.arg.relocatable)
sections[i] = &InputSection::discarded;
- StringRef signature =
- cantFail(this->getELFSyms<ELFT>()[sec.sh_info].getName(stringTable));
- ArrayRef<Elf_Word> entries =
- cantFail(obj.template getSectionContentsAsArray<Elf_Word>(sec));
- if ((entries[0] & GRP_COMDAT) == 0 || ignoreComdats ||
- ctx.symtab->comdatGroups.find(CachedHashStringRef(signature))
- ->second == this)
- selectedGroups.push_back(entries);
+ // Use the verdict parse() recorded for this group instead of repeating
+ // the signature hashing and comdatGroups lookup.
+ while (keptIdx != keptGroups.size() && keptGroups[keptIdx] < i)
+ ++keptIdx;
+ if (keptIdx != keptGroups.size() && keptGroups[keptIdx] == i)
+ selectedGroups.push_back(
+ cantFail(obj.template getSectionContentsAsArray<Elf_Word>(sec)));
break;
}
case SHT_SYMTAB_SHNDX:
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index aef599102ecfc..0ded9b2fa38e2 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -315,6 +315,10 @@ template <class ELFT> class ObjFile : public ELFFileBase {
// The following variable contains the contents of .symtab_shndx.
// If the section does not exist (which is common), the array is empty.
ArrayRef<Elf_Word> shndxTable;
+
+ // Section indices of kept SHT_GROUP sections, recorded by parse() in
+ // ascending order, to be used by the parallel initializeSections().
+ SmallVector<uint32_t, 0> keptGroups;
};
class BitcodeFile : public InputFile {
More information about the llvm-commits
mailing list