[llvm] [flang][runtime] Use dumber but faster check for list-directed repeti… (PR #159867)
Peter Klausler via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 22 09:13:46 PDT 2025
https://github.com/klausler updated https://github.com/llvm/llvm-project/pull/159867
>From 1a0d63eb0270b770203ade0551a4df69d42ece4a Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Fri, 19 Sep 2025 15:51:13 -0700
Subject: [PATCH] [flang][runtime] Use dumber but faster check for
list-directed repetition
When scanning list-directed input for nulls and repetition counts,
the current library depends on having each record be prescanned for
the presence of asterisk characters. It turns out that the overhead
of calling memchr(...,'*',...) on each record doesn't pay off, especially
on systems without SIMD-vectorized memchr implementations -- even on those,
it's faster (about 10%) to just scan ahead for asterisks when decimal
digits are encountered. Only when an asterisk is present, which is
not common, should we then bother to convert the digits to their integer
value.
---
flang-rt/include/flang-rt/runtime/io-stmt.h | 26 +++++++++++++--------
flang-rt/lib/runtime/io-stmt.cpp | 4 ++--
2 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/flang-rt/include/flang-rt/runtime/io-stmt.h b/flang-rt/include/flang-rt/runtime/io-stmt.h
index 03b6efd65ddfc..1c4f06c0a7082 100644
--- a/flang-rt/include/flang-rt/runtime/io-stmt.h
+++ b/flang-rt/include/flang-rt/runtime/io-stmt.h
@@ -149,9 +149,7 @@ class IoStatementState {
: connection_{connection} {}
RT_API_ATTRS FastAsciiField(
ConnectionState &connection, const char *start, std::size_t bytes)
- : connection_{connection}, at_{start}, limit_{start + bytes} {
- CheckForAsterisk();
- }
+ : connection_{connection}, at_{start}, limit_{start + bytes} {}
RT_API_ATTRS ConnectionState &connection() { return connection_; }
RT_API_ATTRS std::size_t got() const { return got_; }
@@ -168,7 +166,6 @@ class IoStatementState {
if (at_) {
if (std::size_t bytes{io.GetNextInputBytes(at_)}) {
limit_ = at_ + bytes;
- CheckForAsterisk();
} else {
at_ = limit_ = nullptr;
}
@@ -181,19 +178,28 @@ class IoStatementState {
}
connection_.HandleRelativePosition(bytes);
}
- RT_API_ATTRS bool MightHaveAsterisk() const { return !at_ || hasAsterisk_; }
- private:
- RT_API_ATTRS void CheckForAsterisk() {
- hasAsterisk_ = at_ && at_ < limit_ &&
- runtime::memchr(at_, '*', limit_ - at_) != nullptr;
+ // Could there be a list-directed repetition count here?
+ RT_API_ATTRS bool MightBeRepetitionCount() const {
+ if (!at_) {
+ return true; // must use slow path for internal KIND/=1 input
+ } else {
+ if (const char *p{at_}; *p >= '0' && *p <= '9') {
+ while (++p < limit_) {
+ if (*p < '0' || *p > '9') {
+ return *p == '*';
+ }
+ }
+ }
+ return false;
+ }
}
+ private:
ConnectionState &connection_;
const char *at_{nullptr};
const char *limit_{nullptr};
std::size_t got_{0}; // for READ(..., SIZE=)
- bool hasAsterisk_{false};
};
RT_API_ATTRS FastAsciiField GetUpcomingFastAsciiField();
diff --git a/flang-rt/lib/runtime/io-stmt.cpp b/flang-rt/lib/runtime/io-stmt.cpp
index e260c0ca7511d..7bcba5fe71ee4 100644
--- a/flang-rt/lib/runtime/io-stmt.cpp
+++ b/flang-rt/lib/runtime/io-stmt.cpp
@@ -905,8 +905,8 @@ ListDirectedStatementState<Direction::Input>::GetNextDataEdit(
if (imaginaryPart_) { // can't repeat components
return edit;
}
- if (*ch >= '0' && *ch <= '9' && fastField.MightHaveAsterisk()) {
- // look for "r*" repetition count
+ if (*ch >= '0' && *ch <= '9' && fastField.MightBeRepetitionCount()) {
+ // There's decimal digits followed by '*'.
auto start{fastField.connection().positionInRecord};
int r{0};
do {
More information about the llvm-commits
mailing list