From 958b01aa691e031c674c974bf6aa5af3dc9d5be2 Mon Sep 17 00:00:00 2001 From: George Rimar Date: Mon, 15 May 2017 11:45:28 +0000 Subject: [DWARF] - Speedup handling of relocations in DWARFContextInMemory. I am working on a speedup of building .gdb_index in LLD and noticed that relocations that are proccessed in DWARFContextInMemory often uses the same symbol in a row. This patch introduces caching to reduce the relocations proccessing time. For benchmark, I took debug LLC binary objects configured with -ggnu-pubnames and linked it using LLD. Link time without --gdb-index is about 4,45s. Link time with --gdb-index: a) Without patch: 19,16s b) With patch: 15,52s That means time spent on --gdb-index in this configuration is 19,16s - 4,45s = 14,71s (without patch) vs 15,52s - 4,45s = 11,07s (with patch). Differential revision: https://reviews.llvm.org/D31136 llvm-svn: 303051 --- llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'llvm/lib/DebugInfo/DWARF/DWARFContext.cpp') diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index 246899ac12b..1b5dd3f220a 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -905,16 +905,23 @@ static Error createError(const Twine &Reason, llvm::Error E) { /// Returns the address of symbol relocation used against. Used for futher /// relocations computation. Symbol's section load address is taken in account if /// LoadedObjectInfo interface is provided. -static Expected getSymbolAddress(const object::ObjectFile &Obj, - const RelocationRef &Reloc, - const LoadedObjectInfo *L) { +static Expected +getSymbolAddress(const object::ObjectFile &Obj, const RelocationRef &Reloc, + const LoadedObjectInfo *L, + std::map &Cache) { uint64_t Ret = 0; object::section_iterator RSec = Obj.section_end(); object::symbol_iterator Sym = Reloc.getSymbol(); + std::map::iterator CacheIt = Cache.end(); // First calculate the address of the symbol or section as it appears // in the object file if (Sym != Obj.symbol_end()) { + bool New; + std::tie(CacheIt, New) = Cache.insert({*Sym, 0}); + if (!New) + return CacheIt->second; + Expected SymAddrOrErr = Sym->getAddress(); if (!SymAddrOrErr) return createError("error: failed to compute symbol address: ", @@ -943,6 +950,10 @@ static Expected getSymbolAddress(const object::ObjectFile &Obj, if (L && RSec != Obj.section_end()) if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec)) Ret += SectionLoadAddress - RSec->getAddress(); + + if (CacheIt != Cache.end()) + CacheIt->second = Ret; + return Ret; } @@ -1075,6 +1086,7 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, continue; } + std::map AddrCache; if (Section.relocation_begin() != Section.relocation_end()) { uint64_t SectionSize = RelocatedSection->getSize(); for (const RelocationRef &Reloc : Section.relocations()) { @@ -1083,7 +1095,8 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, if (isRelocScattered(Obj, Reloc)) continue; - Expected SymAddrOrErr = getSymbolAddress(Obj, Reloc, L); + Expected SymAddrOrErr = + getSymbolAddress(Obj, Reloc, L, AddrCache); if (!SymAddrOrErr) { errs() << toString(SymAddrOrErr.takeError()) << '\n'; continue; -- cgit v1.2.3