[flang-commits] [flang] [llvm] [LLVM-Flang] Improve the realloc size for the write statement (PR #187662)

Thirumalai Shaktivel via flang-commits flang-commits at lists.llvm.org
Sun Mar 22 23:01:22 PDT 2026


https://github.com/Thirumalai-Shaktivel updated https://github.com/llvm/llvm-project/pull/187662

>From fad71c9be7fb5e87ce6890236e597ab9df35327a Mon Sep 17 00:00:00 2001
From: Thirumalai-Shaktivel <thirumalaishaktivel at gmail.com>
Date: Fri, 20 Mar 2026 14:06:34 +0530
Subject: [PATCH 1/3] [LLVM-Flang] Improve the realloc size for the write
 statement

Information:
The "buffer_" is used to store data in memory, and then
 the entire "buffer_" is written at once using the Write(..)
 function. Consider a write statement inside the nested
 implied do loop, the buffer_ size keeps increasing when the
 length exceeds the buffer size. To increase the size, we need
 to reallocate the memory by copying the whole buffer into
 a new memory. This process consumes more time.

Implementation:
By reducing the number of reallocations, the performance
could be improved. Initially, we increase the size linearly,
i.e., +65536 for every new allocation. Then, when we cross
1 MB of buffer size, we increase the size geometrically, i.e.,
2x. Later, for more than 64MB, we do 1.5x.
---
 flang-rt/include/flang-rt/runtime/buffer.h | 14 +++++++++++-
 flang/test/Lower/write01.f90               | 25 ++++++++++++++++++++++
 2 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 flang/test/Lower/write01.f90

diff --git a/flang-rt/include/flang-rt/runtime/buffer.h b/flang-rt/include/flang-rt/runtime/buffer.h
index 3c05e59be25cf..8dc9e2ca89779 100644
--- a/flang-rt/include/flang-rt/runtime/buffer.h
+++ b/flang-rt/include/flang-rt/runtime/buffer.h
@@ -150,7 +150,19 @@ template <typename STORE, std::size_t minBuffer = 65536> class FileFrame {
     if (bytes > size_) {
       char *old{buffer_};
       auto oldSize{size_};
-      size_ = std::max<std::int64_t>(bytes, size_ + minBuffer);
+      std::int64_t newSize{size_ + static_cast<int64_t>(minBuffer)};
+      // Grow the buffer geometrically. Using larger expansion steps reduces the
+      // number of reallocations and prevents excessive mmap/munmap activity.
+      if (newSize > minBuffer * 16) {
+        if (newSize < minBuffer * 1024) {
+          // Between 1 MB and 64 MB -> 2×
+          newSize *= 2;
+        } else {
+          // Above 64 MB -> 1.5×
+          newSize += newSize / 2;
+        }
+      }
+      size_ = std::max<std::int64_t>(bytes, newSize);
       std::int64_t toAllocate{size_};
 #ifdef RT_USE_PSEUDO_FILE_UNIT
       // PseudoOpenFile::Write() needs extra space for a NUL byte.
diff --git a/flang/test/Lower/write01.f90 b/flang/test/Lower/write01.f90
new file mode 100644
index 0000000000000..d53acb7cdaca5
--- /dev/null
+++ b/flang/test/Lower/write01.f90
@@ -0,0 +1,25 @@
+! This test writes a large 4D array to an unformatted file using nested
+! implied DO constructs. The updated lowering aims to produce fewer
+! reallocations as the size increases geometrically when certain
+! threshold is reached
+
+! RUN: %flang -O3 -g %s -o %t && %t | FileCheck %s
+! CHECK: PASS
+
+program test_array_write
+    integer::u,i,j,k
+    real (kind = 8), allocatable, dimension (:,:,:,:):: buf
+    allocate(buf(128, 128, 128, 5))
+    buf = 0
+    open(newunit=u, file = "test_array_write_output.txt", &
+         status="replace", form = "unformatted")
+    write(u) &
+        ((((buf(i,j,k,1)),i=1,127),j=1,127),k=1,127), &
+        ((((buf(i,j,k,2)),i=1,127),j=1,127),k=1,127), &
+        ((((buf(i,j,k,3)),i=1,127),j=1,127),k=1,127), &
+        ((((buf(i,j,k,4)),i=1,127),j=1,127),k=1,127), &
+        ((((buf(i,j,k,5)),i=1,127),j=1,127),k=1,127)
+    print *, "PASS"
+    close(u)
+    deallocate(buf)
+end program test_array_write

>From a07e9ed36ca2a8fae95766c3f2a7103daf25d127 Mon Sep 17 00:00:00 2001
From: Thirumalai-Shaktivel <thirumalaishaktivel at gmail.com>
Date: Fri, 20 Mar 2026 17:13:33 +0530
Subject: [PATCH 2/3] Fix a warning

---
 flang-rt/include/flang-rt/runtime/buffer.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/flang-rt/include/flang-rt/runtime/buffer.h b/flang-rt/include/flang-rt/runtime/buffer.h
index 8dc9e2ca89779..e43e1e4ba831d 100644
--- a/flang-rt/include/flang-rt/runtime/buffer.h
+++ b/flang-rt/include/flang-rt/runtime/buffer.h
@@ -150,11 +150,11 @@ template <typename STORE, std::size_t minBuffer = 65536> class FileFrame {
     if (bytes > size_) {
       char *old{buffer_};
       auto oldSize{size_};
-      std::int64_t newSize{size_ + static_cast<int64_t>(minBuffer)};
+      std::int64_t minBuffer_{minBuffer}, newSize{size_ + minBuffer_};
       // Grow the buffer geometrically. Using larger expansion steps reduces the
       // number of reallocations and prevents excessive mmap/munmap activity.
-      if (newSize > minBuffer * 16) {
-        if (newSize < minBuffer * 1024) {
+      if (newSize > minBuffer_ * 16) {
+        if (newSize < minBuffer_ * 1024) {
           // Between 1 MB and 64 MB -> 2×
           newSize *= 2;
         } else {

>From c2f189fd5d4d4d33a2b42ca16e3733baebe858d4 Mon Sep 17 00:00:00 2001
From: Thirumalai-Shaktivel <thirumalaishaktivel at gmail.com>
Date: Mon, 23 Mar 2026 11:26:38 +0530
Subject: [PATCH 3/3] Move the test to flang-rt

---
 {flang/test/Lower => flang-rt/test/Driver}/write01.f90 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename {flang/test/Lower => flang-rt/test/Driver}/write01.f90 (100%)

diff --git a/flang/test/Lower/write01.f90 b/flang-rt/test/Driver/write01.f90
similarity index 100%
rename from flang/test/Lower/write01.f90
rename to flang-rt/test/Driver/write01.f90



More information about the flang-commits mailing list