Skip to content

Commit 4bb7883

Browse files
committedJul 23, 2018
[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 llvm-svn: 337677
1 parent 52b8537 commit 4bb7883

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed
 

‎llvm/include/llvm/Support/StringSaver.h

+27-1
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,49 @@
1010
#ifndef LLVM_SUPPORT_STRINGSAVER_H
1111
#define LLVM_SUPPORT_STRINGSAVER_H
1212

13+
#include "llvm/ADT/DenseSet.h"
1314
#include "llvm/ADT/StringRef.h"
1415
#include "llvm/ADT/Twine.h"
1516
#include "llvm/Support/Allocator.h"
1617

1718
namespace llvm {
1819

19-
/// Saves strings in the inheritor's stable storage and returns a
20+
/// Saves strings in the provided stable storage and returns a
2021
/// StringRef with a stable character pointer.
2122
class StringSaver final {
2223
BumpPtrAllocator &Alloc;
2324

2425
public:
2526
StringSaver(BumpPtrAllocator &Alloc) : Alloc(Alloc) {}
27+
28+
// All returned strings are null-terminated: *save(S).end() == 0.
2629
StringRef save(const char *S) { return save(StringRef(S)); }
2730
StringRef save(StringRef S);
2831
StringRef save(const Twine &S) { return save(StringRef(S.str())); }
2932
StringRef save(const std::string &S) { return save(StringRef(S)); }
3033
};
34+
35+
/// Saves strings in the provided stable storage and returns a StringRef with a
36+
/// stable character pointer. Saving the same string yields the same StringRef.
37+
///
38+
/// Compared to StringSaver, it does more work but avoids saving the same string
39+
/// multiple times.
40+
///
41+
/// Compared to StringPool, it performs fewer allocations but doesn't support
42+
/// refcounting/deletion.
43+
class UniqueStringSaver final {
44+
StringSaver Strings;
45+
llvm::DenseSet<llvm::StringRef> Unique;
46+
47+
public:
48+
UniqueStringSaver(BumpPtrAllocator &Alloc) : Strings(Alloc) {}
49+
50+
// All returned strings are null-terminated: *save(S).end() == 0.
51+
StringRef save(const char *S) { return save(StringRef(S)); }
52+
StringRef save(StringRef S);
53+
StringRef save(const Twine &S) { return save(StringRef(S.str())); }
54+
StringRef save(const std::string &S) { return save(StringRef(S)); }
55+
};
56+
3157
}
3258
#endif

‎llvm/lib/Support/StringSaver.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,10 @@ StringRef StringSaver::save(StringRef S) {
1717
P[S.size()] = '\0';
1818
return StringRef(P, S.size());
1919
}
20+
21+
StringRef UniqueStringSaver::save(StringRef S) {
22+
auto R = Unique.insert(S);
23+
if (R.second) // cache miss, need to actually save the string
24+
*R.first = Strings.save(S); // safe replacement with equal value
25+
return *R.first;
26+
}

0 commit comments

Comments
 (0)
Please sign in to comment.