Skip to content

Commit d548020

Browse files
authored
[MC][ELF] Eliminate some hash maps from ELFObjectWriter (#97421)
Remove some maps. Mostly cleanup, only a slight performance win. - Replace SectionIndexMap with layout order: The section layout order is only used in MachO, so we can repurpose the field as section table index. - Store section offsets in MCSectionELF: No need for a map, and especially not a std::map. Direct access to the underlying (and easily modifyable) data structure is always faster. - Improve storage of groups: There's no point in having a DenseMap, the number of sections and groups are reasonably small to use vectors.
1 parent 96c18a2 commit d548020

File tree

2 files changed

+60
-72
lines changed

2 files changed

+60
-72
lines changed

llvm/include/llvm/MC/MCSectionELF.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ class MCSectionELF final : public MCSection {
4646
/// section header index of the section where LinkedToSym is defined.
4747
const MCSymbol *LinkedToSym;
4848

49+
/// Start/end offset in file, used by ELFWriter.
50+
uint64_t StartOffset;
51+
uint64_t EndOffset;
52+
4953
private:
5054
friend class MCContext;
5155

@@ -92,6 +96,14 @@ class MCSectionELF final : public MCSection {
9296
}
9397
const MCSymbol *getLinkedToSymbol() const { return LinkedToSym; }
9498

99+
void setOffsets(uint64_t Start, uint64_t End) {
100+
StartOffset = Start;
101+
EndOffset = End;
102+
}
103+
std::pair<uint64_t, uint64_t> getOffsets() const {
104+
return std::make_pair(StartOffset, EndOffset);
105+
}
106+
95107
static bool classof(const MCSection *S) {
96108
return S->getVariant() == SV_ELF;
97109
}

llvm/lib/MC/ELFObjectWriter.cpp

Lines changed: 48 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ using namespace llvm;
6666

6767
namespace {
6868

69-
using SectionIndexMapTy = DenseMap<const MCSectionELF *, uint32_t>;
70-
7169
class ELFObjectWriter;
7270
struct ELFWriter;
7371

@@ -136,8 +134,8 @@ struct ELFWriter {
136134
unsigned SymbolTableIndex = ~0u;
137135

138136
// Sections in the order they are to be output in the section table.
139-
std::vector<const MCSectionELF *> SectionTable;
140-
unsigned addToSectionTable(const MCSectionELF *Sec);
137+
std::vector<MCSectionELF *> SectionTable;
138+
unsigned addToSectionTable(MCSectionELF *Sec);
141139

142140
// TargetObjectWriter wrappers.
143141
bool is64Bit() const;
@@ -171,31 +169,21 @@ struct ELFWriter {
171169
void writeSymbol(const MCAssembler &Asm, SymbolTableWriter &Writer,
172170
uint32_t StringIndex, ELFSymbolData &MSD);
173171

174-
// Start and end offset of each section
175-
using SectionOffsetsTy =
176-
std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>;
177-
178172
// Map from a signature symbol to the group section index
179173
using RevGroupMapTy = DenseMap<const MCSymbol *, unsigned>;
180174

181175
/// Compute the symbol table data
182176
///
183177
/// \param Asm - The assembler.
184-
/// \param SectionIndexMap - Maps a section to its index.
185178
/// \param RevGroupMap - Maps a signature symbol to the group section.
186-
void computeSymbolTable(MCAssembler &Asm,
187-
const SectionIndexMapTy &SectionIndexMap,
188-
const RevGroupMapTy &RevGroupMap,
189-
SectionOffsetsTy &SectionOffsets);
179+
void computeSymbolTable(MCAssembler &Asm, const RevGroupMapTy &RevGroupMap);
190180

191181
void writeAddrsigSection();
192182

193183
MCSectionELF *createRelocationSection(MCContext &Ctx,
194184
const MCSectionELF &Sec);
195185

196-
void writeSectionHeader(const MCAssembler &Asm,
197-
const SectionIndexMapTy &SectionIndexMap,
198-
const SectionOffsetsTy &SectionOffsets);
186+
void writeSectionHeader(const MCAssembler &Asm);
199187

200188
void writeSectionData(const MCAssembler &Asm, MCSection &Sec);
201189

@@ -207,8 +195,7 @@ struct ELFWriter {
207195
void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
208196

209197
uint64_t writeObject(MCAssembler &Asm);
210-
void writeSection(const SectionIndexMapTy &SectionIndexMap,
211-
uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
198+
void writeSection(uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
212199
const MCSectionELF &Section);
213200
};
214201

@@ -330,7 +317,7 @@ uint64_t ELFWriter::align(Align Alignment) {
330317
return NewOffset;
331318
}
332319

333-
unsigned ELFWriter::addToSectionTable(const MCSectionELF *Sec) {
320+
unsigned ELFWriter::addToSectionTable(MCSectionELF *Sec) {
334321
SectionTable.push_back(Sec);
335322
StrTabBuilder.add(Sec->getName());
336323
return SectionTable.size();
@@ -612,9 +599,7 @@ bool ELFWriter::isInSymtab(const MCAssembler &Asm, const MCSymbolELF &Symbol,
612599
}
613600

614601
void ELFWriter::computeSymbolTable(MCAssembler &Asm,
615-
const SectionIndexMapTy &SectionIndexMap,
616-
const RevGroupMapTy &RevGroupMap,
617-
SectionOffsetsTy &SectionOffsets) {
602+
const RevGroupMapTy &RevGroupMap) {
618603
MCContext &Ctx = Asm.getContext();
619604
SymbolTableWriter Writer(*this, is64Bit());
620605

@@ -697,7 +682,7 @@ void ELFWriter::computeSymbolTable(MCAssembler &Asm,
697682

698683
if (Mode == NonDwoOnly && isDwoSection(Section))
699684
continue;
700-
MSD.SectionIndex = SectionIndexMap.lookup(&Section);
685+
MSD.SectionIndex = Section.getOrdinal();
701686
assert(MSD.SectionIndex && "Invalid section index!");
702687
if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
703688
HasLargeSectionIndex = true;
@@ -775,7 +760,7 @@ void ELFWriter::computeSymbolTable(MCAssembler &Asm,
775760
}
776761

777762
uint64_t SecEnd = W.OS.tell();
778-
SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
763+
SymtabSection->setOffsets(SecStart, SecEnd);
779764

780765
ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
781766
if (ShndxIndexes.empty()) {
@@ -785,12 +770,11 @@ void ELFWriter::computeSymbolTable(MCAssembler &Asm,
785770
assert(SymtabShndxSectionIndex != 0);
786771

787772
SecStart = W.OS.tell();
788-
const MCSectionELF *SymtabShndxSection =
789-
SectionTable[SymtabShndxSectionIndex - 1];
773+
MCSectionELF *SymtabShndxSection = SectionTable[SymtabShndxSectionIndex - 1];
790774
for (uint32_t Index : ShndxIndexes)
791775
write(Index);
792776
SecEnd = W.OS.tell();
793-
SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
777+
SymtabShndxSection->setOffsets(SecStart, SecEnd);
794778
}
795779

796780
void ELFWriter::writeAddrsigSection() {
@@ -1030,8 +1014,7 @@ void ELFWriter::writeRelocations(const MCAssembler &Asm,
10301014
}
10311015
}
10321016

1033-
void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
1034-
uint32_t GroupSymbolIndex, uint64_t Offset,
1017+
void ELFWriter::writeSection(uint32_t GroupSymbolIndex, uint64_t Offset,
10351018
uint64_t Size, const MCSectionELF &Section) {
10361019
uint64_t sh_link = 0;
10371020
uint64_t sh_info = 0;
@@ -1050,7 +1033,7 @@ void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
10501033
sh_link = SymbolTableIndex;
10511034
assert(sh_link && ".symtab not found");
10521035
const MCSection *InfoSection = Section.getLinkedToSection();
1053-
sh_info = SectionIndexMap.lookup(cast<MCSectionELF>(InfoSection));
1036+
sh_info = InfoSection->getOrdinal();
10541037
break;
10551038
}
10561039

@@ -1075,10 +1058,8 @@ void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
10751058
// If the value in the associated metadata is not a definition, Sym will be
10761059
// undefined. Represent this with sh_link=0.
10771060
const MCSymbol *Sym = Section.getLinkedToSymbol();
1078-
if (Sym && Sym->isInSection()) {
1079-
const MCSectionELF *Sec = cast<MCSectionELF>(&Sym->getSection());
1080-
sh_link = SectionIndexMap.lookup(Sec);
1081-
}
1061+
if (Sym && Sym->isInSection())
1062+
sh_link = Sym->getSection().getOrdinal();
10821063
}
10831064

10841065
WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getName()),
@@ -1087,9 +1068,7 @@ void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
10871068
Section.getEntrySize());
10881069
}
10891070

1090-
void ELFWriter::writeSectionHeader(const MCAssembler &Asm,
1091-
const SectionIndexMapTy &SectionIndexMap,
1092-
const SectionOffsetsTy &SectionOffsets) {
1071+
void ELFWriter::writeSectionHeader(const MCAssembler &Asm) {
10931072
const unsigned NumSections = SectionTable.size();
10941073

10951074
// Null section first.
@@ -1105,16 +1084,14 @@ void ELFWriter::writeSectionHeader(const MCAssembler &Asm,
11051084
else
11061085
GroupSymbolIndex = Section->getGroup()->getIndex();
11071086

1108-
const std::pair<uint64_t, uint64_t> &Offsets =
1109-
SectionOffsets.find(Section)->second;
1087+
std::pair<uint64_t, uint64_t> Offsets = Section->getOffsets();
11101088
uint64_t Size;
11111089
if (Type == ELF::SHT_NOBITS)
11121090
Size = Asm.getSectionAddressSize(*Section);
11131091
else
11141092
Size = Offsets.second - Offsets.first;
11151093

1116-
writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size,
1117-
*Section);
1094+
writeSection(GroupSymbolIndex, Offsets.first, Size, *Section);
11181095
}
11191096
}
11201097

@@ -1127,17 +1104,15 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm) {
11271104
StringTableIndex = addToSectionTable(StrtabSection);
11281105

11291106
RevGroupMapTy RevGroupMap;
1130-
SectionIndexMapTy SectionIndexMap;
1131-
1132-
DenseMap<const MCSymbol *, SmallVector<const MCSectionELF *, 0>> GroupMembers;
11331107

11341108
// Write out the ELF header ...
11351109
writeHeader(Asm);
11361110

11371111
// ... then the sections ...
1138-
SectionOffsetsTy SectionOffsets;
1139-
std::vector<MCSectionELF *> Groups;
1140-
std::vector<MCSectionELF *> Relocations;
1112+
SmallVector<std::pair<MCSectionELF *, SmallVector<unsigned>>, 0> Groups;
1113+
// Map from group section index to group
1114+
SmallVector<unsigned, 0> GroupMap;
1115+
SmallVector<MCSectionELF *> Relocations;
11411116
for (MCSection &Sec : Asm) {
11421117
MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
11431118
if (Mode == NonDwoOnly && isDwoSection(Section))
@@ -1152,49 +1127,50 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm) {
11521127
writeSectionData(Asm, Section);
11531128

11541129
uint64_t SecEnd = W.OS.tell();
1155-
SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
1130+
Section.setOffsets(SecStart, SecEnd);
11561131

11571132
MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
11581133

1134+
unsigned *GroupIdxEntry = nullptr;
11591135
if (SignatureSymbol) {
1160-
unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
1161-
if (!GroupIdx) {
1136+
GroupIdxEntry = &RevGroupMap[SignatureSymbol];
1137+
if (!*GroupIdxEntry) {
11621138
MCSectionELF *Group =
11631139
Ctx.createELFGroupSection(SignatureSymbol, Section.isComdat());
1164-
GroupIdx = addToSectionTable(Group);
1140+
*GroupIdxEntry = addToSectionTable(Group);
11651141
Group->setAlignment(Align(4));
1166-
Groups.push_back(Group);
1142+
1143+
GroupMap.resize(*GroupIdxEntry + 1);
1144+
GroupMap[*GroupIdxEntry] = Groups.size();
1145+
Groups.emplace_back(Group, SmallVector<unsigned>{});
11671146
}
1168-
SmallVector<const MCSectionELF *, 0> &Members =
1169-
GroupMembers[SignatureSymbol];
1170-
Members.push_back(&Section);
1171-
if (RelSection)
1172-
Members.push_back(RelSection);
11731147
}
11741148

1175-
SectionIndexMap[&Section] = addToSectionTable(&Section);
1149+
Section.setOrdinal(addToSectionTable(&Section));
11761150
if (RelSection) {
1177-
SectionIndexMap[RelSection] = addToSectionTable(RelSection);
1151+
RelSection->setOrdinal(addToSectionTable(RelSection));
11781152
Relocations.push_back(RelSection);
11791153
}
11801154

1155+
if (GroupIdxEntry) {
1156+
auto &Members = Groups[GroupMap[*GroupIdxEntry]];
1157+
Members.second.push_back(Section.getOrdinal());
1158+
if (RelSection)
1159+
Members.second.push_back(RelSection->getOrdinal());
1160+
}
1161+
11811162
OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx, Section);
11821163
}
11831164

1184-
for (MCSectionELF *Group : Groups) {
1165+
for (auto &[Group, Members] : Groups) {
11851166
// Remember the offset into the file for this section.
11861167
const uint64_t SecStart = align(Group->getAlign());
11871168

1188-
const MCSymbol *SignatureSymbol = Group->getGroup();
1189-
assert(SignatureSymbol);
11901169
write(uint32_t(Group->isComdat() ? unsigned(ELF::GRP_COMDAT) : 0));
1191-
for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
1192-
uint32_t SecIndex = SectionIndexMap.lookup(Member);
1193-
write(SecIndex);
1194-
}
1170+
W.write<unsigned>(Members);
11951171

11961172
uint64_t SecEnd = W.OS.tell();
1197-
SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
1173+
Group->setOffsets(SecStart, SecEnd);
11981174
}
11991175

12001176
if (Mode == DwoOnly) {
@@ -1210,7 +1186,7 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm) {
12101186
}
12111187

12121188
// Compute symbol table information.
1213-
computeSymbolTable(Asm, SectionIndexMap, RevGroupMap, SectionOffsets);
1189+
computeSymbolTable(Asm, RevGroupMap);
12141190

12151191
for (MCSectionELF *RelSection : Relocations) {
12161192
// Remember the offset into the file for this section.
@@ -1220,27 +1196,27 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm) {
12201196
cast<MCSectionELF>(*RelSection->getLinkedToSection()));
12211197

12221198
uint64_t SecEnd = W.OS.tell();
1223-
SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
1199+
RelSection->setOffsets(SecStart, SecEnd);
12241200
}
12251201

12261202
if (OWriter.EmitAddrsigSection) {
12271203
uint64_t SecStart = W.OS.tell();
12281204
writeAddrsigSection();
12291205
uint64_t SecEnd = W.OS.tell();
1230-
SectionOffsets[AddrsigSection] = std::make_pair(SecStart, SecEnd);
1206+
AddrsigSection->setOffsets(SecStart, SecEnd);
12311207
}
12321208
}
12331209

12341210
{
12351211
uint64_t SecStart = W.OS.tell();
12361212
StrTabBuilder.write(W.OS);
1237-
SectionOffsets[StrtabSection] = std::make_pair(SecStart, W.OS.tell());
1213+
StrtabSection->setOffsets(SecStart, W.OS.tell());
12381214
}
12391215

12401216
const uint64_t SectionHeaderOffset = align(is64Bit() ? Align(8) : Align(4));
12411217

12421218
// ... then the section header table ...
1243-
writeSectionHeader(Asm, SectionIndexMap, SectionOffsets);
1219+
writeSectionHeader(Asm);
12441220

12451221
uint16_t NumSections = support::endian::byte_swap<uint16_t>(
12461222
(SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF

0 commit comments

Comments
 (0)