Avoid storing a second copy of each string in StringTableBuilder.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 22 Oct 2015 18:32:06 +0000 (18:32 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 22 Oct 2015 18:32:06 +0000 (18:32 +0000)
This was only use in the extremely uncommon case of @@@ symbols on ELF.

llvm-svn: 251039

llvm/include/llvm/MC/StringTableBuilder.h
llvm/lib/MC/ELFObjectWriter.cpp
llvm/lib/MC/StringTableBuilder.cpp

index f382477..414c3ad 100644 (file)
@@ -11,7 +11,7 @@
 #define LLVM_MC_STRINGTABLEBUILDER_H
 
 #include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/DenseMap.h"
 #include <cassert>
 
 namespace llvm {
@@ -19,15 +19,12 @@ namespace llvm {
 /// \brief Utility for building string tables with deduplicated suffixes.
 class StringTableBuilder {
   SmallString<256> StringTable;
-  StringMap<size_t> StringIndexMap;
+  DenseMap<StringRef, size_t> StringIndexMap;
 
 public:
   /// \brief Add a string to the builder. Returns a StringRef to the internal
   /// copy of s. Can only be used before the table is finalized.
-  StringRef add(StringRef s) {
-    assert(!isFinalized());
-    return StringIndexMap.insert(std::make_pair(s, 0)).first->first();
-  }
+  void add(StringRef s);
 
   enum Kind {
     ELF,
@@ -48,12 +45,7 @@ public:
 
   /// \brief Get the offest of a string in the string table. Can only be used
   /// after the table is finalized.
-  size_t getOffset(StringRef s) const {
-    assert(isFinalized());
-    auto I = StringIndexMap.find(s);
-    assert(I != StringIndexMap.end() && "String is not in table!");
-    return I->second;
-  }
+  size_t getOffset(StringRef s) const;
 
   void clear();
 
index f1acc1d..5fdfcf9 100644 (file)
@@ -33,6 +33,7 @@
 #include "llvm/Support/ELF.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/StringSaver.h"
 #include <vector>
 using namespace llvm;
 
@@ -106,6 +107,8 @@ class ELFObjectWriter : public MCObjectWriter {
     /// @name Symbol Table Data
     /// @{
 
+    BumpPtrAllocator Alloc;
+    StringSaver VersionSymSaver{Alloc};
     StringTableBuilder StrTabBuilder;
 
     /// @}
@@ -847,13 +850,15 @@ void ELFObjectWriter::computeSymbolTable(
         Buf += Name.substr(0, Pos);
         unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
         Buf += Name.substr(Pos + Skip);
-        Name = Buf;
+        Name = VersionSymSaver.save(Buf.c_str());
       }
     }
 
     // Sections have their own string table
-    if (Symbol.getType() != ELF::STT_SECTION)
-      MSD.Name = StrTabBuilder.add(Name);
+    if (Symbol.getType() != ELF::STT_SECTION) {
+      MSD.Name = Name;
+      StrTabBuilder.add(Name);
+    }
 
     if (Local)
       LocalSymbolData.push_back(MSD);
index 0f15d30..cc4fbf6 100644 (file)
@@ -8,7 +8,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/MC/StringTableBuilder.h"
-#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/COFF.h"
 #include "llvm/Support/Endian.h"
 
 using namespace llvm;
 
-static int compareBySuffix(StringMapEntry<size_t> *const *AP,
-                           StringMapEntry<size_t> *const *BP) {
-  StringRef a = (*AP)->first();
-  StringRef b = (*BP)->first();
+static int compareBySuffix(std::pair<StringRef, size_t> *const *AP,
+                           std::pair<StringRef, size_t> *const *BP) {
+  StringRef a = (*AP)->first;
+  StringRef b = (*BP)->first;
   size_t sizeA = a.size();
   size_t sizeB = b.size();
   size_t len = std::min(sizeA, sizeB);
@@ -34,9 +33,9 @@ static int compareBySuffix(StringMapEntry<size_t> *const *AP,
 }
 
 void StringTableBuilder::finalize(Kind kind) {
-  std::vector<StringMapEntry<size_t> *> Strings;
+  std::vector<std::pair<StringRef, size_t> *> Strings;
   Strings.reserve(StringIndexMap.size());
-  for (StringMapEntry<size_t> &P : StringIndexMap)
+  for (std::pair<StringRef, size_t> &P : StringIndexMap)
     Strings.push_back(&P);
 
   array_pod_sort(Strings.begin(), Strings.end(), compareBySuffix);
@@ -54,8 +53,8 @@ void StringTableBuilder::finalize(Kind kind) {
   }
 
   StringRef Previous;
-  for (StringMapEntry<size_t> *P : Strings) {
-    StringRef s = P->first();
+  for (std::pair<StringRef, size_t> *P : Strings) {
+    StringRef s = P->first;
     if (kind == WinCOFF)
       assert(s.size() > COFF::NameSize && "Short string in COFF string table!");
 
@@ -92,3 +91,15 @@ void StringTableBuilder::clear() {
   StringTable.clear();
   StringIndexMap.clear();
 }
+
+size_t StringTableBuilder::getOffset(StringRef s) const {
+  assert(isFinalized());
+  auto I = StringIndexMap.find(s);
+  assert(I != StringIndexMap.end() && "String is not in table!");
+  return I->second;
+}
+
+void StringTableBuilder::add(StringRef s) {
+  assert(!isFinalized());
+  StringIndexMap.insert(std::make_pair(s, 0));
+}