[lld] r314092 - Do not use StringTableBuilder to build symbol table for .gdb_index.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 24 19:29:51 PDT 2017


Author: ruiu
Date: Sun Sep 24 19:29:51 2017
New Revision: 314092

URL: http://llvm.org/viewvc/llvm-project?rev=314092&view=rev
Log:
Do not use StringTableBuilder to build symbol table for .gdb_index.

Previously, we had two levels of hash table lookup. The first hash
lookup uses CachedHashStringRefs as keys and returns offsets in string
table. Then, we did the second hash table lookup to obtain GdbSymbol
pointers. But we can directly map strings to GDbSymbols.

One test file is updated in this patch because we no longer have a '\0'
byte at the start of the string pool, which was automatically inserted
by StringTableBuilder.

This patch speeds up Clang debug build (with -gdb-index) link time by
0.3 seconds.

Modified:
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h
    lld/trunk/test/ELF/gdb-index.s

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=314092&r1=314091&r2=314092&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Sun Sep 24 19:29:51 2017
@@ -1787,19 +1787,22 @@ void GdbIndexSection::fixCuIndex() {
 std::vector<std::set<uint32_t>> GdbIndexSection::createCuVectors() {
   std::vector<std::set<uint32_t>> Ret;
   uint32_t Idx = 0;
+  uint32_t Off = 0;
 
   for (GdbIndexChunk &Chunk : Chunks) {
     for (GdbIndexChunk::NameTypeEntry &Ent : Chunk.NamesAndTypes) {
-      size_t Offset = StringPool.add(Ent.Name);
-      GdbSymbol *&Sym = SymbolMap[Offset];
+      GdbSymbol *&Sym = Symbols[Ent.Name];
       if (!Sym) {
-        Sym = make<GdbSymbol>(GdbSymbol{Ent.Name.hash(), Offset, Ret.size()});
+        Sym = make<GdbSymbol>(GdbSymbol{Ent.Name.hash(), Off, Ret.size()});
+        Off += Ent.Name.size() + 1;
         Ret.resize(Ret.size() + 1);
       }
       Ret[Sym->CuVectorIndex].insert((Ent.Type << 24) | Idx);
     }
     Idx += Chunk.CompilationUnits.size();
   }
+
+  StringPoolSize = Off;
   return Ret;
 }
 
@@ -1835,12 +1838,14 @@ static size_t getAddressAreaSize(ArrayRe
 }
 
 std::vector<GdbSymbol *> GdbIndexSection::createGdbSymtab() {
-  uint32_t Size =
-      std::max<uint32_t>(1024, NextPowerOf2(SymbolMap.size() * 4 / 3));
+  uint32_t Size = NextPowerOf2(Symbols.size() * 4 / 3);
+  if (Size < 1024)
+    Size = 1024;
+
   uint32_t Mask = Size - 1;
   std::vector<GdbSymbol *> Ret(Size);
 
-  for (auto &KV : SymbolMap) {
+  for (auto &KV : Symbols) {
     GdbSymbol *Sym = KV.second;
     uint32_t I = Sym->NameHash & Mask;
     uint32_t Step = ((Sym->NameHash * 17) & Mask) | 1;
@@ -1853,8 +1858,7 @@ std::vector<GdbSymbol *> GdbIndexSection
 }
 
 GdbIndexSection::GdbIndexSection(std::vector<GdbIndexChunk> &&C)
-    : SyntheticSection(0, SHT_PROGBITS, 1, ".gdb_index"),
-      StringPool(llvm::StringTableBuilder::ELF), Chunks(std::move(C)) {
+    : SyntheticSection(0, SHT_PROGBITS, 1, ".gdb_index"), Chunks(std::move(C)) {
   fixCuIndex();
   CuVectors = createCuVectors();
   GdbSymtab = createGdbSymtab();
@@ -1871,11 +1875,10 @@ GdbIndexSection::GdbIndexSection(std::ve
     Off += (CuVec.size() + 1) * 4;
   }
   StringPoolOffset = ConstantPoolOffset + Off;
-  StringPool.finalizeInOrder();
 }
 
 size_t GdbIndexSection::getSize() const {
-  return StringPoolOffset + StringPool.getSize();
+  return StringPoolOffset + StringPoolSize;
 }
 
 void GdbIndexSection::writeTo(uint8_t *Buf) {
@@ -1929,7 +1932,13 @@ void GdbIndexSection::writeTo(uint8_t *B
   }
 
   // Write the string pool.
-  StringPool.write(Buf);
+  for (auto &KV : Symbols) {
+    CachedHashStringRef S = KV.first;
+    GdbSymbol *Sym = KV.second;
+    size_t Off = Sym->NameOffset;
+    memcpy(Buf + Off, S.val().data(), S.size());
+    Buf[Off + S.size() + 1] = '\0';
+  }
 }
 
 bool GdbIndexSection::empty() const { return !Out::DebugInfo; }

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=314092&r1=314091&r2=314092&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Sun Sep 24 19:29:51 2017
@@ -542,15 +542,11 @@ private:
   // A symbol table for this .gdb_index section.
   std::vector<GdbSymbol *> GdbSymtab;
 
-  // Symbol table entries are uniquified by their offsets, so
-  // we need a map from offsets to symbols.
-  llvm::DenseMap<size_t, GdbSymbol *> SymbolMap;
-
   // CU vector is a part of constant pool area of section.
   std::vector<std::set<uint32_t>> CuVectors;
 
-  // String pool is also a part of constant pool, it follows CU vectors.
-  llvm::StringTableBuilder StringPool;
+  // Symbol table contents.
+  llvm::DenseMap<llvm::CachedHashStringRef, GdbSymbol *> Symbols;
 
   // Each chunk contains information gathered from a debug sections of single
   // object and used to build different areas of gdb index.
@@ -561,6 +557,7 @@ private:
   uint32_t SymtabOffset;
   uint32_t ConstantPoolOffset;
   uint32_t StringPoolOffset;
+  uint32_t StringPoolSize;
 
   std::vector<size_t> CuVectorOffsets;
 };

Modified: lld/trunk/test/ELF/gdb-index.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gdb-index.s?rev=314092&r1=314091&r2=314092&view=diff
==============================================================================
--- lld/trunk/test/ELF/gdb-index.s (original)
+++ lld/trunk/test/ELF/gdb-index.s Sun Sep 24 19:29:51 2017
@@ -24,11 +24,11 @@
 # CHECK-NEXT:    Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0
 # CHECK-NEXT:    Low/High address = [0x201004, 0x201006) (Size: 0x2), CU id = 1
 # CHECK:       Symbol table offset = 0x60, size = 1024, filled slots:
-# CHECK-NEXT:    489: Name offset = 0x1d, CU vector offset = 0x0
+# CHECK-NEXT:    489: Name offset = 0x1c, CU vector offset = 0x0
 # CHECK-NEXT:      String name: main, CU vector index: 0
-# CHECK-NEXT:    754: Name offset = 0x22, CU vector offset = 0x8
+# CHECK-NEXT:    754: Name offset = 0x21, CU vector offset = 0x8
 # CHECK-NEXT:      String name: int, CU vector index: 1
-# CHECK-NEXT:    956: Name offset = 0x26, CU vector offset = 0x14
+# CHECK-NEXT:    956: Name offset = 0x25, CU vector offset = 0x14
 # CHECK-NEXT:      String name: main2, CU vector index: 2
 # CHECK:       Constant pool offset = 0x2060, has 3 CU vectors:
 # CHECK-NEXT:    0(0x0): 0x30000000




More information about the llvm-commits mailing list