Skip to content

Commit efcb07b

Browse files
committed
[llvm][Support] Avoid intermediate heap allocations in StringSaver
The `Twine::str()` function currently always allocates heap memory via `std::string`. However, some instances of `Twine` don't need an intermediate buffer at all, and the rest can attempt to print into a stack buffer first. This is intentionally not making use of `Twine::isSingleStringLiteral()` from D157010 to skip saving the string in the bump-pointer allocator, since the `StringSaver` documentation suggests that MUST happen for every given string. Reviewed By: benlangmuir Differential Revision: https://reviews.llvm.org/D157015
1 parent 43dfe0f commit efcb07b

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

llvm/include/llvm/Support/StringSaver.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class StringSaver final {
2929
// All returned strings are null-terminated: *save(S).end() == 0.
3030
StringRef save(const char *S) { return save(StringRef(S)); }
3131
StringRef save(StringRef S);
32-
StringRef save(const Twine &S) { return save(StringRef(S.str())); }
32+
StringRef save(const Twine &S);
3333
StringRef save(const std::string &S) { return save(StringRef(S)); }
3434
};
3535

@@ -51,7 +51,7 @@ class UniqueStringSaver final {
5151
// All returned strings are null-terminated: *save(S).end() == 0.
5252
StringRef save(const char *S) { return save(StringRef(S)); }
5353
StringRef save(StringRef S);
54-
StringRef save(const Twine &S) { return save(StringRef(S.str())); }
54+
StringRef save(const Twine &S);
5555
StringRef save(const std::string &S) { return save(StringRef(S)); }
5656
};
5757

llvm/lib/Support/StringSaver.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#include "llvm/Support/StringSaver.h"
1010

11+
#include "llvm/ADT/SmallString.h"
12+
1113
using namespace llvm;
1214

1315
StringRef StringSaver::save(StringRef S) {
@@ -18,9 +20,19 @@ StringRef StringSaver::save(StringRef S) {
1820
return StringRef(P, S.size());
1921
}
2022

23+
StringRef StringSaver::save(const Twine &S) {
24+
SmallString<128> Storage;
25+
return save(S.toStringRef(Storage));
26+
}
27+
2128
StringRef UniqueStringSaver::save(StringRef S) {
2229
auto R = Unique.insert(S);
2330
if (R.second) // cache miss, need to actually save the string
2431
*R.first = Strings.save(S); // safe replacement with equal value
2532
return *R.first;
2633
}
34+
35+
StringRef UniqueStringSaver::save(const Twine &S) {
36+
SmallString<128> Storage;
37+
return save(S.toStringRef(Storage));
38+
}

0 commit comments

Comments
 (0)