[llvm] r337677 - [Support] Add a UniqueStringSaver: like StringSaver, but deduplicating.

Sam McCall via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 23 03:44:41 PDT 2018


Author: sammccall
Date: Mon Jul 23 03:44:40 2018
New Revision: 337677

URL: http://llvm.org/viewvc/llvm-project?rev=337677&view=rev
Log:
[Support] Add a UniqueStringSaver: like StringSaver, but deduplicating.

Summary: Clarify contract of StringSaver (it null-terminates, callers rely on it).

Reviewers: hokein

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D49596

Modified:
    llvm/trunk/include/llvm/Support/StringSaver.h
    llvm/trunk/lib/Support/StringSaver.cpp

Modified: llvm/trunk/include/llvm/Support/StringSaver.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StringSaver.h?rev=337677&r1=337676&r2=337677&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/StringSaver.h (original)
+++ llvm/trunk/include/llvm/Support/StringSaver.h Mon Jul 23 03:44:40 2018
@@ -10,23 +10,49 @@
 #ifndef LLVM_SUPPORT_STRINGSAVER_H
 #define LLVM_SUPPORT_STRINGSAVER_H
 
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/Allocator.h"
 
 namespace llvm {
 
-/// Saves strings in the inheritor's stable storage and returns a
+/// Saves strings in the provided stable storage and returns a
 /// StringRef with a stable character pointer.
 class StringSaver final {
   BumpPtrAllocator &Alloc;
 
 public:
   StringSaver(BumpPtrAllocator &Alloc) : Alloc(Alloc) {}
+
+  // All returned strings are null-terminated: *save(S).end() == 0.
   StringRef save(const char *S) { return save(StringRef(S)); }
   StringRef save(StringRef S);
   StringRef save(const Twine &S) { return save(StringRef(S.str())); }
   StringRef save(const std::string &S) { return save(StringRef(S)); }
 };
+
+/// Saves strings in the provided stable storage and returns a StringRef with a
+/// stable character pointer. Saving the same string yields the same StringRef.
+///
+/// Compared to StringSaver, it does more work but avoids saving the same string
+/// multiple times.
+///
+/// Compared to StringPool, it performs fewer allocations but doesn't support
+/// refcounting/deletion.
+class UniqueStringSaver final {
+  StringSaver Strings;
+  llvm::DenseSet<llvm::StringRef> Unique;
+
+public:
+  UniqueStringSaver(BumpPtrAllocator &Alloc) : Strings(Alloc) {}
+
+  // All returned strings are null-terminated: *save(S).end() == 0.
+  StringRef save(const char *S) { return save(StringRef(S)); }
+  StringRef save(StringRef S);
+  StringRef save(const Twine &S) { return save(StringRef(S.str())); }
+  StringRef save(const std::string &S) { return save(StringRef(S)); }
+};
+
 }
 #endif

Modified: llvm/trunk/lib/Support/StringSaver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StringSaver.cpp?rev=337677&r1=337676&r2=337677&view=diff
==============================================================================
--- llvm/trunk/lib/Support/StringSaver.cpp (original)
+++ llvm/trunk/lib/Support/StringSaver.cpp Mon Jul 23 03:44:40 2018
@@ -17,3 +17,10 @@ StringRef StringSaver::save(StringRef S)
   P[S.size()] = '\0';
   return StringRef(P, S.size());
 }
+
+StringRef UniqueStringSaver::save(StringRef S) {
+  auto R = Unique.insert(S);
+  if (R.second)                 // cache miss, need to actually save the string
+    *R.first = Strings.save(S); // safe replacement with equal value
+  return *R.first;
+}




More information about the llvm-commits mailing list