[Mlir-commits] [mlir] [mlir] Reduce Diagnostic storage across standard library debug modes (PR #226070)

Mehdi Amini llvmlistbot at llvm.org
Thu Sep 24 01:30:27 PDT 2026


https://github.com/joker-eph created https://github.com/llvm/llvm-project/pull/226070

The multi-part diagnostic support added a SmallVector of part boundaries to Diagnostic. With libstdc++'s _GLIBCXX_DEBUG enabled, the two std::vector members also grow substantially: sizeof(Diagnostic) reaches 288 bytes. This exceeds the 256-byte limit for default SmallVector<Diagnostic> and breaks Transform dialect builds that use that type.

Use zero-inline SmallVectors for the owned string buffers and attached notes. Both collections already allocated when populated, while their empty representation no longer grows under _GLIBCXX_DEBUG. Give the part-boundary vector zero inline elements as well: ordinary diagnostics have a single part and never populate it. Keep the four inline argument slots, so common diagnostic assembly retains its existing allocation behavior. Splitting a diagnostic now allocates boundary storage.

On this 64-bit checkout, sizeof(Diagnostic) falls from 224 to 192 bytes normally and from 288 to 192 bytes with _GLIBCXX_DEBUG.

Assisted-by: Codex

>From 624089c55e92ff318e77a5c697dcda64616163fc Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Thu, 24 Sep 2026 01:27:06 -0700
Subject: [PATCH] [mlir] Reduce Diagnostic storage across standard library
 debug modes

The multi-part diagnostic support added a SmallVector of part boundaries to
Diagnostic. With libstdc++'s _GLIBCXX_DEBUG enabled, the two std::vector
members also grow substantially: sizeof(Diagnostic) reaches 288 bytes.
This exceeds the 256-byte limit for default SmallVector<Diagnostic> and
breaks Transform dialect builds that use that type.

Use zero-inline SmallVectors for the owned string buffers and attached
notes. Both collections already allocated when populated, while their
empty representation no longer grows under _GLIBCXX_DEBUG. Give the
part-boundary vector zero inline elements as well: ordinary diagnostics
have a single part and never populate it. Keep the four inline argument
slots, so common diagnostic assembly retains its existing allocation
behavior. Splitting a diagnostic now allocates boundary storage.

On this 64-bit checkout, sizeof(Diagnostic) falls from 224 to 192 bytes
normally and from 288 to 192 bytes with _GLIBCXX_DEBUG.

Verified the affected IR and diagnostic unit-test sources compile in the
configured build. Also compiled Diagnostics.cpp and the previously failing
SmallVector<Diagnostic> declaration with _GLIBCXX_DEBUG, and checked the
diff with git diff --check.

Assisted-by: Codex
---
 mlir/include/mlir/IR/Diagnostics.h | 7 ++++---
 mlir/lib/IR/Diagnostics.cpp        | 5 +++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/mlir/include/mlir/IR/Diagnostics.h b/mlir/include/mlir/IR/Diagnostics.h
index aae14b3d6e9ec..276bfd60f0a28 100644
--- a/mlir/include/mlir/IR/Diagnostics.h
+++ b/mlir/include/mlir/IR/Diagnostics.h
@@ -157,7 +157,7 @@ inline raw_ostream &operator<<(raw_ostream &os, const DiagnosticArgument &arg) {
 /// A diagnostic may contain multiple message parts that share its location,
 /// severity, metadata, and attached notes. Empty message parts are ignored.
 class Diagnostic {
-  using NoteVector = std::vector<std::unique_ptr<Diagnostic>>;
+  using NoteVector = SmallVector<std::unique_ptr<Diagnostic>, 0>;
 
 public:
   Diagnostic(Location loc, DiagnosticSeverity severity)
@@ -318,10 +318,11 @@ class Diagnostic {
 
   /// A list of string values used as arguments. This is used to guarantee the
   /// liveness of non-constant strings used in diagnostics.
-  std::vector<std::unique_ptr<char[]>> strings;
+  SmallVector<std::unique_ptr<char[]>, 0> strings;
 
   /// The exclusive end indices in `arguments` of completed message parts.
-  SmallVector<size_t, 2> messagePartEnds;
+  /// Most diagnostics have only one part, so avoid reserving inline storage.
+  SmallVector<size_t, 0> messagePartEnds;
 
   /// A list of attached notes.
   NoteVector notes;
diff --git a/mlir/lib/IR/Diagnostics.cpp b/mlir/lib/IR/Diagnostics.cpp
index ad93a9b1606fc..0dae9e4c90cf7 100644
--- a/mlir/lib/IR/Diagnostics.cpp
+++ b/mlir/lib/IR/Diagnostics.cpp
@@ -84,8 +84,9 @@ void DiagnosticArgument::print(raw_ostream &os) const {
 
 /// Convert a Twine to a StringRef. Memory used for generating the StringRef is
 /// stored in 'strings'.
-static StringRef twineToStrRef(const Twine &val,
-                               std::vector<std::unique_ptr<char[]>> &strings) {
+static StringRef
+twineToStrRef(const Twine &val,
+              SmallVectorImpl<std::unique_ptr<char[]>> &strings) {
   // Allocate memory to hold this string.
   SmallString<64> data;
   auto strRef = val.toStringRef(data);



More information about the Mlir-commits mailing list