Speeds up CU vector creation.
authorRui Ueyama <ruiu@google.com>
Mon, 25 Sep 2017 04:55:27 +0000 (04:55 +0000)
committerRui Ueyama <ruiu@google.com>
Mon, 25 Sep 2017 04:55:27 +0000 (04:55 +0000)
We used to use std::set to uniquify CU vector elements, but as we know,
std::set is pretty slow. Fortunately we didn't actually have to use a
std::set here. This patch replaces it with std::vector.

With this patch, lld's -gdb-index overhead when linking a clang debug
build is now about 1 second (8.65 seconds without -gdb-index vs 9.60
seconds with -gdb-index). Since gold takes more than 6 seconds to create
a .gdb_index for the same output, our number isn't that bad.

llvm-svn: 314094

lld/ELF/SyntheticSections.cpp
lld/ELF/SyntheticSections.h

index 6a5527d..9294a99 100644 (file)
@@ -1784,8 +1784,8 @@ void GdbIndexSection::fixCuIndex() {
   }
 }
 
-std::vector<std::set<uint32_t>> GdbIndexSection::createCuVectors() {
-  std::vector<std::set<uint32_t>> Ret;
+std::vector<std::vector<uint32_t>> GdbIndexSection::createCuVectors() {
+  std::vector<std::vector<uint32_t>> Ret;
   uint32_t Idx = 0;
   uint32_t Off = 0;
 
@@ -1795,13 +1795,18 @@ std::vector<std::set<uint32_t>> GdbIndexSection::createCuVectors() {
       if (!Sym) {
         Sym = make<GdbSymbol>(GdbSymbol{Ent.Name.hash(), Off, Ret.size()});
         Off += Ent.Name.size() + 1;
-        Ret.resize(Ret.size() + 1);
+        Ret.push_back({});
       }
-      Ret[Sym->CuVectorIndex].insert((Ent.Type << 24) | Idx);
+      Ret[Sym->CuVectorIndex].push_back((Ent.Type << 24) | Idx);
     }
     Idx += Chunk.CompilationUnits.size();
   }
 
+  for (std::vector<uint32_t> &V : Ret) {
+    std::sort(V.begin(), V.end());
+    V.erase(std::unique(V.begin(), V.end()), V.end());
+  }
+
   StringPoolSize = Off;
   return Ret;
 }
@@ -1870,9 +1875,9 @@ GdbIndexSection::GdbIndexSection(std::vector<GdbIndexChunk> &&C)
   ConstantPoolOffset = SymtabOffset + GdbSymtab.size() * 8;
 
   size_t Off = 0;
-  for (std::set<uint32_t> &CuVec : CuVectors) {
+  for (ArrayRef<uint32_t> Vec : CuVectors) {
     CuVectorOffsets.push_back(Off);
-    Off += (CuVec.size() + 1) * 4;
+    Off += (Vec.size() + 1) * 4;
   }
   StringPoolOffset = ConstantPoolOffset + Off;
 }
@@ -1922,10 +1927,10 @@ void GdbIndexSection::writeTo(uint8_t *Buf) {
   }
 
   // Write the CU vectors.
-  for (std::set<uint32_t> &CuVec : CuVectors) {
-    write32le(Buf, CuVec.size());
+  for (ArrayRef<uint32_t> Vec : CuVectors) {
+    write32le(Buf, Vec.size());
     Buf += 4;
-    for (uint32_t Val : CuVec) {
+    for (uint32_t Val : Vec) {
       write32le(Buf, Val);
       Buf += 4;
     }
index 0199499..081d086 100644 (file)
@@ -27,8 +27,6 @@
 #include "llvm/ADT/MapVector.h"
 #include "llvm/MC/StringTableBuilder.h"
 
-#include <set>
-
 namespace lld {
 namespace elf {
 
@@ -536,14 +534,14 @@ public:
 
 private:
   void fixCuIndex();
-  std::vector<std::set<uint32_t>> createCuVectors();
+  std::vector<std::vector<uint32_t>> createCuVectors();
   std::vector<GdbSymbol *> createGdbSymtab();
 
   // A symbol table for this .gdb_index section.
   std::vector<GdbSymbol *> GdbSymtab;
 
   // CU vector is a part of constant pool area of section.
-  std::vector<std::set<uint32_t>> CuVectors;
+  std::vector<std::vector<uint32_t>> CuVectors;
 
   // Symbol table contents.
   llvm::DenseMap<llvm::CachedHashStringRef, GdbSymbol *> Symbols;