summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2017-09-25 02:29:51 +0000
committerRui Ueyama <ruiu@google.com>2017-09-25 02:29:51 +0000
commitbbc477c9b6cfebc2d410db14f8ee5a096863ec9d (patch)
tree7ce7be33c6be0da9fd6d43985bca836848a13e0e
parent22125d8c84ec5111828a8d3183bdb4ede5dbc58e (diff)
downloadbcm5719-llvm-bbc477c9b6cfebc2d410db14f8ee5a096863ec9d.tar.gz
bcm5719-llvm-bbc477c9b6cfebc2d410db14f8ee5a096863ec9d.zip
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. llvm-svn: 314092
-rw-r--r--lld/ELF/SyntheticSections.cpp31
-rw-r--r--lld/ELF/SyntheticSections.h9
-rw-r--r--lld/test/ELF/gdb-index.s6
3 files changed, 26 insertions, 20 deletions
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 8d4e09e8b86..b006c0bcb85 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -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(ArrayRef<GdbIndexChunk> Arr) {
}
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::createGdbSymtab() {
}
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::vector<GdbIndexChunk> &&C)
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 *Buf) {
}
// 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; }
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 200ae95a8de..01994991894 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -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;
};
diff --git a/lld/test/ELF/gdb-index.s b/lld/test/ELF/gdb-index.s
index f9ea3928c34..5ea9fc4a08f 100644
--- a/lld/test/ELF/gdb-index.s
+++ b/lld/test/ELF/gdb-index.s
@@ -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
OpenPOWER on IntegriCloud