Index: ELF/InputSection.h =================================================================== --- ELF/InputSection.h +++ ELF/InputSection.h @@ -72,6 +72,7 @@ typedef typename llvm::object::ELFFile::Elf_Shdr Elf_Shdr; public: + std::unique_ptr Offsets; MergeInputSection(ObjectFile *F, const Elf_Shdr *Header); static bool classof(const InputSectionBase *S); uintX_t getOffset(uintX_t Offset) const; Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -128,7 +128,6 @@ return S->SectionKind == Base::Merge; } -// FIXME: Optimize this by keeping an offset for each element. template typename MergeInputSection::uintX_t MergeInputSection::getOffset(uintX_t Offset) const { @@ -136,8 +135,9 @@ uintX_t EntSize = this->Header->sh_entsize; if (Offset + EntSize > Data.size()) error("Entry is past the end of the section"); - Data = Data.slice(Offset, EntSize); - return static_cast *>(this->OutSec)->getOffset(Data); + assert(Offset % EntSize == 0); + uintX_t Index = Offset / EntSize; + return Offsets.get()[Index]; } namespace lld { Index: ELF/OutputSections.h =================================================================== --- ELF/OutputSections.h +++ ELF/OutputSections.h @@ -214,8 +214,6 @@ void addSection(MergeInputSection *S); void writeTo(uint8_t *Buf) override; - unsigned getOffset(ArrayRef Val); - private: // This map is used to find if we already have an entry for a given value and, // if so, at what offset it is. Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -535,8 +535,10 @@ uintX_t EntSize = S->getSectionHdr()->sh_entsize; if (Data.size() % EntSize) error("SHF_MERGE section size must be a multiple of sh_entsize"); - for (unsigned I = 0, N = Data.size(); I != N; I += EntSize) { + S->Offsets.reset(new uintX_t[Data.size() / EntSize]); + for (unsigned I = 0, N = Data.size(), J = 0; I != N; I += EntSize, ++J) { auto P = Offsets.insert(std::make_pair(Data.slice(I, EntSize), Off)); + S->Offsets.get()[J] = P.first->second; if (P.second) Off += EntSize; } @@ -544,11 +546,6 @@ } template -unsigned MergeOutputSection::getOffset(ArrayRef Val) { - return Offsets.find(Val)->second; -} - -template StringTableSection::StringTableSection(bool Dynamic) : OutputSectionBase(Dynamic ? ".dynstr" : ".strtab", llvm::ELF::SHT_STRTAB,