[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