Skip to content

Commit 05e87a5

Browse files
authored
Reland "[MC][NFC] Make ELFUniquingMap a StringMap (#95006)" (#95030)
This avoids std::map, which is slow, and uses a StringMap. Section name, group name, linked-to name and unique id are encoded into the key for fast lookup. This gives a measurable performance boost for applications that compile many small object files (e.g., functions in JIT compilers). --- Now also the second case works properly. That's what happens when you do that last refactoring without re-running all tests... sorry.
1 parent 2825342 commit 05e87a5

File tree

2 files changed

+38
-36
lines changed

2 files changed

+38
-36
lines changed

llvm/include/llvm/MC/MCContext.h

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -252,31 +252,6 @@ class MCContext {
252252
/// A collection of MCPseudoProbe in the current module
253253
MCPseudoProbeTable PseudoProbeTable;
254254

255-
// Sections are differentiated by the quadruple (section_name, group_name,
256-
// unique_id, link_to_symbol_name). Sections sharing the same quadruple are
257-
// combined into one section.
258-
struct ELFSectionKey {
259-
std::string SectionName;
260-
StringRef GroupName;
261-
StringRef LinkedToName;
262-
unsigned UniqueID;
263-
264-
ELFSectionKey(StringRef SectionName, StringRef GroupName,
265-
StringRef LinkedToName, unsigned UniqueID)
266-
: SectionName(SectionName), GroupName(GroupName),
267-
LinkedToName(LinkedToName), UniqueID(UniqueID) {}
268-
269-
bool operator<(const ELFSectionKey &Other) const {
270-
if (SectionName != Other.SectionName)
271-
return SectionName < Other.SectionName;
272-
if (GroupName != Other.GroupName)
273-
return GroupName < Other.GroupName;
274-
if (int O = LinkedToName.compare(Other.LinkedToName))
275-
return O < 0;
276-
return UniqueID < Other.UniqueID;
277-
}
278-
};
279-
280255
struct COFFSectionKey {
281256
std::string SectionName;
282257
StringRef GroupName;
@@ -350,8 +325,8 @@ class MCContext {
350325
};
351326

352327
StringMap<MCSectionMachO *> MachOUniquingMap;
353-
std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap;
354328
std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
329+
StringMap<MCSectionELF *> ELFUniquingMap;
355330
std::map<std::string, MCSectionGOFF *> GOFFUniquingMap;
356331
std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap;
357332
std::map<XCOFFSectionKey, MCSectionXCOFF *> XCOFFUniquingMap;

llvm/lib/MC/MCContext.cpp

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "llvm/MC/SectionKind.h"
4545
#include "llvm/Support/Casting.h"
4646
#include "llvm/Support/CommandLine.h"
47+
#include "llvm/Support/EndianStream.h"
4748
#include "llvm/Support/ErrorHandling.h"
4849
#include "llvm/Support/MemoryBuffer.h"
4950
#include "llvm/Support/Path.h"
@@ -547,16 +548,42 @@ MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
547548
if (GroupSym)
548549
Group = GroupSym->getName();
549550
assert(!(LinkedToSym && LinkedToSym->getName().empty()));
550-
// Do the lookup, if we have a hit, return it.
551-
auto IterBool = ELFUniquingMap.insert(std::make_pair(
552-
ELFSectionKey{Section.str(), Group,
553-
LinkedToSym ? LinkedToSym->getName() : "", UniqueID},
554-
nullptr));
555-
auto &Entry = *IterBool.first;
556-
if (!IterBool.second)
557-
return Entry.second;
558551

559-
StringRef CachedName = Entry.first.SectionName;
552+
// Sections are differentiated by the quadruple (section_name, group_name,
553+
// unique_id, link_to_symbol_name). Sections sharing the same quadruple are
554+
// combined into one section. As an optimization, non-unique sections without
555+
// group or linked-to symbol have a shorter unique-ing key.
556+
std::pair<StringMap<MCSectionELF *>::iterator, bool> EntryNewPair;
557+
// Length of the section name, which are the first SectionLen bytes of the key
558+
unsigned SectionLen;
559+
if (GroupSym || LinkedToSym || UniqueID != MCSection::NonUniqueID) {
560+
SmallString<128> Buffer;
561+
Section.toVector(Buffer);
562+
SectionLen = Buffer.size();
563+
Buffer.push_back(0); // separator which cannot occur in the name
564+
if (GroupSym)
565+
Buffer.append(GroupSym->getName());
566+
Buffer.push_back(0); // separator which cannot occur in the name
567+
if (LinkedToSym)
568+
Buffer.append(LinkedToSym->getName());
569+
support::endian::write(Buffer, UniqueID, endianness::native);
570+
StringRef UniqueMapKey = StringRef(Buffer);
571+
EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr));
572+
} else if (!Section.isSingleStringRef()) {
573+
SmallString<128> Buffer;
574+
StringRef UniqueMapKey = Section.toStringRef(Buffer);
575+
SectionLen = UniqueMapKey.size();
576+
EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr));
577+
} else {
578+
StringRef UniqueMapKey = Section.getSingleStringRef();
579+
SectionLen = UniqueMapKey.size();
580+
EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr));
581+
}
582+
583+
if (!EntryNewPair.second)
584+
return EntryNewPair.first->second;
585+
586+
StringRef CachedName = EntryNewPair.first->getKey().take_front(SectionLen);
560587

561588
SectionKind Kind;
562589
if (Flags & ELF::SHF_ARM_PURECODE)
@@ -600,7 +627,7 @@ MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
600627
MCSectionELF *Result =
601628
createELFSectionImpl(CachedName, Type, Flags, Kind, EntrySize, GroupSym,
602629
IsComdat, UniqueID, LinkedToSym);
603-
Entry.second = Result;
630+
EntryNewPair.first->second = Result;
604631

605632
recordELFMergeableSectionInfo(Result->getName(), Result->getFlags(),
606633
Result->getUniqueID(), Result->getEntrySize());

0 commit comments

Comments
 (0)