[llvm] Reland "[MC][NFC] Make ELFUniquingMap a StringMap (#95006)" (PR #95030)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 10 12:46:04 PDT 2024
https://github.com/aengelke created https://github.com/llvm/llvm-project/pull/95030
This avoid 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.
>From f2aada80f5ec4105785ff9ab6bb42ae81e04bd0d Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Mon, 10 Jun 2024 18:04:01 +0200
Subject: [PATCH 1/3] [MC] Make ELFUniquingMap a StringMap
This avoid 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).
---
llvm/include/llvm/MC/MCContext.h | 27 +-----------------
llvm/lib/MC/MCContext.cpp | 47 +++++++++++++++++++++++++-------
2 files changed, 38 insertions(+), 36 deletions(-)
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index b0ac432a065bf..4c57c5bd28b77 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -252,31 +252,6 @@ class MCContext {
/// A collection of MCPseudoProbe in the current module
MCPseudoProbeTable PseudoProbeTable;
- // Sections are differentiated by the quadruple (section_name, group_name,
- // unique_id, link_to_symbol_name). Sections sharing the same quadruple are
- // combined into one section.
- struct ELFSectionKey {
- std::string SectionName;
- StringRef GroupName;
- StringRef LinkedToName;
- unsigned UniqueID;
-
- ELFSectionKey(StringRef SectionName, StringRef GroupName,
- StringRef LinkedToName, unsigned UniqueID)
- : SectionName(SectionName), GroupName(GroupName),
- LinkedToName(LinkedToName), UniqueID(UniqueID) {}
-
- bool operator<(const ELFSectionKey &Other) const {
- if (SectionName != Other.SectionName)
- return SectionName < Other.SectionName;
- if (GroupName != Other.GroupName)
- return GroupName < Other.GroupName;
- if (int O = LinkedToName.compare(Other.LinkedToName))
- return O < 0;
- return UniqueID < Other.UniqueID;
- }
- };
-
struct COFFSectionKey {
std::string SectionName;
StringRef GroupName;
@@ -350,7 +325,7 @@ class MCContext {
};
StringMap<MCSectionMachO *> MachOUniquingMap;
- std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap;
+ StringMap<MCSectionELF *> ELFUniquingMap;
std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
std::map<std::string, MCSectionGOFF *> GOFFUniquingMap;
std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap;
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 771ca9c6006ca..d5bde2bcb7301 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -44,6 +44,7 @@
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/EndianStream.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
@@ -548,16 +549,42 @@ MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
if (GroupSym)
Group = GroupSym->getName();
assert(!(LinkedToSym && LinkedToSym->getName().empty()));
- // Do the lookup, if we have a hit, return it.
- auto IterBool = ELFUniquingMap.insert(std::make_pair(
- ELFSectionKey{Section.str(), Group,
- LinkedToSym ? LinkedToSym->getName() : "", UniqueID},
- nullptr));
- auto &Entry = *IterBool.first;
- if (!IterBool.second)
- return Entry.second;
- StringRef CachedName = Entry.first.SectionName;
+ // Sections are differentiated by the quadruple (section_name, group_name,
+ // unique_id, link_to_symbol_name). Sections sharing the same quadruple are
+ // combined into one section. As an optimization, non-unique sections without
+ // group or linked-to symbol have a shorter unique-ing key.
+ std::pair<StringMap<MCSectionELF *>::iterator, bool> EntryNewPair;
+ // Length of the section name, which are the first SectionLen bytes of the key
+ unsigned SectionLen;
+ if (GroupSym || LinkedToSym || UniqueID != MCSection::NonUniqueID) {
+ SmallString<128> Buffer;
+ Section.toVector(Buffer);
+ SectionLen = Buffer.size();
+ Buffer.push_back(0); // separator which cannot occur in the name
+ if (GroupSym)
+ Buffer.append(GroupSym->getName());
+ Buffer.push_back(0); // separator which cannot occur in the name
+ if (LinkedToSym)
+ Buffer.append(LinkedToSym->getName());
+ support::endian::write(Buffer, UniqueID, endianness::native);
+ StringRef UniqueMapKey = StringRef(Buffer);
+ EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr));
+ } else if (!Section.isSingleStringRef()) {
+ SmallString<128> Buffer;
+ SectionLen = Buffer.size();
+ StringRef UniqueMapKey = Section.toStringRef(Buffer);
+ EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr));
+ } else {
+ SectionLen = Section.getSingleStringRef().size();
+ StringRef UniqueMapKey = Section.getSingleStringRef();
+ EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr));
+ }
+
+ if (!EntryNewPair.second)
+ return EntryNewPair.first->second;
+
+ StringRef CachedName = EntryNewPair.first->getKey().take_front(SectionLen);
SectionKind Kind;
if (Flags & ELF::SHF_ARM_PURECODE)
@@ -601,7 +628,7 @@ MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
MCSectionELF *Result =
createELFSectionImpl(CachedName, Type, Flags, Kind, EntrySize, GroupSym,
IsComdat, UniqueID, LinkedToSym);
- Entry.second = Result;
+ EntryNewPair.first->second = Result;
recordELFMergeableSectionInfo(Result->getName(), Result->getFlags(),
Result->getUniqueID(), Result->getEntrySize());
>From e62db55e137f313877427ff51a0592a985d1b175 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Mon, 10 Jun 2024 20:39:03 +0200
Subject: [PATCH 2/3] Reorder fields
---
llvm/include/llvm/MC/MCContext.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 4c57c5bd28b77..b2a52b4297e60 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -325,8 +325,8 @@ class MCContext {
};
StringMap<MCSectionMachO *> MachOUniquingMap;
- StringMap<MCSectionELF *> ELFUniquingMap;
std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
+ StringMap<MCSectionELF *> ELFUniquingMap;
std::map<std::string, MCSectionGOFF *> GOFFUniquingMap;
std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap;
std::map<XCOFFSectionKey, MCSectionXCOFF *> XCOFFUniquingMap;
>From a9e841375939f2691cd27eb42f318eae65c7eaa1 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Mon, 10 Jun 2024 21:32:50 +0200
Subject: [PATCH 3/3] Fix section name length for twines
---
llvm/lib/MC/MCContext.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index d5bde2bcb7301..ef0ac09083f5f 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -572,12 +572,12 @@ MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr));
} else if (!Section.isSingleStringRef()) {
SmallString<128> Buffer;
- SectionLen = Buffer.size();
StringRef UniqueMapKey = Section.toStringRef(Buffer);
+ SectionLen = UniqueMapKey.size();
EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr));
} else {
- SectionLen = Section.getSingleStringRef().size();
StringRef UniqueMapKey = Section.getSingleStringRef();
+ SectionLen = UniqueMapKey.size();
EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr));
}
More information about the llvm-commits
mailing list