diff options
author | aengelke <engelke@in.tum.de> | 2024-06-20 11:36:11 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-20 11:36:11 +0200 |
commit | c1a7c5ac73af92316426deed5f8f10f33f729ad2 (patch) | |
tree | 267c89e4ae2b34b97035a1fd6a7ec8f44ec7eec8 /llvm | |
parent | 919c547130cfd1cd75ccf148cbf2334b27b2f37f (diff) | |
download | llvm-c1a7c5ac73af92316426deed5f8f10f33f729ad2.zip llvm-c1a7c5ac73af92316426deed5f8f10f33f729ad2.tar.gz llvm-c1a7c5ac73af92316426deed5f8f10f33f729ad2.tar.bz2 |
[MC] Eliminate two symbol-related hash maps (#95464)
Previously, a symbol insertion requires (at least) three hash table
operations:
- Lookup/create entry in Symbols (main symbol table)
- Lookup NextUniqueID to deduplicate identical temporary labels
- Add entry to UsedNames, which is also used to serve as storage for the
symbol name in the MCSymbol.
All three lookups are done with the same name, so combining these into a
single table reduces the number of lookups to one. Thus, a pointer to a
symbol table entry can be passed to createSymbol to avoid a duplicate
lookup of the same name.
The new symbol table entry value is placed in a separate header to avoid
including MCContext in MCSymbol or vice versa.
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/MC/MCContext.h | 28 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCSymbol.h | 12 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCSymbolCOFF.h | 3 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCSymbolELF.h | 3 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCSymbolGOFF.h | 3 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCSymbolMachO.h | 3 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCSymbolTableEntry.h | 45 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCSymbolWasm.h | 3 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCSymbolXCOFF.h | 3 | ||||
-rw-r--r-- | llvm/lib/MC/MCContext.cpp | 125 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/MasmParser.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/MC/MCSymbol.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp | 4 |
14 files changed, 144 insertions, 100 deletions
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h index 3fe4c28..e32a532 100644 --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -21,6 +21,7 @@ #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCPseudoProbe.h" #include "llvm/MC/MCSection.h" +#include "llvm/MC/MCSymbolTableEntry.h" #include "llvm/MC/SectionKind.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" @@ -81,7 +82,7 @@ struct WasmSignature; /// class MCContext { public: - using SymbolTable = StringMap<MCSymbol *, BumpPtrAllocator &>; + using SymbolTable = StringMap<MCSymbolTableValue, BumpPtrAllocator &>; using DiagHandlerTy = std::function<void(const SMDiagnostic &, bool, const SourceMgr &, std::vector<const MDNode *> &)>; @@ -147,7 +148,7 @@ private: SpecificBumpPtrAllocator<wasm::WasmSignature> WasmSignatureAllocator; - /// Bindings of names to symbols. + /// Bindings of names to symbol table values. SymbolTable Symbols; /// A mapping from a local label number and an instance count to a symbol. @@ -158,18 +159,8 @@ private: /// We have three labels represented by the pairs (1, 0), (2, 0) and (1, 1) DenseMap<std::pair<unsigned, unsigned>, MCSymbol *> LocalSymbols; - /// Keeps tracks of names that were used both for used declared and - /// artificial symbols. The value is "true" if the name has been used for a - /// non-section symbol (there can be at most one of those, plus an unlimited - /// number of section symbols with the same name). - StringMap<bool, BumpPtrAllocator &> UsedNames; - /// Keeps track of labels that are used in inline assembly. - SymbolTable InlineAsmUsedLabelNames; - - /// The next ID to dole out to an unnamed assembler temporary symbol with - /// a given prefix. - StringMap<unsigned> NextID; + StringMap<MCSymbol *, BumpPtrAllocator &> InlineAsmUsedLabelNames; /// Instances of directional local labels. DenseMap<unsigned, MCLabel *> Instances; @@ -348,10 +339,11 @@ private: MCDataFragment *allocInitialFragment(MCSection &Sec); - MCSymbol *createSymbolImpl(const StringMapEntry<bool> *Name, - bool IsTemporary); - MCSymbol *createSymbol(StringRef Name, bool AlwaysAddSuffix, - bool IsTemporary); + MCSymbolTableEntry &getSymbolTableEntry(StringRef Name); + + MCSymbol *createSymbolImpl(const MCSymbolTableEntry *Name, bool IsTemporary); + MCSymbol *createRenamableSymbol(const Twine &Name, bool AlwaysAddSuffix, + bool IsTemporary); MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal, unsigned Instance); @@ -362,7 +354,7 @@ private: unsigned UniqueID, const MCSymbolELF *LinkedToSym); - MCSymbolXCOFF *createXCOFFSymbolImpl(const StringMapEntry<bool> *Name, + MCSymbolXCOFF *createXCOFFSymbolImpl(const MCSymbolTableEntry *Name, bool IsTemporary); /// Map of currently defined macros. diff --git a/llvm/include/llvm/MC/MCSymbol.h b/llvm/include/llvm/MC/MCSymbol.h index a53e531..5f06249 100644 --- a/llvm/include/llvm/MC/MCSymbol.h +++ b/llvm/include/llvm/MC/MCSymbol.h @@ -17,6 +17,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFragment.h" +#include "llvm/MC/MCSymbolTableEntry.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include <cassert> @@ -156,11 +157,11 @@ protected: /// system, the name is a pointer so isn't going to satisfy the 8 byte /// alignment of uint64_t. Account for that here. using NameEntryStorageTy = union { - const StringMapEntry<bool> *NameEntry; + const MCSymbolTableEntry *NameEntry; uint64_t AlignmentPadding; }; - MCSymbol(SymbolKind Kind, const StringMapEntry<bool> *Name, bool isTemporary) + MCSymbol(SymbolKind Kind, const MCSymbolTableEntry *Name, bool isTemporary) : IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false), IsRegistered(false), IsExternal(false), IsPrivateExtern(false), IsWeakExternal(false), Kind(Kind), IsUsedInReloc(false), @@ -173,8 +174,7 @@ protected: // Provide custom new/delete as we will only allocate space for a name // if we need one. - void *operator new(size_t s, const StringMapEntry<bool> *Name, - MCContext &Ctx); + void *operator new(size_t s, const MCSymbolTableEntry *Name, MCContext &Ctx); private: void operator delete(void *); @@ -188,12 +188,12 @@ private: } /// Get a reference to the name field. Requires that we have a name - const StringMapEntry<bool> *&getNameEntryPtr() { + const MCSymbolTableEntry *&getNameEntryPtr() { assert(HasName && "Name is required"); NameEntryStorageTy *Name = reinterpret_cast<NameEntryStorageTy *>(this); return (*(Name - 1)).NameEntry; } - const StringMapEntry<bool> *&getNameEntryPtr() const { + const MCSymbolTableEntry *&getNameEntryPtr() const { return const_cast<MCSymbol*>(this)->getNameEntryPtr(); } diff --git a/llvm/include/llvm/MC/MCSymbolCOFF.h b/llvm/include/llvm/MC/MCSymbolCOFF.h index 7983fff..2964c52 100644 --- a/llvm/include/llvm/MC/MCSymbolCOFF.h +++ b/llvm/include/llvm/MC/MCSymbolCOFF.h @@ -11,6 +11,7 @@ #include "llvm/BinaryFormat/COFF.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolTableEntry.h" #include <cstdint> namespace llvm { @@ -29,7 +30,7 @@ class MCSymbolCOFF : public MCSymbol { }; public: - MCSymbolCOFF(const StringMapEntry<bool> *Name, bool isTemporary) + MCSymbolCOFF(const MCSymbolTableEntry *Name, bool isTemporary) : MCSymbol(SymbolKindCOFF, Name, isTemporary) {} uint16_t getType() const { diff --git a/llvm/include/llvm/MC/MCSymbolELF.h b/llvm/include/llvm/MC/MCSymbolELF.h index 9fc49ea..13c2c6b 100644 --- a/llvm/include/llvm/MC/MCSymbolELF.h +++ b/llvm/include/llvm/MC/MCSymbolELF.h @@ -9,6 +9,7 @@ #define LLVM_MC_MCSYMBOLELF_H #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolTableEntry.h" namespace llvm { class MCSymbolELF : public MCSymbol { @@ -17,7 +18,7 @@ class MCSymbolELF : public MCSymbol { const MCExpr *SymbolSize = nullptr; public: - MCSymbolELF(const StringMapEntry<bool> *Name, bool isTemporary) + MCSymbolELF(const MCSymbolTableEntry *Name, bool isTemporary) : MCSymbol(SymbolKindELF, Name, isTemporary) {} void setSize(const MCExpr *SS) { SymbolSize = SS; } diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h index cc4e2bb..9ca53a5 100644 --- a/llvm/include/llvm/MC/MCSymbolGOFF.h +++ b/llvm/include/llvm/MC/MCSymbolGOFF.h @@ -14,12 +14,13 @@ #define LLVM_MC_MCSYMBOLGOFF_H #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolTableEntry.h" namespace llvm { class MCSymbolGOFF : public MCSymbol { public: - MCSymbolGOFF(const StringMapEntry<bool> *Name, bool IsTemporary) + MCSymbolGOFF(const MCSymbolTableEntry *Name, bool IsTemporary) : MCSymbol(SymbolKindGOFF, Name, IsTemporary) {} static bool classof(const MCSymbol *S) { return S->isGOFF(); } }; diff --git a/llvm/include/llvm/MC/MCSymbolMachO.h b/llvm/include/llvm/MC/MCSymbolMachO.h index bce0f82..f75f61c 100644 --- a/llvm/include/llvm/MC/MCSymbolMachO.h +++ b/llvm/include/llvm/MC/MCSymbolMachO.h @@ -10,6 +10,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolTableEntry.h" namespace llvm { class MCSymbolMachO : public MCSymbol { @@ -42,7 +43,7 @@ class MCSymbolMachO : public MCSymbol { }; public: - MCSymbolMachO(const StringMapEntry<bool> *Name, bool isTemporary) + MCSymbolMachO(const MCSymbolTableEntry *Name, bool isTemporary) : MCSymbol(SymbolKindMachO, Name, isTemporary) {} // Reference type methods. diff --git a/llvm/include/llvm/MC/MCSymbolTableEntry.h b/llvm/include/llvm/MC/MCSymbolTableEntry.h new file mode 100644 index 0000000..4d9b85f --- /dev/null +++ b/llvm/include/llvm/MC/MCSymbolTableEntry.h @@ -0,0 +1,45 @@ +//===-- llvm/MC/MCSymbolTableEntry.h - Symbol table entry -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCSYMBOLTABLEENTRY_H +#define LLVM_MC_MCSYMBOLTABLEENTRY_H + +#include "llvm/ADT/StringMapEntry.h" + +namespace llvm { + +class MCSymbol; + +/// The value for an entry in the symbol table of an MCContext. +/// +/// This is in a separate file, because MCSymbol uses MCSymbolTableEntry (see +/// below) to reuse the name that is stored in the symbol table. +struct MCSymbolTableValue { + /// The symbol associated with the name, if any. + MCSymbol *Symbol = nullptr; + + /// The next ID to dole out to an unnamed assembler temporary symbol with + /// the prefix (symbol table key). + unsigned NextUniqueID = 0; + + /// Whether the name associated with this value is used for a symbol. This is + /// not necessarily true: sometimes, we use a symbol table value without an + /// associated symbol for accessing NextUniqueID when a suffix is added to a + /// name. However, Used might be true even if Symbol is nullptr: temporary + /// named symbols are not added to the symbol table. + bool Used = false; +}; + +/// MCContext stores MCSymbolTableValue in a string map (see MCSymbol::operator +/// new). To avoid redundant storage of the name, MCSymbol stores a pointer (8 +/// bytes -- half the size of a StringRef) to the entry to access it. +using MCSymbolTableEntry = StringMapEntry<MCSymbolTableValue>; + +} // end namespace llvm + +#endif diff --git a/llvm/include/llvm/MC/MCSymbolWasm.h b/llvm/include/llvm/MC/MCSymbolWasm.h index 0c2b97a..e566ad8 100644 --- a/llvm/include/llvm/MC/MCSymbolWasm.h +++ b/llvm/include/llvm/MC/MCSymbolWasm.h @@ -10,6 +10,7 @@ #include "llvm/BinaryFormat/Wasm.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolTableEntry.h" namespace llvm { @@ -33,7 +34,7 @@ class MCSymbolWasm : public MCSymbol { const MCExpr *SymbolSize = nullptr; public: - MCSymbolWasm(const StringMapEntry<bool> *Name, bool isTemporary) + MCSymbolWasm(const MCSymbolTableEntry *Name, bool isTemporary) : MCSymbol(SymbolKindWasm, Name, isTemporary) {} static bool classof(const MCSymbol *S) { return S->isWasm(); } diff --git a/llvm/include/llvm/MC/MCSymbolXCOFF.h b/llvm/include/llvm/MC/MCSymbolXCOFF.h index 3bf4491..8877431 100644 --- a/llvm/include/llvm/MC/MCSymbolXCOFF.h +++ b/llvm/include/llvm/MC/MCSymbolXCOFF.h @@ -11,6 +11,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/XCOFF.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolTableEntry.h" namespace llvm { @@ -21,7 +22,7 @@ class MCSymbolXCOFF : public MCSymbol { enum XCOFFSymbolFlags : uint16_t { SF_EHInfo = 0x0001 }; public: - MCSymbolXCOFF(const StringMapEntry<bool> *Name, bool isTemporary) + MCSymbolXCOFF(const MCSymbolTableEntry *Name, bool isTemporary) : MCSymbol(SymbolKindXCOFF, Name, isTemporary) {} static bool classof(const MCSymbol *S) { return S->isXCOFF(); } diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index 432ff5e7..9c7cb74 100644 --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -70,7 +70,7 @@ MCContext::MCContext(const Triple &TheTriple, const MCAsmInfo *mai, bool DoAutoReset, StringRef Swift5ReflSegmentName) : Swift5ReflectionSegmentName(Swift5ReflSegmentName), TT(TheTriple), SrcMgr(mgr), InlineSrcMgr(nullptr), DiagHandler(defaultDiagHandler), - MAI(mai), MRI(mri), MSTI(msti), Symbols(Allocator), UsedNames(Allocator), + MAI(mai), MRI(mri), MSTI(msti), Symbols(Allocator), InlineAsmUsedLabelNames(Allocator), CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), AutoReset(DoAutoReset), TargetOptions(TargetOpts) { @@ -153,7 +153,6 @@ void MCContext::reset() { MCSubtargetAllocator.DestroyAll(); InlineAsmUsedLabelNames.clear(); - UsedNames.clear(); Symbols.clear(); Allocator.Reset(); Instances.clear(); @@ -179,7 +178,6 @@ void MCContext::reset() { ELFEntrySizeMap.clear(); ELFSeenGenericMergeableSections.clear(); - NextID.clear(); DwarfLocSeen = false; GenDwarfForAssembly = false; GenDwarfFileNumber = 0; @@ -214,11 +212,21 @@ MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) { assert(!NameRef.empty() && "Normal symbols cannot be unnamed!"); - MCSymbol *&Sym = Symbols[NameRef]; - if (!Sym) - Sym = createSymbol(NameRef, false, false); + MCSymbolTableEntry &Entry = getSymbolTableEntry(NameRef); + if (!Entry.second.Symbol) { + bool IsRenamable = NameRef.starts_with(MAI->getPrivateGlobalPrefix()); + bool IsTemporary = IsRenamable && !SaveTempLabels; + if (!Entry.second.Used) { + Entry.second.Used = true; + Entry.second.Symbol = createSymbolImpl(&Entry, IsTemporary); + } else { + assert(IsRenamable && "cannot rename non-private symbol"); + // Slow path: we need to rename a temp symbol from the user. + Entry.second.Symbol = createRenamableSymbol(NameRef, false, IsTemporary); + } + } - return Sym; + return Entry.second.Symbol; } MCSymbol *MCContext::getOrCreateFrameAllocSymbol(const Twine &FuncName, @@ -237,7 +245,11 @@ MCSymbol *MCContext::getOrCreateLSDASymbol(const Twine &FuncName) { FuncName); } -MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name, +MCSymbolTableEntry &MCContext::getSymbolTableEntry(StringRef Name) { + return *Symbols.try_emplace(Name, MCSymbolTableValue{}).first; +} + +MCSymbol *MCContext::createSymbolImpl(const MCSymbolTableEntry *Name, bool IsTemporary) { static_assert(std::is_trivially_destructible<MCSymbolCOFF>(), "MCSymbol classes must be trivially destructible"); @@ -273,49 +285,37 @@ MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name, MCSymbol(MCSymbol::SymbolKindUnset, Name, IsTemporary); } -MCSymbol *MCContext::createSymbol(StringRef Name, bool AlwaysAddSuffix, - bool IsTemporary) { - // Determine whether this is a user written assembler temporary or normal - // label, if used. - if (!SaveTempLabels && !IsTemporary) - IsTemporary = Name.starts_with(MAI->getPrivateGlobalPrefix()); - - SmallString<128> NewName = Name; - bool AddSuffix = AlwaysAddSuffix; - unsigned &NextUniqueID = NextID[Name]; - while (true) { - if (AddSuffix) { - NewName.resize(Name.size()); - raw_svector_ostream(NewName) << NextUniqueID++; - } - auto NameEntry = UsedNames.insert(std::make_pair(NewName.str(), true)); - if (NameEntry.second || !NameEntry.first->second) { - // Ok, we found a name. - // Mark it as used for a non-section symbol. - NameEntry.first->second = true; - // Have the MCSymbol object itself refer to the copy of the string that is - // embedded in the UsedNames entry. - return createSymbolImpl(&*NameEntry.first, IsTemporary); - } - assert(IsTemporary && "Cannot rename non-temporary symbols"); - AddSuffix = true; +MCSymbol *MCContext::createRenamableSymbol(const Twine &Name, + bool AlwaysAddSuffix, + bool IsTemporary) { + SmallString<128> NewName; + Name.toVector(NewName); + size_t NameLen = NewName.size(); + + MCSymbolTableEntry &NameEntry = getSymbolTableEntry(NewName.str()); + MCSymbolTableEntry *EntryPtr = &NameEntry; + while (AlwaysAddSuffix || EntryPtr->second.Used) { + AlwaysAddSuffix = false; + + NewName.resize(NameLen); + raw_svector_ostream(NewName) << NameEntry.second.NextUniqueID++; + EntryPtr = &getSymbolTableEntry(NewName.str()); } - llvm_unreachable("Infinite loop"); + + EntryPtr->second.Used = true; + return createSymbolImpl(EntryPtr, IsTemporary); } MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix) { if (!UseNamesOnTempLabels) return createSymbolImpl(nullptr, /*IsTemporary=*/true); - - SmallString<128> NameSV; - raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name; - return createSymbol(NameSV, AlwaysAddSuffix, true); + return createRenamableSymbol(MAI->getPrivateGlobalPrefix() + Name, + AlwaysAddSuffix, /*IsTemporary=*/true); } MCSymbol *MCContext::createNamedTempSymbol(const Twine &Name) { - SmallString<128> NameSV; - raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name; - return createSymbol(NameSV, true, false); + return createRenamableSymbol(MAI->getPrivateGlobalPrefix() + Name, true, + /*IsTemporary=*/!SaveTempLabels); } MCSymbol *MCContext::createLinkerPrivateTempSymbol() { @@ -323,9 +323,9 @@ MCSymbol *MCContext::createLinkerPrivateTempSymbol() { } MCSymbol *MCContext::createLinkerPrivateSymbol(const Twine &Name) { - SmallString<128> NameSV; - raw_svector_ostream(NameSV) << MAI->getLinkerPrivateGlobalPrefix() << Name; - return createSymbol(NameSV, true, false); + return createRenamableSymbol(MAI->getLinkerPrivateGlobalPrefix() + Name, + /*AlwaysAddSuffix=*/true, + /*IsTemporary=*/false); } MCSymbol *MCContext::createTempSymbol() { return createTempSymbol("tmp"); } @@ -372,7 +372,7 @@ MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal, MCSymbol *MCContext::lookupSymbol(const Twine &Name) const { SmallString<128> NameSV; StringRef NameRef = Name.toStringRef(NameSV); - return Symbols.lookup(NameRef); + return Symbols.lookup(NameRef).Symbol; } void MCContext::setSymbolValue(MCStreamer &Streamer, const Twine &Sym, @@ -389,9 +389,8 @@ wasm::WasmSignature *MCContext::createWasmSignature() { return new (WasmSignatureAllocator.Allocate()) wasm::WasmSignature; } -MCSymbolXCOFF * -MCContext::createXCOFFSymbolImpl(const StringMapEntry<bool> *Name, - bool IsTemporary) { +MCSymbolXCOFF *MCContext::createXCOFFSymbolImpl(const MCSymbolTableEntry *Name, + bool IsTemporary) { if (!Name) return new (nullptr, *this) MCSymbolXCOFF(nullptr, IsTemporary); @@ -431,15 +430,13 @@ MCContext::createXCOFFSymbolImpl(const StringMapEntry<bool> *Name, else ValidName.append(InvalidName); - auto NameEntry = UsedNames.insert(std::make_pair(ValidName.str(), true)); - assert((NameEntry.second || !NameEntry.first->second) && - "This name is used somewhere else."); - // Mark the name as used for a non-section symbol. - NameEntry.first->second = true; + MCSymbolTableEntry &NameEntry = getSymbolTableEntry(ValidName.str()); + assert(!NameEntry.second.Used && "This name is used somewhere else."); + NameEntry.second.Used = true; // Have the MCSymbol object itself refer to the copy of the string - // that is embedded in the UsedNames entry. - MCSymbolXCOFF *XSym = new (&*NameEntry.first, *this) - MCSymbolXCOFF(&*NameEntry.first, IsTemporary); + // that is embedded in the symbol table entry. + MCSymbolXCOFF *XSym = + new (&NameEntry, *this) MCSymbolXCOFF(&NameEntry, IsTemporary); XSym->setSymbolTableName(MCSymbolXCOFF::getUnqualifiedName(OriginalName)); return XSym; } @@ -485,7 +482,8 @@ MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type, bool Comdat, unsigned UniqueID, const MCSymbolELF *LinkedToSym) { MCSymbolELF *R; - MCSymbol *&Sym = Symbols[Section]; + MCSymbolTableEntry &SymEntry = getSymbolTableEntry(Section); + MCSymbol *Sym = SymEntry.second.Symbol; // A section symbol can not redefine regular symbols. There may be multiple // sections with the same name, in which case the first such section wins. if (Sym && Sym->isDefined() && @@ -494,10 +492,10 @@ MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type, if (Sym && Sym->isUndefined()) { R = cast<MCSymbolELF>(Sym); } else { - auto NameIter = UsedNames.insert(std::make_pair(Section, false)).first; - R = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false); + SymEntry.second.Used = true; + R = new (&SymEntry, *this) MCSymbolELF(&SymEntry, /*isTemporary*/ false); if (!Sym) - Sym = R; + SymEntry.second.Symbol = R; } R->setBinding(ELF::STB_LOCAL); R->setType(ELF::STT_SECTION); @@ -750,8 +748,9 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind, StringRef CachedName = Entry.first.SectionName; - MCSymbol *Begin = createSymbol(CachedName, true, false); - Symbols[Begin->getName()] = Begin; + MCSymbol *Begin = createRenamableSymbol(CachedName, true, false); + // Begin always has a different name than CachedName... see #48596. + getSymbolTableEntry(Begin->getName()).second.Symbol = Begin; cast<MCSymbolWasm>(Begin)->setType(wasm::WASM_SYMBOL_TYPE_SECTION); MCSectionWasm *Result = new (WasmAllocator.Allocate()) diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index ddbf99b..6e7ec68 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -1044,11 +1044,12 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { if (!NoFinalize) { if (MAI.hasSubsectionsViaSymbols()) { for (const auto &TableEntry : getContext().getSymbols()) { - MCSymbol *Sym = TableEntry.getValue(); + MCSymbol *Sym = TableEntry.getValue().Symbol; // Variable symbols may not be marked as defined, so check those // explicitly. If we know it's a variable, we have a definition for // the purposes of this check. - if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined()) + if (Sym && Sym->isTemporary() && !Sym->isVariable() && + !Sym->isDefined()) // FIXME: We would really like to refer back to where the symbol was // first referenced for a source location. We need to add something // to track that. Currently, we just point to the end of the file. diff --git a/llvm/lib/MC/MCParser/MasmParser.cpp b/llvm/lib/MC/MCParser/MasmParser.cpp index 5ed66fb..67f3540 100644 --- a/llvm/lib/MC/MCParser/MasmParser.cpp +++ b/llvm/lib/MC/MCParser/MasmParser.cpp @@ -1421,11 +1421,12 @@ bool MasmParser::Run(bool NoInitialTextSection, bool NoFinalize) { if (!NoFinalize) { if (MAI.hasSubsectionsViaSymbols()) { for (const auto &TableEntry : getContext().getSymbols()) { - MCSymbol *Sym = TableEntry.getValue(); + MCSymbol *Sym = TableEntry.getValue().Symbol; // Variable symbols may not be marked as defined, so check those // explicitly. If we know it's a variable, we have a definition for // the purposes of this check. - if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined()) + if (Sym && Sym->isTemporary() && !Sym->isVariable() && + !Sym->isDefined()) // FIXME: We would really like to refer back to where the symbol was // first referenced for a source location. We need to add something // to track that. Currently, we just point to the end of the file. diff --git a/llvm/lib/MC/MCSymbol.cpp b/llvm/lib/MC/MCSymbol.cpp index 4017225..867a472 100644 --- a/llvm/lib/MC/MCSymbol.cpp +++ b/llvm/lib/MC/MCSymbol.cpp @@ -27,7 +27,7 @@ static MCDummyFragment SentinelFragment(nullptr); // Sentinel value for the absolute pseudo fragment. MCFragment *MCSymbol::AbsolutePseudoFragment = &SentinelFragment; -void *MCSymbol::operator new(size_t s, const StringMapEntry<bool> *Name, +void *MCSymbol::operator new(size_t s, const MCSymbolTableEntry *Name, MCContext &Ctx) { // We may need more space for a Name to account for alignment. So allocate // space for the storage type and not the name pointer. diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index 0b7ec6e..b0a97c7 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -319,8 +319,8 @@ void WebAssemblyAsmPrinter::emitDecls(const Module &M) { // Emit .globaltype, .tagtype, or .tabletype declarations for extern // declarations, i.e. those that have only been declared (but not defined) // in the current module - auto Sym = cast<MCSymbolWasm>(It.getValue()); - if (!Sym->isDefined()) + auto Sym = cast_or_null<MCSymbolWasm>(It.getValue().Symbol); + if (Sym && !Sym->isDefined()) emitSymbolType(Sym); } |