diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h index b0ac432a065bf0..b2a52b4297e603 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,8 +325,8 @@ class MCContext { }; StringMap MachOUniquingMap; - std::map ELFUniquingMap; std::map COFFUniquingMap; + StringMap ELFUniquingMap; std::map GOFFUniquingMap; std::map WasmUniquingMap; std::map XCOFFUniquingMap; diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index 771ca9c6006ca0..ef0ac09083f5f8 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::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; + StringRef UniqueMapKey = Section.toStringRef(Buffer); + SectionLen = UniqueMapKey.size(); + EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr)); + } else { + StringRef UniqueMapKey = Section.getSingleStringRef(); + SectionLen = UniqueMapKey.size(); + 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());