[llvm] [TableGen] Use a more efficient memory buffer for output (PR #123353)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 17 07:09:50 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-tablegen
Author: Jay Foad (jayfoad)
<details>
<summary>Changes</summary>
TableGen writes all output to an in-memory buffer in case the
-write-if-change option is being used. Using raw_string_ostream for this
is inefficient because all the data has to be copied every time the
underlying std::string is resized. Fix this by writing to a custom
raw_ostream which stores the buffered data as the concatenation of a
vector of strings of increasing capacity. Each string in the vector is
never resized beyond its initial capacity to avoid unnecessary copying.
---
Full diff: https://github.com/llvm/llvm-project/pull/123353.diff
1 Files Affected:
- (modified) llvm/lib/TableGen/Main.cpp (+49-4)
``````````diff
diff --git a/llvm/lib/TableGen/Main.cpp b/llvm/lib/TableGen/Main.cpp
index 55a99cbfc58acd..88bca04ec19a41 100644
--- a/llvm/lib/TableGen/Main.cpp
+++ b/llvm/lib/TableGen/Main.cpp
@@ -37,6 +37,52 @@
#include <utility>
using namespace llvm;
+class stringvec_ostream : public raw_ostream {
+ std::vector<std::string> V;
+
+ size_t Pos = 0;
+ uint64_t current_pos() const override { return Pos; }
+
+ void write_impl(const char *Ptr, size_t Size) override {
+ Pos += Size;
+
+ size_t ThisSize = std::min(Size, V.back().capacity() - V.back().size());
+ V.back().append(Ptr, ThisSize);
+ Ptr += ThisSize;
+ Size -= ThisSize;
+
+ if (Size != 0) {
+ size_t NewCapacity = std::max(Size, V.back().capacity() * 2);
+ V.emplace_back();
+ V.back().reserve(NewCapacity);
+ V.back().append(Ptr, Size);
+ }
+ }
+
+public:
+ stringvec_ostream() : V(1) { SetUnbuffered(); }
+
+ friend raw_ostream &operator<<(raw_ostream &OS,
+ const stringvec_ostream &RHS) {
+ for (const std::string &S : RHS.V)
+ OS << S;
+ return OS;
+ }
+
+ bool operator==(StringRef RHS) {
+ if (Pos != RHS.size())
+ return false;
+
+ size_t Offset = 0;
+ for (const std::string &S : V) {
+ if (S != RHS.slice(Offset, Offset + S.size()))
+ return false;
+ Offset += S.size();
+ }
+ return true;
+ }
+};
+
static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"),
cl::init("-"));
@@ -130,8 +176,7 @@ int llvm::TableGenMain(const char *argv0,
// Write output to memory.
Timer.startBackendTimer("Backend overall");
- std::string OutString;
- raw_string_ostream Out(OutString);
+ stringvec_ostream Out;
unsigned status = 0;
// ApplyCallback will return true if it did not apply any callback. In that
// case, attempt to apply the MainFn.
@@ -158,7 +203,7 @@ int llvm::TableGenMain(const char *argv0,
// aren't any.
if (auto ExistingOrErr =
MemoryBuffer::getFile(OutputFilename, /*IsText=*/true))
- if (std::move(ExistingOrErr.get())->getBuffer() == OutString)
+ if (Out == std::move(ExistingOrErr.get())->getBuffer())
WriteFile = false;
}
if (WriteFile) {
@@ -167,7 +212,7 @@ int llvm::TableGenMain(const char *argv0,
if (EC)
return reportError(argv0, "error opening " + OutputFilename + ": " +
EC.message() + "\n");
- OutFile.os() << OutString;
+ OutFile.os() << Out;
if (ErrorsPrinted == 0)
OutFile.keep();
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/123353
More information about the llvm-commits
mailing list