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

Alexis Engelke via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 4 02:51:33 PDT 2024


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

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. :)

>From 784ae4bf2ad079bc667130b2c0293475779db0a0 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Tue, 2 Jul 2024 16:09:31 +0200
Subject: [PATCH 1/3] [Support] Inline some raw_ostream methods

Inline the fast path of write, which is frequently called, as well as
flush and SetBufferAndMode, the latter being called for every
raw_svector_ostream. This avoids several out-of-line calls and improves
performance.
---
 llvm/include/llvm/Support/raw_ostream.h | 72 ++++++++++++++++++-------
 llvm/lib/Support/raw_ostream.cpp        | 52 +++++-------------
 2 files changed, 68 insertions(+), 56 deletions(-)

diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
index df9ee2e5a78586..22d22373a66d83 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.
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 2ce54faa9857e6..48323d50110180 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -97,6 +97,7 @@ size_t raw_ostream::preferred_buffer_size() const {
 }
 
 void raw_ostream::SetBuffered() {
+  assert(BufferMode != BufferKind::ExternalBuffer);
   // Ask the subclass to determine an appropriate buffer size.
   if (size_t Size = preferred_buffer_size())
     SetBufferSize(Size);
@@ -105,25 +106,6 @@ void raw_ostream::SetBuffered() {
     SetUnbuffered();
 }
 
-void raw_ostream::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!");
-}
-
 raw_ostream &raw_ostream::operator<<(unsigned long N) {
   write_integer(*this, static_cast<uint64_t>(N), 0, IntegerStyle::Integer);
   return *this;
@@ -217,44 +199,38 @@ raw_ostream &raw_ostream::operator<<(double N) {
   return *this;
 }
 
-void raw_ostream::flush_nonempty() {
-  assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
-  size_t Length = OutBufCur - OutBufStart;
-  OutBufCur = OutBufStart;
-  write_impl(OutBufStart, Length);
-}
-
-raw_ostream &raw_ostream::write(unsigned char C) {
+void raw_ostream::writeSlow(unsigned char C) {
   // Group exceptional cases into a single branch.
   if (LLVM_UNLIKELY(OutBufCur >= OutBufEnd)) {
     if (LLVM_UNLIKELY(!OutBufStart)) {
       if (BufferMode == BufferKind::Unbuffered) {
         write_impl(reinterpret_cast<char *>(&C), 1);
-        return *this;
+        return;
       }
       // Set up a buffer and start over.
       SetBuffered();
-      return write(C);
+      write(C);
+      return;
     }
 
     flush_nonempty();
   }
 
   *OutBufCur++ = C;
-  return *this;
 }
 
-raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
+void raw_ostream::writeSlow(const char *Ptr, size_t Size) {
   // Group exceptional cases into a single branch.
   if (LLVM_UNLIKELY(size_t(OutBufEnd - OutBufCur) < Size)) {
     if (LLVM_UNLIKELY(!OutBufStart)) {
       if (BufferMode == BufferKind::Unbuffered) {
         write_impl(Ptr, Size);
-        return *this;
+        return;
       }
       // Set up a buffer and start over.
       SetBuffered();
-      return write(Ptr, Size);
+      write(Ptr, Size);
+      return;
     }
 
     size_t NumBytes = OutBufEnd - OutBufCur;
@@ -269,22 +245,22 @@ raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
       size_t BytesRemaining = Size - BytesToWrite;
       if (BytesRemaining > size_t(OutBufEnd - OutBufCur)) {
         // Too much left over to copy into our buffer.
-        return write(Ptr + BytesToWrite, BytesRemaining);
+        write(Ptr + BytesToWrite, BytesRemaining);
+        return;
       }
       copy_to_buffer(Ptr + BytesToWrite, BytesRemaining);
-      return *this;
+      return;
     }
 
     // We don't have enough space in the buffer to fit the string in. Insert as
     // much as possible, flush and start over with the remainder.
     copy_to_buffer(Ptr, NumBytes);
     flush_nonempty();
-    return write(Ptr + NumBytes, Size - NumBytes);
+    write(Ptr + NumBytes, Size - NumBytes);
+    return;
   }
 
   copy_to_buffer(Ptr, Size);
-
-  return *this;
 }
 
 void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) {

>From 044e1c6a3a606005d6915d55cafbb1a9945b7e6b Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Wed, 3 Jul 2024 12:00:45 +0000
Subject: [PATCH 2/3] [Support] Introduce bufferd_svector_ostream

This provides an alternative to raw_svector_ostream without the
guarantee of keeping the SmallVector up-to-date at all times, in
particular, the size is only updated on destruction. This allows to use
the SmallVector buffer as buffer for the ostream itself, staying on the
fast path of write() most of the time.
---
 llvm/include/llvm/Support/raw_ostream.h | 50 +++++++++++++++++++++++++
 llvm/lib/Support/raw_ostream.cpp        | 35 ++++++++++++++++-
 2 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
index 22d22373a66d83..828d893d2a134f 100644
--- a/llvm/include/llvm/Support/raw_ostream.h
+++ b/llvm/include/llvm/Support/raw_ostream.h
@@ -763,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/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 48323d50110180..7ec07044daec96 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -77,8 +77,9 @@ constexpr raw_ostream::Colors raw_ostream::RESET;
 raw_ostream::~raw_ostream() {
   // raw_ostream's subclasses should take care to flush the buffer
   // in their destructors.
-  assert(OutBufCur == OutBufStart &&
-         "raw_ostream destructor called with non-empty buffer!");
+  assert(
+      (BufferMode == BufferKind::ExternalBuffer || OutBufCur == OutBufStart) &&
+      "raw_ostream destructor called with non-empty buffer!");
 
   if (BufferMode == BufferKind::InternalBuffer)
     delete [] OutBufStart;
@@ -954,6 +955,36 @@ bool raw_svector_ostream::classof(const raw_ostream *OS) {
   return OS->get_kind() == OStreamKind::OK_SVecStream;
 }
 
+//===----------------------------------------------------------------------===//
+//  buffered_svector_ostream
+//===----------------------------------------------------------------------===//
+
+void buffered_svector_ostream::write_impl(const char *Ptr, size_t Size) {
+  // write_impl is either calls with the start of the buffer, or a user buffer.
+  // In the first case, we just extend the size of the flushed part, resize
+  // the vector, and update the buffer pointers. Otherwise, use SmallVector's
+  // append() to copy the user data.
+  if (Ptr != OS.data() + FlushedSize) {
+    OS.truncate(FlushedSize);
+    OS.append(Ptr, Ptr + Size);
+  } else {
+    assert(FlushedSize + Size <= OS.size() && "buffer overrun");
+  }
+  FlushedSize += Size;
+  // We must always have spare space in the buffer.
+  if (FlushedSize == OS.size()) {
+    OS.reserve(OS.size() + 1); // SmallVector grows exponentially
+    OS.resize_for_overwrite(OS.capacity());
+  }
+  updateBuffer();
+}
+
+void buffered_svector_ostream::pwrite_impl(const char *Ptr, size_t Size,
+                                           uint64_t Offset) {
+  flush();
+  memcpy(OS.data() + Offset, Ptr, Size);
+}
+
 //===----------------------------------------------------------------------===//
 //  raw_null_ostream
 //===----------------------------------------------------------------------===//

>From db796d51c0a4dccb2d326b47ac5cb1cad9918fd1 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Wed, 3 Jul 2024 13:11:38 +0000
Subject: [PATCH 3/3] Use buffered_svector_ostream in some places

---
 llvm/include/llvm/Support/FormatCommon.h      |  6 ++--
 llvm/include/llvm/Support/FormatVariadic.h    |  3 +-
 llvm/include/llvm/Support/YAMLTraits.h        |  2 +-
 .../llvm/TableGen/StringToOffsetTable.h       |  2 +-
 llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp  |  9 ++---
 llvm/lib/Analysis/TargetLibraryInfo.cpp       |  2 +-
 llvm/lib/CodeGen/AsmPrinter/AIXException.cpp  |  3 +-
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp    |  8 ++---
 .../AsmPrinter/AsmPrinterInlineAsm.cpp        |  4 +--
 llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h    |  4 +--
 llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp |  4 +--
 llvm/lib/CodeGen/CFGuardLongjmp.cpp           |  3 +-
 llvm/lib/CodeGen/MachineBasicBlock.cpp        |  2 +-
 llvm/lib/CodeGen/MachineFunction.cpp          |  4 +--
 llvm/lib/CodeGen/MachineFunctionPass.cpp      |  4 +--
 llvm/lib/CodeGen/ModuloSchedule.cpp           |  2 +-
 .../CodeGen/TargetLoweringObjectFileImpl.cpp  | 35 ++++++++++++-------
 llvm/lib/DebugInfo/BTF/BTFParser.cpp          |  4 +--
 llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp  | 11 +++---
 .../LogicalView/Readers/LVBinaryReader.cpp    |  2 +-
 llvm/lib/ExecutionEngine/ExecutionEngine.cpp  |  6 ++--
 llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp      | 19 +++++-----
 .../OProfileJIT/OProfileWrapper.cpp           |  4 +--
 llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp |  2 +-
 llvm/lib/FileCheck/FileCheck.cpp              |  4 +--
 llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp     |  6 ++--
 llvm/lib/IR/AutoUpgrade.cpp                   |  2 +-
 llvm/lib/IR/Mangler.cpp                       |  4 +--
 llvm/lib/IR/VFABIDemangler.cpp                |  8 +++--
 llvm/lib/MC/ELFObjectWriter.cpp               |  6 ++--
 llvm/lib/MC/MCAssembler.cpp                   | 29 ++++++++-------
 llvm/lib/MC/MCContext.cpp                     |  4 +--
 llvm/lib/MC/MCStreamer.cpp                    | 12 +++----
 llvm/lib/MC/MCWinCOFFStreamer.cpp             |  4 +--
 llvm/lib/MC/MachObjectWriter.cpp              |  2 +-
 llvm/lib/MC/WinCOFFObjectWriter.cpp           | 10 +++---
 llvm/lib/Object/IRSymtab.cpp                  |  2 +-
 llvm/lib/ObjectYAML/yaml2obj.cpp              |  2 +-
 llvm/lib/Support/ErrorHandling.cpp            |  2 +-
 llvm/lib/Support/PrettyStackTrace.cpp         |  2 +-
 llvm/lib/Support/Twine.cpp                    |  2 +-
 llvm/lib/Support/raw_ostream.cpp              |  6 ++--
 .../Target/X86/MCTargetDesc/X86AsmBackend.cpp |  2 +-
 .../MCTargetDesc/X86WinCOFFTargetStreamer.cpp |  2 +-
 44 files changed, 141 insertions(+), 115 deletions(-)

diff --git a/llvm/include/llvm/Support/FormatCommon.h b/llvm/include/llvm/Support/FormatCommon.h
index 326e00936aa7c5..848a98fa56f46b 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 595f2cf559a428..29e0a09e22e363 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 1d04783753d5cd..dc33afe3da0b51 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/TableGen/StringToOffsetTable.h b/llvm/include/llvm/TableGen/StringToOffsetTable.h
index 66bcc81c94b594..87a93b00182b97 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 9f6e53ba15b6a6..2670ab1c87e1f7 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 bf53f562ec4195..89d6e2e8085de7 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 5d7c97adcacade..3fb82c1bebac34 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 1391893e55a52a..ae0f5a69f0b39d 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 5a7013c964cb4b..64629455ca430f 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 bd2c60eadd6129..0529a6ed6a8bb1 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 dddc08b3bc0166..a5fe97c25236df 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 b5d88a7432b171..faa25700c1e386 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 533ab7cccaeb71..47ff7bb9648422 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 7f6a75208d253f..186bbe0d31ea2f 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 62ac3e32d24d9d..b8d5a1a3b660ff 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 0aed235ec39b5f..90070f206f43bb 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 976691b7de4484..9518015684f7d0 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -657,7 +657,8 @@ getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind,
   bool HasPrefix = false;
   if (const auto *F = dyn_cast<Function>(GO)) {
     if (std::optional<StringRef> Prefix = F->getSectionPrefix()) {
-      raw_svector_ostream(Name) << '.' << *Prefix;
+      Name += ".";
+      Name += *Prefix;
       HasPrefix = true;
     }
   }
@@ -1747,14 +1748,18 @@ MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal(
       StringRef COMDATSymName = Sym->getName();
 
       if (const auto *F = dyn_cast<Function>(GO))
-        if (std::optional<StringRef> Prefix = F->getSectionPrefix())
-          raw_svector_ostream(Name) << '$' << *Prefix;
+        if (std::optional<StringRef> Prefix = F->getSectionPrefix()) {
+          Name += "$";
+          Name += *Prefix;
+        }
 
       // Append "$symbol" to the section name *before* IR-level mangling is
       // applied when targetting mingw. This is what GCC does, and the ld.bfd
       // COFF linker will not properly handle comdats otherwise.
-      if (getContext().getTargetTriple().isWindowsGNUEnvironment())
-        raw_svector_ostream(Name) << '$' << ComdatGV->getName();
+      if (getContext().getTargetTriple().isWindowsGNUEnvironment()) {
+        Name += "$";
+        Name += ComdatGV->getName();
+      }
 
       return getContext().getCOFFSection(Name, Characteristics, COMDATSymName,
                                          Selection, UniqueID);
@@ -1971,10 +1976,12 @@ static MCSectionCOFF *getCOFFStaticStructorSection(MCContext &Ctx,
       LastLetter = 'C';
     else if (Priority == 400)
       LastLetter = 'L';
-    raw_svector_ostream OS(Name);
-    OS << ".CRT$X" << (IsCtor ? "C" : "T") << LastLetter;
-    if (AddPrioritySuffix)
-      OS << format("%05u", Priority);
+    {
+      buffered_svector_ostream OS(Name);
+      OS << ".CRT$X" << (IsCtor ? "C" : "T") << LastLetter;
+      if (AddPrioritySuffix)
+        OS << format("%05u", Priority);
+    }
     MCSectionCOFF *Sec = Ctx.getCOFFSection(
         Name, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ);
     return Ctx.getAssociativeCOFFSection(Sec, KeySym, 0);
@@ -2200,9 +2207,10 @@ selectWasmSectionForGlobal(MCContext &Ctx, const GlobalObject *GO,
   SmallString<128> Name = getSectionPrefixForGlobal(Kind, /*IsLarge=*/false);
 
   if (const auto *F = dyn_cast<Function>(GO)) {
-    const auto &OptionalPrefix = F->getSectionPrefix();
-    if (OptionalPrefix)
-      raw_svector_ostream(Name) << '.' << *OptionalPrefix;
+    if (std::optional<StringRef> Prefix = F->getSectionPrefix()) {
+      Name += ".";
+      Name += *Prefix;
+    }
   }
 
   if (EmitUniqueSection && UniqueSectionNames) {
@@ -2707,7 +2715,8 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForLSDA(
     // name of the LSDA csect so that each function has its own LSDA csect.
     // This helps the linker to garbage-collect EH info of unused functions.
     SmallString<128> NameStr = LSDA->getName();
-    raw_svector_ostream(NameStr) << '.' << F.getName();
+    NameStr += ".";
+    NameStr += F.getName();
     LSDA = getContext().getXCOFFSection(NameStr, LSDA->getKind(),
                                         LSDA->getCsectProp());
   }
diff --git a/llvm/lib/DebugInfo/BTF/BTFParser.cpp b/llvm/lib/DebugInfo/BTF/BTFParser.cpp
index 4fc31a44560310..8390fb440701ba 100644
--- a/llvm/lib/DebugInfo/BTF/BTFParser.cpp
+++ b/llvm/lib/DebugInfo/BTF/BTFParser.cpp
@@ -656,12 +656,12 @@ static void relocKindName(uint32_t X, raw_ostream &Out) {
 // [1] https://www.kernel.org/doc/html/latest/bpf/libbpf/index.html
 void BTFParser::symbolize(const BTF::BPFFieldReloc *Reloc,
                           SmallVectorImpl<char> &Result) const {
-  raw_svector_ostream Stream(Result);
+  buffered_svector_ostream Stream(Result);
   StringRef FullSpecStr = findString(Reloc->OffsetNameOff);
   SmallVector<uint32_t, 8> RawSpec;
 
   auto Fail = [&](auto Msg) {
-    Result.resize(0);
+    Stream.truncate(0);
     relocKindName(Reloc->RelocKind, Stream);
     Stream << " [" << Reloc->TypeID << "] '" << FullSpecStr << "'"
            << " <" << Msg << ">";
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
index d4979024cb57bd..28f31c3b056a7e 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
@@ -454,7 +454,7 @@ static bool printCompactDWARFExpr(
       auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
       if (RegName.empty())
         return false;
-      raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
+      buffered_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
       S << RegName;
       break;
     }
@@ -464,7 +464,7 @@ static bool printCompactDWARFExpr(
       auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
       if (RegName.empty())
         return false;
-      raw_svector_ostream S(Stack.emplace_back().String);
+      buffered_svector_ostream S(Stack.emplace_back().String);
       S << RegName;
       if (Offset)
         S << format("%+" PRId64, Offset);
@@ -477,7 +477,7 @@ static bool printCompactDWARFExpr(
       uint64_t SubExprLength = Op.getRawOperand(0);
       DWARFExpression::iterator SubExprEnd = I.skipBytes(SubExprLength);
       ++I;
-      raw_svector_ostream S(Stack.emplace_back().String);
+      buffered_svector_ostream S(Stack.emplace_back().String);
       S << "entry(";
       printCompactDWARFExpr(S, I, SubExprEnd, GetNameForDWARFReg);
       S << ")";
@@ -506,7 +506,8 @@ static bool printCompactDWARFExpr(
         auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
         if (RegName.empty())
           return false;
-        raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
+        buffered_svector_ostream S(
+            Stack.emplace_back(PrintedExpr::Value).String);
         S << RegName;
       } else if (Opcode >= dwarf::DW_OP_breg0 &&
                  Opcode <= dwarf::DW_OP_breg31) {
@@ -515,7 +516,7 @@ static bool printCompactDWARFExpr(
         auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
         if (RegName.empty())
           return false;
-        raw_svector_ostream S(Stack.emplace_back().String);
+        buffered_svector_ostream S(Stack.emplace_back().String);
         S << RegName;
         if (Offset)
           S << format("%+" PRId64, Offset);
diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp
index c45f0e91c43589..dfc6eb2bc49eca 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp
@@ -459,7 +459,7 @@ Error LVBinaryReader::createInstructions(LVScope *Scope,
     MCInst Instruction;
     uint64_t BytesConsumed = 0;
     SmallVector<char, 64> InsnStr;
-    raw_svector_ostream Annotations(InsnStr);
+    buffered_svector_ostream Annotations(InsnStr);
     MCDisassembler::DecodeStatus const S =
         MD->getInstruction(Instruction, BytesConsumed,
                            ArrayRef<uint8_t>(Begin, End), Address, outs());
diff --git a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp
index 28e4f96df828cd..ca8e3903537981 100644
--- a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -885,7 +885,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
     }
 
     SmallString<256> Msg;
-    raw_svector_ostream OS(Msg);
+    buffered_svector_ostream OS(Msg);
     OS << "ConstantExpr not handled: " << *CE;
     report_fatal_error(OS.str());
   }
@@ -1025,7 +1025,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
 
   default:
     SmallString<256> Msg;
-    raw_svector_ostream OS(Msg);
+    buffered_svector_ostream OS(Msg);
     OS << "ERROR: Constant unimplemented for type: " << *C->getType();
     report_fatal_error(OS.str());
   }
@@ -1149,7 +1149,7 @@ void ExecutionEngine::LoadValueFromMemory(GenericValue &Result,
   }
   default:
     SmallString<256> Msg;
-    raw_svector_ostream OS(Msg);
+    buffered_svector_ostream OS(Msg);
     OS << "Cannot load value of type " << *Ty << "!";
     report_fatal_error(OS.str());
   }
diff --git a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
index 869b383dd064f2..2a9abd2db79e1b 100644
--- a/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
+++ b/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
@@ -160,16 +160,19 @@ std::unique_ptr<MemoryBuffer> MCJIT::emitObject(Module *M) {
 
   // The RuntimeDyld will take ownership of this shortly
   SmallVector<char, 4096> ObjBufferSV;
-  raw_svector_ostream ObjStream(ObjBufferSV);
 
-  // Turn the machine code intermediate representation into bytes in memory
-  // that may be executed.
-  if (TM->addPassesToEmitMC(PM, Ctx, ObjStream, !getVerifyModules()))
-    report_fatal_error("Target does not support MC emission!");
+  {
+    buffered_svector_ostream ObjStream(ObjBufferSV);
+
+    // Turn the machine code intermediate representation into bytes in memory
+    // that may be executed.
+    if (TM->addPassesToEmitMC(PM, Ctx, ObjStream, !getVerifyModules()))
+      report_fatal_error("Target does not support MC emission!");
 
-  // Initialize passes.
-  PM.run(*M);
-  // Flush the output buffer to get the generated code into memory
+    // Initialize passes.
+    PM.run(*M);
+    // Flush the output buffer to get the generated code into memory
+  }
 
   auto CompiledObjBuffer = std::make_unique<SmallVectorMemoryBuffer>(
       std::move(ObjBufferSV), /*RequiresNullTerminator=*/false);
diff --git a/llvm/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp b/llvm/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp
index b78d2531382d03..0399b9df4b10e1 100644
--- a/llvm/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp
+++ b/llvm/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp
@@ -127,8 +127,8 @@ bool OProfileWrapper::checkForOProfileProcEntry() {
     if (Entry->d_type == DT_DIR) {
       // Build a path from the current entry name
       SmallString<256> CmdLineFName;
-      raw_svector_ostream(CmdLineFName) << "/proc/" << Entry->d_name
-                                        << "/cmdline";
+      buffered_svector_ostream(CmdLineFName)
+          << "/proc/" << Entry->d_name << "/cmdline";
 
       // Open the cmdline file
       int CmdLineFD = open(CmdLineFName.c_str(), S_IRUSR);
diff --git a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp
index fad7428e1f906c..96460ac89c5c2d 100644
--- a/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp
@@ -43,7 +43,7 @@ Expected<SimpleCompiler::CompileResult> SimpleCompiler::operator()(Module &M) {
   SmallVector<char, 0> ObjBufferSV;
 
   {
-    raw_svector_ostream ObjStream(ObjBufferSV);
+    buffered_svector_ostream ObjStream(ObjBufferSV);
 
     legacy::PassManager PM;
     MCContext *Ctx;
diff --git a/llvm/lib/FileCheck/FileCheck.cpp b/llvm/lib/FileCheck/FileCheck.cpp
index 1eb8330232321e..1971b0b4acdaee 100644
--- a/llvm/lib/FileCheck/FileCheck.cpp
+++ b/llvm/lib/FileCheck/FileCheck.cpp
@@ -1210,7 +1210,7 @@ void Pattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer,
   if (!Substitutions.empty()) {
     for (const auto &Substitution : Substitutions) {
       SmallString<256> Msg;
-      raw_svector_ostream OS(Msg);
+      buffered_svector_ostream OS(Msg);
 
       Expected<std::string> MatchedValue = Substitution->getResult();
       // Substitution failures are handled in printNoMatch().
@@ -1280,7 +1280,7 @@ void Pattern::printVariableDefs(const SourceMgr &SM,
   // Create notes for the sorted captures.
   for (const VarCapture &VC : VarCaptures) {
     SmallString<256> Msg;
-    raw_svector_ostream OS(Msg);
+    buffered_svector_ostream OS(Msg);
     OS << "captured var \"" << VC.Name << "\"";
     if (Diags)
       Diags->emplace_back(SM, CheckTy, getLoc(), MatchTy, VC.Range, OS.str());
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index a06e81dd280e0c..94268b56fab4d1 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -6714,7 +6714,7 @@ std::string OpenMPIRBuilder::getNameWithSeparators(ArrayRef<StringRef> Parts,
                                                    StringRef FirstSeparator,
                                                    StringRef Separator) {
   SmallString<128> Buffer;
-  llvm::raw_svector_ostream OS(Buffer);
+  buffered_svector_ostream OS(Buffer);
   StringRef Sep = FirstSeparator;
   for (StringRef Part : Parts) {
     OS << Sep << Part;
@@ -8136,7 +8136,7 @@ void OpenMPIRBuilder::createOffloadEntriesAndInfoMetadata(
 void TargetRegionEntryInfo::getTargetRegionEntryFnName(
     SmallVectorImpl<char> &Name, StringRef ParentName, unsigned DeviceID,
     unsigned FileID, unsigned Line, unsigned Count) {
-  raw_svector_ostream OS(Name);
+  buffered_svector_ostream OS(Name);
   OS << "__omp_offloading" << llvm::format("_%x", DeviceID)
      << llvm::format("_%x_", FileID) << ParentName << "_l" << Line;
   if (Count)
@@ -8224,7 +8224,7 @@ Constant *OpenMPIRBuilder::getAddrOfDeclareTargetVar(
        Config.hasRequiresUnifiedSharedMemory())) {
     SmallString<64> PtrName;
     {
-      raw_svector_ostream OS(PtrName);
+      buffered_svector_ostream OS(PtrName);
       OS << MangledName;
       if (!IsExternallyVisible)
         OS << format("_%x", EntryInfo.FileID);
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 5beefaa1ec7018..9aeb2375d1c355 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -5269,7 +5269,7 @@ void llvm::UpgradeSectionAttributes(Module &M) {
     Section.split(Components, ',');
 
     SmallString<32> Buffer;
-    raw_svector_ostream OS(Buffer);
+    buffered_svector_ostream OS(Buffer);
 
     for (auto Component : Components)
       OS << ',' << Component.trim();
diff --git a/llvm/lib/IR/Mangler.cpp b/llvm/lib/IR/Mangler.cpp
index e6c3ea9d568831..3724ec975cfe96 100644
--- a/llvm/lib/IR/Mangler.cpp
+++ b/llvm/lib/IR/Mangler.cpp
@@ -74,7 +74,7 @@ void Mangler::getNameWithPrefix(raw_ostream &OS, const Twine &GVName,
 
 void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
                                 const Twine &GVName, const DataLayout &DL) {
-  raw_svector_ostream OS(OutName);
+  buffered_svector_ostream OS(OutName);
   char Prefix = DL.getGlobalPrefix();
   return getNameWithPrefixImpl(OS, GVName, Default, DL, Prefix);
 }
@@ -187,7 +187,7 @@ void Mangler::getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV,
 void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
                                 const GlobalValue *GV,
                                 bool CannotUsePrivateLabel) const {
-  raw_svector_ostream OS(OutName);
+  buffered_svector_ostream OS(OutName);
   getNameWithPrefix(OS, GV, CannotUsePrivateLabel);
 }
 
diff --git a/llvm/lib/IR/VFABIDemangler.cpp b/llvm/lib/IR/VFABIDemangler.cpp
index cdfb9fbfaa084d..b9bfcb0e2f3a6a 100644
--- a/llvm/lib/IR/VFABIDemangler.cpp
+++ b/llvm/lib/IR/VFABIDemangler.cpp
@@ -576,9 +576,11 @@ void VFABI::setVectorVariantNames(CallInst *CI,
     return;
 
   SmallString<256> Buffer;
-  llvm::raw_svector_ostream Out(Buffer);
-  for (const std::string &VariantMapping : VariantMappings)
-    Out << VariantMapping << ",";
+  {
+    buffered_svector_ostream Out(Buffer);
+    for (const std::string &VariantMapping : VariantMappings)
+      Out << VariantMapping << ",";
+  }
   // Get rid of the trailing ','.
   assert(!Buffer.str().empty() && "Must have at least one char.");
   Buffer.pop_back();
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index 5cba6eb15b5c99..535a037980b3ba 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -854,8 +854,10 @@ void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec) {
   }
 
   SmallVector<char, 128> UncompressedData;
-  raw_svector_ostream VecOS(UncompressedData);
-  Asm.writeSectionData(VecOS, &Section);
+  {
+    buffered_svector_ostream VecOS(UncompressedData);
+    Asm.writeSectionData(VecOS, &Section);
+  }
   ArrayRef<uint8_t> Uncompressed =
       ArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
                UncompressedData.size());
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index cdac58c5fbf68b..91145f35483b52 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -1152,15 +1152,18 @@ bool MCAssembler::relaxLEB(MCLEBFragment &LF) {
       Value = 0;
   }
   Data.clear();
-  raw_svector_ostream OSE(Data);
-  // The compiler can generate EH table assembly that is impossible to assemble
-  // without either adding padding to an LEB fragment or adding extra padding
-  // to a later alignment fragment. To accommodate such tables, relaxation can
-  // only increase an LEB fragment size here, not decrease it. See PR35809.
-  if (LF.isSigned())
-    encodeSLEB128(Value, OSE, PadTo);
-  else
-    encodeULEB128(Value, OSE, PadTo);
+  {
+    buffered_svector_ostream OSE(Data);
+    // The compiler can generate EH table assembly that is impossible to
+    // assemble without either adding padding to an LEB fragment or adding extra
+    // padding to a later alignment fragment. To accommodate such tables,
+    // relaxation can only increase an LEB fragment size here, not decrease it.
+    // See PR35809.
+    if (LF.isSigned())
+      encodeSLEB128(Value, OSE, PadTo);
+    else
+      encodeULEB128(Value, OSE, PadTo);
+  }
   return OldSize != LF.getContents().size();
 }
 
@@ -1291,11 +1294,13 @@ bool MCAssembler::relaxPseudoProbeAddr(MCPseudoProbeAddrFragment &PF) {
   (void)Abs;
   SmallVectorImpl<char> &Data = PF.getContents();
   Data.clear();
-  raw_svector_ostream OSE(Data);
   PF.getFixups().clear();
 
-  // AddrDelta is a signed integer
-  encodeSLEB128(AddrDelta, OSE, OldSize);
+  {
+    buffered_svector_ostream OSE(Data);
+    // AddrDelta is a signed integer
+    encodeSLEB128(AddrDelta, OSE, OldSize);
+  }
   return OldSize != Data.size();
 }
 
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 2fe83690164406..8b4b8f778ff2d2 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -302,7 +302,7 @@ MCSymbol *MCContext::createRenamableSymbol(const Twine &Name,
     AlwaysAddSuffix = false;
 
     NewName.resize(NameLen);
-    raw_svector_ostream(NewName) << NameEntry.second.NextUniqueID++;
+    buffered_svector_ostream(NewName) << NameEntry.second.NextUniqueID++;
     EntryPtr = &getSymbolTableEntry(NewName.str());
   }
 
@@ -454,7 +454,7 @@ MCSymbolXCOFF *MCContext::createXCOFFSymbolImpl(const MCSymbolTableEntry *Name,
   // at the same time replace invalid characters with '_'.
   for (size_t I = 0; I < InvalidName.size(); ++I) {
     if (!MAI->isAcceptableChar(InvalidName[I]) || InvalidName[I] == '_') {
-      raw_svector_ostream(ValidName).write_hex(InvalidName[I]);
+      buffered_svector_ostream(ValidName).write_hex(InvalidName[I]);
       InvalidName[I] = '_';
     }
   }
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index a3f67941c10157..130ec747a10582 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -70,7 +70,7 @@ void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
 
 void MCTargetStreamer::emitValue(const MCExpr *Value) {
   SmallString<128> Str;
-  raw_svector_ostream OS(Str);
+  buffered_svector_ostream OS(Str);
 
   Value->print(OS, Streamer.getContext().getAsmInfo());
   Streamer.emitRawText(OS.str());
@@ -81,7 +81,7 @@ void MCTargetStreamer::emitRawBytes(StringRef Data) {
   const char *Directive = MAI->getData8bitsDirective();
   for (const unsigned char C : Data.bytes()) {
     SmallString<128> Str;
-    raw_svector_ostream OS(Str);
+    buffered_svector_ostream OS(Str);
 
     OS << Directive << (unsigned)C;
     Streamer.emitRawText(OS.str());
@@ -160,20 +160,20 @@ void MCStreamer::emitIntValue(const APInt &Value) {
 /// client having to pass in a MCExpr for constant integers.
 unsigned MCStreamer::emitULEB128IntValue(uint64_t Value, unsigned PadTo) {
   SmallString<128> Tmp;
-  raw_svector_ostream OSE(Tmp);
+  buffered_svector_ostream OSE(Tmp);
   encodeULEB128(Value, OSE, PadTo);
   emitBytes(OSE.str());
-  return Tmp.size();
+  return OSE.tell();
 }
 
 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
 /// client having to pass in a MCExpr for constant integers.
 unsigned MCStreamer::emitSLEB128IntValue(int64_t Value) {
   SmallString<128> Tmp;
-  raw_svector_ostream OSE(Tmp);
+  buffered_svector_ostream OSE(Tmp);
   encodeSLEB128(Value, OSE);
   emitBytes(OSE.str());
-  return Tmp.size();
+  return OSE.tell();
 }
 
 void MCStreamer::emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
diff --git a/llvm/lib/MC/MCWinCOFFStreamer.cpp b/llvm/lib/MC/MCWinCOFFStreamer.cpp
index 538244cb8ba6a4..22f583f68fa2fc 100644
--- a/llvm/lib/MC/MCWinCOFFStreamer.cpp
+++ b/llvm/lib/MC/MCWinCOFFStreamer.cpp
@@ -288,7 +288,7 @@ void MCWinCOFFStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size,
 
   if (!T.isWindowsMSVCEnvironment() && ByteAlignment > 1) {
     SmallString<128> Directive;
-    raw_svector_ostream OS(Directive);
+    buffered_svector_ostream OS(Directive);
     const MCObjectFileInfo *MFI = getContext().getObjectFileInfo();
 
     OS << " -aligncomm:\"" << Symbol->getName() << "\","
@@ -296,7 +296,7 @@ void MCWinCOFFStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size,
 
     pushSection();
     switchSection(MFI->getDrectveSection());
-    emitBytes(Directive);
+    emitBytes(OS.str());
     popSection();
   }
 }
diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp
index e9499558a90dbf..090aafde61b08d 100644
--- a/llvm/lib/MC/MachObjectWriter.cpp
+++ b/llvm/lib/MC/MachObjectWriter.cpp
@@ -791,7 +791,7 @@ uint64_t MachObjectWriter::writeObject(MCAssembler &Asm) {
         "__LLVM", "__cg_profile", 0, SectionKind::getMetadata());
     auto &Frag = cast<MCDataFragment>(*CGProfileSection->begin());
     Frag.getContents().clear();
-    raw_svector_ostream OS(Frag.getContents());
+    buffered_svector_ostream OS(Frag.getContents());
     for (const MCAssembler::CGProfileEntry &CGPE : Asm.CGProfile) {
       uint32_t FromIndex = CGPE.From->getSymbol().getIndex();
       uint32_t ToIndex = CGPE.To->getSymbol().getIndex();
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index c0bad192eb9823..e1822aaabcd043 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -602,8 +602,10 @@ uint32_t WinCOFFWriter::writeSectionContents(MCAssembler &Asm,
   // Save the contents of the section to a temporary buffer, we need this
   // to CRC the data before we dump it into the object file.
   SmallVector<char, 128> Buf;
-  raw_svector_ostream VecOS(Buf);
-  Asm.writeSectionData(VecOS, &MCSec);
+  {
+    buffered_svector_ostream VecOS(Buf);
+    Asm.writeSectionData(VecOS, &MCSec);
+  }
 
   // Write the section contents to the object file.
   W.OS << Buf;
@@ -1089,7 +1091,7 @@ uint64_t WinCOFFWriter::writeObject(MCAssembler &Asm) {
     auto *Sec = Asm.getContext().getCOFFSection(
         ".llvm_addrsig", COFF::IMAGE_SCN_LNK_REMOVE);
     auto *Frag = cast<MCDataFragment>(Sec->curFragList()->Head);
-    raw_svector_ostream OS(Frag->getContents());
+    buffered_svector_ostream OS(Frag->getContents());
     for (const MCSymbol *S : OWriter.AddrsigSyms) {
       if (!S->isRegistered())
         continue;
@@ -1111,7 +1113,7 @@ uint64_t WinCOFFWriter::writeObject(MCAssembler &Asm) {
     auto *Sec = Asm.getContext().getCOFFSection(
         ".llvm.call-graph-profile", COFF::IMAGE_SCN_LNK_REMOVE);
     auto *Frag = cast<MCDataFragment>(Sec->curFragList()->Head);
-    raw_svector_ostream OS(Frag->getContents());
+    buffered_svector_ostream OS(Frag->getContents());
     for (const MCAssembler::CGProfileEntry &CGPE : Asm.CGProfile) {
       uint32_t FromIndex = CGPE.From->getSymbol().getIndex();
       uint32_t ToIndex = CGPE.To->getSymbol().getIndex();
diff --git a/llvm/lib/Object/IRSymtab.cpp b/llvm/lib/Object/IRSymtab.cpp
index 7e29da4d5e948f..56959b462a8a64 100644
--- a/llvm/lib/Object/IRSymtab.cpp
+++ b/llvm/lib/Object/IRSymtab.cpp
@@ -242,7 +242,7 @@ Error Builder::addSymbol(const ModuleSymbolTable &Msymtab,
 
   SmallString<64> Name;
   {
-    raw_svector_ostream OS(Name);
+    buffered_svector_ostream OS(Name);
     Msymtab.printSymbolName(OS, Msym);
   }
   setStr(Sym.Name, Saver.save(Name.str()));
diff --git a/llvm/lib/ObjectYAML/yaml2obj.cpp b/llvm/lib/ObjectYAML/yaml2obj.cpp
index b9a9ad63970995..65d37fd6b758a1 100644
--- a/llvm/lib/ObjectYAML/yaml2obj.cpp
+++ b/llvm/lib/ObjectYAML/yaml2obj.cpp
@@ -67,7 +67,7 @@ std::unique_ptr<object::ObjectFile>
 yaml2ObjectFile(SmallVectorImpl<char> &Storage, StringRef Yaml,
                 ErrorHandler ErrHandler) {
   Storage.clear();
-  raw_svector_ostream OS(Storage);
+  buffered_svector_ostream OS(Storage);
 
   yaml::Input YIn(Yaml);
   if (!convertYAML(YIn, OS, ErrHandler))
diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
index cb42e28c04a86d..e5ffa079f9d3a4 100644
--- a/llvm/lib/Support/ErrorHandling.cpp
+++ b/llvm/lib/Support/ErrorHandling.cpp
@@ -107,7 +107,7 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
     // succeeds (e.g. handling EINTR) and we can't use errs() here because
     // raw ostreams can call report_fatal_error.
     SmallVector<char, 64> Buffer;
-    raw_svector_ostream OS(Buffer);
+    buffered_svector_ostream OS(Buffer);
     OS << "LLVM ERROR: " << Reason << "\n";
     StringRef MessageStr = OS.str();
     ssize_t written = ::write(2, MessageStr.data(), MessageStr.size());
diff --git a/llvm/lib/Support/PrettyStackTrace.cpp b/llvm/lib/Support/PrettyStackTrace.cpp
index 9b09384e95bfed..6fcfbcd549624b 100644
--- a/llvm/lib/Support/PrettyStackTrace.cpp
+++ b/llvm/lib/Support/PrettyStackTrace.cpp
@@ -178,7 +178,7 @@ static void CrashHandler(void *) {
   setCrashLogMessage(crashHandlerString.c_str());
 
   {
-    raw_svector_ostream Stream(crashHandlerString);
+    buffered_svector_ostream Stream(crashHandlerString);
     PrintCurStackTrace(Stream);
   }
 
diff --git a/llvm/lib/Support/Twine.cpp b/llvm/lib/Support/Twine.cpp
index 495b9cf2dbd680..6170fc00b0db8a 100644
--- a/llvm/lib/Support/Twine.cpp
+++ b/llvm/lib/Support/Twine.cpp
@@ -30,7 +30,7 @@ std::string Twine::str() const {
 }
 
 void Twine::toVector(SmallVectorImpl<char> &Out) const {
-  raw_svector_ostream OS(Out);
+  buffered_svector_ostream OS(Out);
   print(OS);
 }
 
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 7ec07044daec96..15f0c7dd9b4ee3 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -369,8 +369,10 @@ raw_ostream &raw_ostream::operator<<(const FormattedNumber &FN) {
     llvm::write_hex(*this, FN.HexValue, Style, FN.Width);
   } else {
     llvm::SmallString<16> Buffer;
-    llvm::raw_svector_ostream Stream(Buffer);
-    llvm::write_integer(Stream, FN.DecValue, 0, IntegerStyle::Integer);
+    {
+      buffered_svector_ostream Stream(Buffer);
+      llvm::write_integer(Stream, FN.DecValue, 0, IntegerStyle::Integer);
+    }
     if (Buffer.size() < FN.Width)
       indent(FN.Width - Buffer.size());
     (*this) << Buffer;
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index 09a6d57afc0ba1..46b17cb7b73176 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -756,7 +756,7 @@ void X86AsmBackend::relaxInstruction(MCInst &Inst,
 
   if (RelaxedOp == Inst.getOpcode()) {
     SmallString<256> Tmp;
-    raw_svector_ostream OS(Tmp);
+    buffered_svector_ostream OS(Tmp);
     Inst.dump_pretty(OS);
     OS << "\n";
     report_fatal_error("unexpected instruction to relax: " + OS.str());
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFTargetStreamer.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFTargetStreamer.cpp
index 19427617a3d3ef..1a37e4b03ff8fc 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFTargetStreamer.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFTargetStreamer.cpp
@@ -317,7 +317,7 @@ void FPOStateMachine::emitFrameDataRecord(MCStreamer &OS, MCSymbol *Label) {
 
   // Compute the new FrameFunc string.
   FrameFunc.clear();
-  raw_svector_ostream FuncOS(FrameFunc);
+  buffered_svector_ostream FuncOS(FrameFunc);
   const MCRegisterInfo *MRI = OS.getContext().getRegisterInfo();
   assert((StackAlign == 0 || FrameReg != 0) &&
          "cannot align stack without frame reg");



More information about the llvm-commits mailing list