Skip to content

Commit 3b8b102

Browse files
authored
[MC] Make ELFEntrySizeMap a DenseMap (#91728)
There is no need for an ordered std::map and also no need to duplicate the section name, which is owned by the ELFSectionKey. Therefore, use a DenseMap instead and don't copy the string. As a further, minor performance optimization, avoid the hash table lookup in isELFGenericMergeableSection when the section name was just added. This slightly improves compilation performance in our application, where we occasionally compile many small object files.
1 parent be9b4da commit 3b8b102

File tree

2 files changed

+11
-23
lines changed

2 files changed

+11
-23
lines changed

llvm/include/llvm/MC/MCContext.h

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -391,29 +391,13 @@ class MCContext {
391391
/// Map of currently defined macros.
392392
StringMap<MCAsmMacro> MacroMap;
393393

394-
struct ELFEntrySizeKey {
395-
std::string SectionName;
396-
unsigned Flags;
397-
unsigned EntrySize;
398-
399-
ELFEntrySizeKey(StringRef SectionName, unsigned Flags, unsigned EntrySize)
400-
: SectionName(SectionName), Flags(Flags), EntrySize(EntrySize) {}
401-
402-
bool operator<(const ELFEntrySizeKey &Other) const {
403-
if (SectionName != Other.SectionName)
404-
return SectionName < Other.SectionName;
405-
if (Flags != Other.Flags)
406-
return Flags < Other.Flags;
407-
return EntrySize < Other.EntrySize;
408-
}
409-
};
410-
411394
// Symbols must be assigned to a section with a compatible entry size and
412395
// flags. This map is used to assign unique IDs to sections to distinguish
413396
// between sections with identical names but incompatible entry sizes and/or
414397
// flags. This can occur when a symbol is explicitly assigned to a section,
415-
// e.g. via __attribute__((section("myname"))).
416-
std::map<ELFEntrySizeKey, unsigned> ELFEntrySizeMap;
398+
// e.g. via __attribute__((section("myname"))). The map key is the tuple
399+
// (section name, flags, entry size).
400+
DenseMap<std::tuple<StringRef, unsigned, unsigned>, unsigned> ELFEntrySizeMap;
417401

418402
// This set is used to record the generic mergeable section names seen.
419403
// These are sections that are created as mergeable e.g. .debug_str. We need

llvm/lib/MC/MCContext.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -620,15 +620,20 @@ void MCContext::recordELFMergeableSectionInfo(StringRef SectionName,
620620
unsigned Flags, unsigned UniqueID,
621621
unsigned EntrySize) {
622622
bool IsMergeable = Flags & ELF::SHF_MERGE;
623-
if (UniqueID == GenericSectionID)
623+
if (UniqueID == GenericSectionID) {
624624
ELFSeenGenericMergeableSections.insert(SectionName);
625+
// Minor performance optimization: avoid hash map lookup in
626+
// isELFGenericMergeableSection, which will return true for SectionName.
627+
IsMergeable = true;
628+
}
625629

626630
// For mergeable sections or non-mergeable sections with a generic mergeable
627631
// section name we enter their Unique ID into the ELFEntrySizeMap so that
628632
// compatible globals can be assigned to the same section.
633+
629634
if (IsMergeable || isELFGenericMergeableSection(SectionName)) {
630635
ELFEntrySizeMap.insert(std::make_pair(
631-
ELFEntrySizeKey{SectionName, Flags, EntrySize}, UniqueID));
636+
std::make_tuple(SectionName, Flags, EntrySize), UniqueID));
632637
}
633638
}
634639

@@ -645,8 +650,7 @@ bool MCContext::isELFGenericMergeableSection(StringRef SectionName) {
645650
std::optional<unsigned>
646651
MCContext::getELFUniqueIDForEntsize(StringRef SectionName, unsigned Flags,
647652
unsigned EntrySize) {
648-
auto I = ELFEntrySizeMap.find(
649-
MCContext::ELFEntrySizeKey{SectionName, Flags, EntrySize});
653+
auto I = ELFEntrySizeMap.find(std::make_tuple(SectionName, Flags, EntrySize));
650654
return (I != ELFEntrySizeMap.end()) ? std::optional<unsigned>(I->second)
651655
: std::nullopt;
652656
}

0 commit comments

Comments
 (0)