[llvm] [RFC][Support] Introduce buffered_svector_ostream (PR #97704)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 4 02:52:38 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-support

Author: Alexis Engelke (aengelke)

<details>
<summary>Changes</summary>

Draft PR for comments/feedback; on the top off #<!-- -->97703. I also did no systematic replacement, merely a find-and-replace of some parts that could be somehow performance sensitive.

---

Currently, raw_svector_ostream guarantees that the underlying vector is kept in sync. This was added in 3d1173ba1a53cab08ed2c33e47dd617df77a914b, citing performance improvements. However, this causes all writes to a raw_svector_ostream to go through the slow path of raw_ostream. The sync guarantee is rarely needed, however.

With inlining some methods into raw_ostream, using the SmallVector capacity as buffer can be nearly as fast as writing directly to the small vector (growing is slower and currently there's an out-of-line destructor call). This actually improves performance ([c-t-t of buffered_svector commits (excluding inlining done by #<!-- -->97703)](http://llvm-compile-time-tracker.com/compare.php?from=23d0e1a2c1b9cd6b48866ca9c18f8ed09423502e&to=a1dfa84dc357f4fe9c6bc174d84966da25188590&stat=instructions%3Au)).

Now, I'm unsure how to proceed:

- Add a new class `buffered_svector_ostream`, which is more efficient than raw_svector_ostream because it gives fewer guarantees, and do a mass refactoring (lot of churn)
- Change semantics of `raw_svector_ostream`, causing less churn in-tree, but is likely to cause some bugs in the meantime (and will probably break some downstream users)
- Something else?

Feedback/comments appreciated. :)

---

Patch is 54.05 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/97704.diff


45 Files Affected:

- (modified) llvm/include/llvm/Support/FormatCommon.h (+4-2) 
- (modified) llvm/include/llvm/Support/FormatVariadic.h (+1-2) 
- (modified) llvm/include/llvm/Support/YAMLTraits.h (+1-1) 
- (modified) llvm/include/llvm/Support/raw_ostream.h (+104-18) 
- (modified) llvm/include/llvm/TableGen/StringToOffsetTable.h (+1-1) 
- (modified) llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp (+3-6) 
- (modified) llvm/lib/Analysis/TargetLibraryInfo.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/AsmPrinter/AIXException.cpp (+2-1) 
- (modified) llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (+4-4) 
- (modified) llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp (+2-2) 
- (modified) llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h (+2-2) 
- (modified) llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (+2-2) 
- (modified) llvm/lib/CodeGen/CFGuardLongjmp.cpp (+2-1) 
- (modified) llvm/lib/CodeGen/MachineBasicBlock.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/MachineFunction.cpp (+2-2) 
- (modified) llvm/lib/CodeGen/MachineFunctionPass.cpp (+2-2) 
- (modified) llvm/lib/CodeGen/ModuloSchedule.cpp (+1-1) 
- (modified) llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (+22-13) 
- (modified) llvm/lib/DebugInfo/BTF/BTFParser.cpp (+2-2) 
- (modified) llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp (+6-5) 
- (modified) llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp (+1-1) 
- (modified) llvm/lib/ExecutionEngine/ExecutionEngine.cpp (+3-3) 
- (modified) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp (+11-8) 
- (modified) llvm/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp (+2-2) 
- (modified) llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp (+1-1) 
- (modified) llvm/lib/FileCheck/FileCheck.cpp (+2-2) 
- (modified) llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp (+3-3) 
- (modified) llvm/lib/IR/AutoUpgrade.cpp (+1-1) 
- (modified) llvm/lib/IR/Mangler.cpp (+2-2) 
- (modified) llvm/lib/IR/VFABIDemangler.cpp (+5-3) 
- (modified) llvm/lib/MC/ELFObjectWriter.cpp (+4-2) 
- (modified) llvm/lib/MC/MCAssembler.cpp (+17-12) 
- (modified) llvm/lib/MC/MCContext.cpp (+2-2) 
- (modified) llvm/lib/MC/MCStreamer.cpp (+6-6) 
- (modified) llvm/lib/MC/MCWinCOFFStreamer.cpp (+2-2) 
- (modified) llvm/lib/MC/MachObjectWriter.cpp (+1-1) 
- (modified) llvm/lib/MC/WinCOFFObjectWriter.cpp (+6-4) 
- (modified) llvm/lib/Object/IRSymtab.cpp (+1-1) 
- (modified) llvm/lib/ObjectYAML/yaml2obj.cpp (+1-1) 
- (modified) llvm/lib/Support/ErrorHandling.cpp (+1-1) 
- (modified) llvm/lib/Support/PrettyStackTrace.cpp (+1-1) 
- (modified) llvm/lib/Support/Twine.cpp (+1-1) 
- (modified) llvm/lib/Support/raw_ostream.cpp (+51-42) 
- (modified) llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp (+1-1) 
- (modified) llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFTargetStreamer.cpp (+1-1) 


``````````diff
diff --git a/llvm/include/llvm/Support/FormatCommon.h b/llvm/include/llvm/Support/FormatCommon.h
index 326e00936aa7c..848a98fa56f46 100644
--- a/llvm/include/llvm/Support/FormatCommon.h
+++ b/llvm/include/llvm/Support/FormatCommon.h
@@ -37,9 +37,11 @@ struct FmtAlign {
       return;
     }
     SmallString<64> Item;
-    raw_svector_ostream Stream(Item);
+    {
+      buffered_svector_ostream Stream(Item);
+      Adapter.format(Stream, Options);
+    }
 
-    Adapter.format(Stream, Options);
     if (Amount <= Item.size()) {
       S << Item;
       return;
diff --git a/llvm/include/llvm/Support/FormatVariadic.h b/llvm/include/llvm/Support/FormatVariadic.h
index 595f2cf559a42..29e0a09e22e36 100644
--- a/llvm/include/llvm/Support/FormatVariadic.h
+++ b/llvm/include/llvm/Support/FormatVariadic.h
@@ -115,8 +115,7 @@ class formatv_object_base {
 
   template <unsigned N> SmallString<N> sstr() const {
     SmallString<N> Result;
-    raw_svector_ostream Stream(Result);
-    Stream << *this;
+    buffered_svector_ostream(Result) << *this;
     return Result;
   }
 
diff --git a/llvm/include/llvm/Support/YAMLTraits.h b/llvm/include/llvm/Support/YAMLTraits.h
index 1d04783753d5c..dc33afe3da0b5 100644
--- a/llvm/include/llvm/Support/YAMLTraits.h
+++ b/llvm/include/llvm/Support/YAMLTraits.h
@@ -1004,7 +1004,7 @@ std::enable_if_t<has_ScalarTraits<T>::value, void> yamlize(IO &io, T &Val, bool,
                                                            EmptyContext &Ctx) {
   if ( io.outputting() ) {
     SmallString<128> Storage;
-    raw_svector_ostream Buffer(Storage);
+    buffered_svector_ostream Buffer(Storage);
     ScalarTraits<T>::output(Val, io.getContext(), Buffer);
     StringRef Str = Buffer.str();
     io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
index df9ee2e5a7858..828d893d2a134 100644
--- a/llvm/include/llvm/Support/raw_ostream.h
+++ b/llvm/include/llvm/Support/raw_ostream.h
@@ -78,7 +78,8 @@ class raw_ostream {
   ///
   /// If a subclass installs an external buffer using SetBuffer then it can wait
   /// for a \see write_impl() call to handle the data which has been put into
-  /// this buffer.
+  /// this buffer. If a subclass uses an external buffer, it is not possible
+  /// to switch to an internal buffer or an unbuffered mode.
   char *OutBufStart, *OutBufEnd, *OutBufCur;
   bool ColorEnabled = false;
 
@@ -165,11 +166,13 @@ class raw_ostream {
 
   /// Set the stream to be buffered, using the specified buffer size.
   void SetBufferSize(size_t Size) {
+    assert(BufferMode != BufferKind::ExternalBuffer);
     flush();
     SetBufferAndMode(new char[Size], Size, BufferKind::InternalBuffer);
   }
 
   size_t GetBufferSize() const {
+    assert(BufferMode != BufferKind::ExternalBuffer);
     // If we're supposed to be buffered but haven't actually gotten around
     // to allocating the buffer yet, return the value that would be used.
     if (BufferMode != BufferKind::Unbuffered && OutBufStart == nullptr)
@@ -183,6 +186,7 @@ class raw_ostream {
   /// after every write. This routine will also flush the buffer immediately
   /// when the stream is being set to unbuffered.
   void SetUnbuffered() {
+    assert(BufferMode != BufferKind::ExternalBuffer);
     flush();
     SetBufferAndMode(nullptr, 0, BufferKind::Unbuffered);
   }
@@ -222,18 +226,7 @@ class raw_ostream {
   }
 
   raw_ostream &operator<<(StringRef Str) {
-    // Inline fast path, particularly for strings with a known length.
-    size_t Size = Str.size();
-
-    // Make sure we can use the fast path.
-    if (Size > (size_t)(OutBufEnd - OutBufCur))
-      return write(Str.data(), Size);
-
-    if (Size) {
-      memcpy(OutBufCur, Str.data(), Size);
-      OutBufCur += Size;
-    }
-    return *this;
+    return write(Str.data(), Str.size());
   }
 
 #if defined(__cpp_char8_t)
@@ -258,7 +251,6 @@ class raw_ostream {
   }
 
   raw_ostream &operator<<(const std::string &Str) {
-    // Avoid the fast path, it would only increase code size for a marginal win.
     return write(Str.data(), Str.length());
   }
 
@@ -300,8 +292,25 @@ class raw_ostream {
   /// satisfy llvm::isPrint into an escape sequence.
   raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false);
 
-  raw_ostream &write(unsigned char C);
-  raw_ostream &write(const char *Ptr, size_t Size);
+  raw_ostream &write(unsigned char C) {
+    if (OutBufCur >= OutBufEnd)
+      writeSlow(C);
+    else
+      *OutBufCur++ = C;
+    return *this;
+  }
+
+  raw_ostream &write(const char *Ptr, size_t Size) {
+    // Inline fast path
+    if (LLVM_UNLIKELY(size_t(OutBufEnd - OutBufCur) < Size)) {
+      writeSlow(Ptr, Size);
+      return *this;
+    }
+    if (Size)
+      memcpy(OutBufCur, Ptr, Size);
+    OutBufCur += Size;
+    return *this;
+  }
 
   // Formatted output, see the format() function in Support/Format.h.
   raw_ostream &operator<<(const format_object_base &Fmt);
@@ -385,6 +394,8 @@ class raw_ostream {
   /// use only by subclasses which can arrange for the output to go directly
   /// into the desired output buffer, instead of being copied on each flush.
   void SetBuffer(char *BufferStart, size_t Size) {
+    assert((!OutBufStart && BufferMode == BufferKind::InternalBuffer) ||
+           BufferMode == BufferKind::ExternalBuffer);
     SetBufferAndMode(BufferStart, Size, BufferKind::ExternalBuffer);
   }
 
@@ -400,11 +411,36 @@ class raw_ostream {
   //===--------------------------------------------------------------------===//
 private:
   /// Install the given buffer and mode.
-  void SetBufferAndMode(char *BufferStart, size_t Size, BufferKind Mode);
+  void SetBufferAndMode(char *BufferStart, size_t Size, BufferKind Mode) {
+    assert(((Mode == BufferKind::Unbuffered && !BufferStart && Size == 0) ||
+            (Mode != BufferKind::Unbuffered && BufferStart && Size != 0)) &&
+           "stream must be unbuffered or have at least one byte");
+    // Make sure the current buffer is free of content (we can't flush here; the
+    // child buffer management logic will be in write_impl).
+    assert(GetNumBytesInBuffer() == 0 && "Current buffer is non-empty!");
+
+    if (BufferMode == BufferKind::InternalBuffer)
+      delete[] OutBufStart;
+    OutBufStart = BufferStart;
+    OutBufEnd = OutBufStart + Size;
+    OutBufCur = OutBufStart;
+    BufferMode = Mode;
+
+    assert(OutBufStart <= OutBufEnd && "Invalid size!");
+  }
 
   /// Flush the current buffer, which is known to be non-empty. This outputs the
   /// currently buffered data and resets the buffer to empty.
-  void flush_nonempty();
+  void flush_nonempty() {
+    assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
+    size_t Length = OutBufCur - OutBufStart;
+    OutBufCur = OutBufStart;
+    write_impl(OutBufStart, Length);
+  }
+
+  /// Slow path for writing when buffer is too small.
+  void writeSlow(unsigned char C);
+  void writeSlow(const char *Ptr, size_t Size);
 
   /// Copy data into the buffer. Size must not be greater than the number of
   /// unused bytes in the buffer.
@@ -727,6 +763,56 @@ class raw_svector_ostream : public raw_pwrite_stream {
   static bool classof(const raw_ostream *OS);
 };
 
+/// A raw_ostream that writes efficiently to a SmallVector or SmallString.
+/// This class is a similar to raw_svector_ostream, except that the underlying
+/// size of the underlying buffer is *not* correct. Instead, the entire
+/// capacity of the SmallVector will be used as buffer, so that the fastp path
+/// of raw_ostream::write is hit most of the time. The size of the SmallVector
+/// will be corrected on destruction.
+class buffered_svector_ostream : public raw_pwrite_stream {
+  SmallVectorImpl<char> &OS;
+  size_t FlushedSize;
+
+  /// See raw_ostream::write_impl.
+  void write_impl(const char *Ptr, size_t Size) override final;
+
+  void pwrite_impl(const char *Ptr, size_t Size,
+                   uint64_t Offset) override final;
+
+  /// Return the current position within the stream.
+  uint64_t current_pos() const override final { return FlushedSize; }
+
+  void updateBuffer() {
+    assert(FlushedSize < OS.size() && "must have non-empty buffer space");
+    SetBuffer(OS.data() + FlushedSize, OS.size() - FlushedSize);
+  }
+
+public:
+  /// Construct a new raw_svector_ostream.
+  ///
+  /// \param O The vector to write to; this should generally have at least 128
+  /// bytes free to avoid any extraneous memory overhead.
+  explicit buffered_svector_ostream(SmallVectorImpl<char> &O)
+      : OS(O), FlushedSize(OS.size()) {
+    if (OS.size() == OS.capacity())
+      OS.reserve(OS.size() < 128 ? 128 : OS.size() + 1);
+    OS.resize_for_overwrite(OS.capacity());
+    updateBuffer();
+  }
+
+  ~buffered_svector_ostream() override { OS.truncate(tell()); }
+
+  /// Return a StringRef for the vector contents.
+  StringRef str() const { return StringRef(OS.data(), tell()); }
+
+  void truncate(size_t Size) {
+    flush();
+    assert(Size <= FlushedSize && "truncate larger than vector size");
+    FlushedSize = Size;
+    updateBuffer();
+  }
+};
+
 /// A raw_ostream that discards all output.
 class raw_null_ostream : public raw_pwrite_stream {
   /// See raw_ostream::write_impl.
diff --git a/llvm/include/llvm/TableGen/StringToOffsetTable.h b/llvm/include/llvm/TableGen/StringToOffsetTable.h
index 66bcc81c94b59..87a93b00182b9 100644
--- a/llvm/include/llvm/TableGen/StringToOffsetTable.h
+++ b/llvm/include/llvm/TableGen/StringToOffsetTable.h
@@ -44,7 +44,7 @@ class StringToOffsetTable {
   void EmitString(raw_ostream &O) {
     // Escape the string.
     SmallString<256> Str;
-    raw_svector_ostream(Str).write_escaped(AggregateString);
+    buffered_svector_ostream(Str).write_escaped(AggregateString);
     AggregateString = std::string(Str);
 
     O << "    \"";
diff --git a/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp b/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
index 9f6e53ba15b6a..2670ab1c87e1f 100644
--- a/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
+++ b/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
@@ -568,12 +568,9 @@ BlockFrequency
 BlockFrequencyInfoImplBase::getBlockFreq(const BlockNode &Node) const {
   if (!Node.isValid()) {
 #ifndef NDEBUG
-    if (CheckBFIUnknownBlockQueries) {
-      SmallString<256> Msg;
-      raw_svector_ostream OS(Msg);
-      OS << "*** Detected BFI query for unknown block " << getBlockName(Node);
-      report_fatal_error(OS.str());
-    }
+    if (CheckBFIUnknownBlockQueries)
+      report_fatal_error(Twine("*** Detected BFI query for unknown block ") +
+                         getBlockName(Node));
 #endif
     return BlockFrequency(0);
   }
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index bf53f562ec419..89d6e2e8085de 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -51,7 +51,7 @@ StringLiteral const TargetLibraryInfoImpl::StandardNames[LibFunc::NumLibFuncs] =
 std::string VecDesc::getVectorFunctionABIVariantString() const {
   assert(!VectorFnName.empty() && "Vector function name must not be empty.");
   SmallString<256> Buffer;
-  llvm::raw_svector_ostream Out(Buffer);
+  buffered_svector_ostream Out(Buffer);
   Out << VABIPrefix << "_" << ScalarFnName << "(" << VectorFnName << ")";
   return std::string(Out.str());
 }
diff --git a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
index 5d7c97adcacad..3fb82c1bebac3 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
@@ -45,7 +45,8 @@ void AIXException::emitExceptionInfoTable(const MCSymbol *LSDA,
     // Table csect. This helps the linker to garbage-collect EH info of unused
     // functions.
     SmallString<128> NameStr = EHInfo->getName();
-    raw_svector_ostream(NameStr) << '.' << Asm->MF->getFunction().getName();
+    NameStr += ".";
+    NameStr += Asm->MF->getFunction().getName();
     EHInfo = Asm->OutContext.getXCOFFSection(NameStr, EHInfo->getKind(),
                                              EHInfo->getCsectProp());
   }
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 1391893e55a52..ae0f5a69f0b39 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1111,7 +1111,7 @@ void AsmPrinter::emitImplicitDef(const MachineInstr *MI) const {
   Register RegNo = MI->getOperand(0).getReg();
 
   SmallString<128> Str;
-  raw_svector_ostream OS(Str);
+  buffered_svector_ostream OS(Str);
   OS << "implicit-def: "
      << printReg(RegNo, MF->getSubtarget().getRegisterInfo());
 
@@ -1141,7 +1141,7 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
     return false;
 
   SmallString<128> Str;
-  raw_svector_ostream OS(Str);
+  buffered_svector_ostream OS(Str);
   OS << "DEBUG_VALUE: ";
 
   const DILocalVariable *V = MI->getDebugVariable();
@@ -1235,7 +1235,7 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
   }
 
   // NOTE: Want this comment at start of line, don't emit with AddComment.
-  AP.OutStreamer->emitRawComment(Str);
+  AP.OutStreamer->emitRawComment(OS.str());
   return true;
 }
 
@@ -1247,7 +1247,7 @@ static bool emitDebugLabelComment(const MachineInstr *MI, AsmPrinter &AP) {
     return false;
 
   SmallString<128> Str;
-  raw_svector_ostream OS(Str);
+  buffered_svector_ostream OS(Str);
   OS << "DEBUG_LABEL: ";
 
   const DILabel *V = MI->getDebugLabel();
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index 5a7013c964cb4..64629455ca430 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -361,7 +361,7 @@ void AsmPrinter::emitInlineAsm(const MachineInstr *MI) const {
   // Emit the inline asm to a temporary string so we can emit it through
   // EmitInlineAsm.
   SmallString<256> StringData;
-  raw_svector_ostream OS(StringData);
+  buffered_svector_ostream OS(StringData);
 
   AsmPrinter *AP = const_cast<AsmPrinter*>(this);
   EmitInlineAsmStr(AsmStr, MI, MMI, MAI, AP, LocCookie, OS);
@@ -411,7 +411,7 @@ void AsmPrinter::emitInlineAsm(const MachineInstr *MI) const {
     }
   }
 
-  emitInlineAsm(StringData, getSubtargetInfo(), TM.Options.MCOptions, LocMD,
+  emitInlineAsm(OS.str(), getSubtargetInfo(), TM.Options.MCOptions, LocMD,
                 MI->getInlineAsmDialect());
 
   // Emit the #NOAPP end marker.  This has to happen even if verbose-asm isn't
diff --git a/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h b/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h
index bd2c60eadd612..0529a6ed6a8bb 100644
--- a/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h
+++ b/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h
@@ -108,7 +108,7 @@ class BufferByteStreamer final : public ByteStreamer {
       Comments.push_back(Comment.str());
   }
   void emitSLEB128(uint64_t DWord, const Twine &Comment) override {
-    raw_svector_ostream OSE(Buffer);
+    buffered_svector_ostream OSE(Buffer);
     unsigned Length = encodeSLEB128(DWord, OSE);
     if (GenerateComments) {
       Comments.push_back(Comment.str());
@@ -121,7 +121,7 @@ class BufferByteStreamer final : public ByteStreamer {
   }
   void emitULEB128(uint64_t DWord, const Twine &Comment,
                    unsigned PadTo) override {
-    raw_svector_ostream OSE(Buffer);
+    buffered_svector_ostream OSE(Buffer);
     unsigned Length = encodeULEB128(DWord, OSE, PadTo);
     if (GenerateComments) {
       Comments.push_back(Comment.str());
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index dddc08b3bc016..a5fe97c25236d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -773,9 +773,9 @@ void CodeViewDebug::emitTypeGlobalHashes() {
       // Emit an EOL-comment describing which TypeIndex this hash corresponds
       // to, as well as the stringified SHA1 hash.
       SmallString<32> Comment;
-      raw_svector_ostream CommentOS(Comment);
+      buffered_svector_ostream CommentOS(Comment);
       CommentOS << formatv("{0:X+} [{1}]", TI.getIndex(), GHR);
-      OS.AddComment(Comment);
+      OS.AddComment(CommentOS.str());
       ++TI;
     }
     assert(GHR.Hash.size() == 8);
diff --git a/llvm/lib/CodeGen/CFGuardLongjmp.cpp b/llvm/lib/CodeGen/CFGuardLongjmp.cpp
index b5d88a7432b17..faa25700c1e38 100644
--- a/llvm/lib/CodeGen/CFGuardLongjmp.cpp
+++ b/llvm/lib/CodeGen/CFGuardLongjmp.cpp
@@ -109,7 +109,8 @@ bool CFGuardLongjmp::runOnMachineFunction(MachineFunction &MF) {
   // of longjmp targets.
   for (MachineInstr *Setjmp : SetjmpCalls) {
     SmallString<128> SymbolName;
-    raw_svector_ostream(SymbolName) << "$cfgsj_" << MF.getName() << SetjmpNum++;
+    buffered_svector_ostream(SymbolName)
+        << "$cfgsj_" << MF.getName() << SetjmpNum++;
     MCSymbol *SjSymbol = MF.getContext().getOrCreateSymbol(SymbolName);
 
     Setjmp->setPostInstrSymbol(MF, SjSymbol);
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index 533ab7cccaeb7..47ff7bb964842 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -94,7 +94,7 @@ MCSymbol *MachineBasicBlock::getEHCatchretSymbol() const {
   if (!CachedEHCatchretMCSymbol) {
     const MachineFunction *MF = getParent();
     SmallString<128> SymbolName;
-    raw_svector_ostream(SymbolName)
+    buffered_svector_ostream(SymbolName)
         << "$ehgcr_" << MF->getFunctionNumber() << '_' << getNumber();
     CachedEHCatchretMCSymbol = MF->getContext().getOrCreateSymbol(SymbolName);
   }
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index 7f6a75208d253..186bbe0d31ea2 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -753,8 +753,8 @@ MCSymbol *MachineFunction::getJTISymbol(unsigned JTI, MCContext &Ctx,
   StringRef Prefix = isLinkerPrivate ? DL.getLinkerPrivateGlobalPrefix()
                                      : DL.getPrivateGlobalPrefix();
   SmallString<60> Name;
-  raw_svector_ostream(Name)
-    << Prefix << "JTI" << getFunctionNumber() << '_' << JTI;
+  buffered_svector_ostream(Name)
+      << Prefix << "JTI" << getFunctionNumber() << '_' << JTI;
   return Ctx.getOrCreateSymbol(Name);
 }
 
diff --git a/llvm/lib/CodeGen/MachineFunctionPass.cpp b/llvm/lib/CodeGen/MachineFunctionPass.cpp
index 62ac3e32d24d9..b8d5a1a3b660f 100644
--- a/llvm/lib/CodeGen/MachineFunctionPass.cpp
+++ b/llvm/lib/CodeGen/MachineFunctionPass.cpp
@@ -85,7 +85,7 @@ bool MachineFunctionPass::runOnFunction(Function &F) {
                                   IsInterestingPass &&
                                   isFunctionInPrintList(MF.getName());
   if (ShouldPrintChanged) {
-    raw_svector_ostream OS(BeforeStr);
+    buffered_svector_ostream OS(BeforeStr);
     MF.print(OS);
   }
 
@@ -122,7 +122,7 @@ bool MachineFunctionPass::runOnFunction(Function &F) {
   // than quiet/verbose are unimplemented and treated the same as 'quiet'.
   if (ShouldPrintChanged || !IsInterestingPass) {
     if (ShouldPrintChanged) {
-      raw_svector_ostream OS(AfterStr);
+      buffered_svector_ostream OS(AfterStr);
       MF.print(OS);
     }
     if (IsInterestingPass && BeforeStr != AfterStr) {
diff --git a/llvm/lib/CodeGen/ModuloSchedule.cpp b/llvm/lib/CodeGen/ModuloSchedule.cpp
index 0aed235ec39b5..90070f206f43b 100644
--- a/llvm/lib/CodeGen/ModuloSchedule.cpp
+++ b/llvm/lib/CodeGen/ModuloSchedule.cpp
@@ -2841,7 +2841,7 @@ void ModuloScheduleTest::runOnLoop(MachineFunction &MF, MachineLoop &L) {
 void ModuloScheduleTestAnnotater::annotate() {
   for (MachineInstr *MI : S.getInstructions()) {
     SmallVector<char, 16> SV;
-    raw_svector_ostream OS(SV);
+    buffered_svector_ostream OS(SV);
     OS << "Stage-" << S.getStage(MI) << "_Cycle-" << S.getCycle(MI);
     MCSymbol *Sym = MF.getContext().getOrCreateSymbol(OS.str());
     MI->setPostInstrSymbol(MF, Sym);
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 976691b7de448..9518015684f7d 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringO...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/97704


More information about the llvm-commits mailing list