diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 882929f2eee..0a296cd2974 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -10,6 +10,7 @@ #ifndef LLVM_MC_MCASSEMBLER_H #define LLVM_MC_MCASSEMBLER_H +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" @@ -587,6 +588,16 @@ private: iplist Symbols; + /// The map of sections to their associated assembler backend data. + // + // FIXME: Avoid this indirection? + DenseMap SectionMap; + + /// The map of symbols to their associated assembler backend data. + // + // FIXME: Avoid this indirection? + DenseMap SymbolMap; + std::vector IndirectSymbols; unsigned SubsectionsViaSymbols : 1; @@ -672,6 +683,44 @@ public: size_t indirect_symbol_size() const { return IndirectSymbols.size(); } + /// @} + /// @name Backend Data Access + /// @{ + + MCSectionData &getSectionData(const MCSection &Section) { + MCSectionData *&Entry = SectionMap[&Section]; + assert(Entry && "Missing section data!"); + return *Entry; + } + + MCSectionData &getOrCreateSectionData(const MCSection &Section, + bool *Created = 0) { + MCSectionData *&Entry = SectionMap[&Section]; + + if (Created) *Created = !Entry; + if (!Entry) + Entry = new MCSectionData(Section, this); + + return *Entry; + } + + MCSymbolData &getSymbolData(const MCSymbol &Symbol) { + MCSymbolData *&Entry = SymbolMap[&Symbol]; + assert(Entry && "Missing symbol data!"); + return *Entry; + } + + MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol, + bool *Created = 0) { + MCSymbolData *&Entry = SymbolMap[&Symbol]; + + if (Created) *Created = !Entry; + if (!Entry) + Entry = new MCSymbolData(Symbol, 0, 0, this); + + return *Entry; + } + /// @} void dump(); diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 9f62efee2f9..a35aae29a8c 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -47,8 +47,6 @@ private: MCAssembler Assembler; MCCodeEmitter *Emitter; MCSectionData *CurSectionData; - DenseMap SectionMap; - DenseMap SymbolMap; private: MCFragment *getCurrentFragment() const { @@ -60,24 +58,6 @@ private: return 0; } - MCSectionData &getSectionData(const MCSection &Section) { - MCSectionData *&Entry = SectionMap[&Section]; - - if (!Entry) - Entry = new MCSectionData(Section, &Assembler); - - return *Entry; - } - - MCSymbolData &getSymbolData(const MCSymbol &Symbol) { - MCSymbolData *&Entry = SymbolMap[&Symbol]; - - if (!Entry) - Entry = new MCSymbolData(Symbol, 0, 0, &Assembler); - - return *Entry; - } - public: MCMachOStreamer(MCContext &Context, raw_ostream &_OS, MCCodeEmitter *_Emitter) : MCStreamer(Context), Assembler(Context, _OS), Emitter(_Emitter), @@ -98,7 +78,8 @@ public: } case MCExpr::SymbolRef: - getSymbolData(cast(Value)->getSymbol()); + Assembler.getOrCreateSymbolData( + cast(Value)->getSymbol()); break; case MCExpr::Unary: @@ -163,7 +144,7 @@ void MCMachOStreamer::SwitchSection(const MCSection *Section) { if (Section == CurSection) return; CurSection = Section; - CurSectionData = &getSectionData(*Section); + CurSectionData = &Assembler.getOrCreateSectionData(*Section); } void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) { @@ -174,7 +155,7 @@ void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) { if (!F) F = new MCDataFragment(CurSectionData); - MCSymbolData &SD = getSymbolData(*Symbol); + MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); SD.setFragment(F); SD.setOffset(F->getContents().size()); @@ -220,9 +201,9 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, } // Adding a symbol attribute always introduces the symbol, note that an - // important side effect of calling getSymbolData here is to register the - // symbol with the assembler. - MCSymbolData &SD = getSymbolData(*Symbol); + // important side effect of calling getOrCreateSymbolData here is to register + // the symbol with the assembler. + MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); // The implementation of symbol attributes is designed to match 'as', but it // leaves much to desired. It doesn't really make sense to arbitrarily add and @@ -288,7 +269,7 @@ void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { // Encode the 'desc' value into the lowest implementation defined bits. assert(DescValue == (DescValue & SF_DescFlagsMask) && "Invalid .desc value!"); - getSymbolData(*Symbol).setFlags(DescValue & SF_DescFlagsMask); + Assembler.getOrCreateSymbolData(*Symbol).setFlags(DescValue&SF_DescFlagsMask); } void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, @@ -296,14 +277,14 @@ void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself. assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); - MCSymbolData &SD = getSymbolData(*Symbol); + MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); SD.setExternal(true); SD.setCommon(Size, ByteAlignment); } void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, unsigned Size, unsigned ByteAlignment) { - MCSectionData &SectData = getSectionData(*Section); + MCSectionData &SectData = Assembler.getOrCreateSectionData(*Section); // The symbol may not be present, which only creates the section. if (!Symbol) @@ -313,7 +294,7 @@ void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); - MCSymbolData &SD = getSymbolData(*Symbol); + MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); MCFragment *F = new MCZeroFillFragment(Size, ByteAlignment, &SectData); SD.setFragment(F);