Skip to content

Commit a860706

Browse files
authored
[flang-rt] Simplify INDEX with len-1 SUBSTRING. (#137889)
The len-1 case is noticeably slower than gfortran's straightforward implementation https://github.com/gcc-mirror/gcc/blob/075611b646e5554ae02b2622061ea1614bf16ead/libgfortran/intrinsics/string_intrinsics_inc.c#L253 This change speeds up a simple microkernel by 37% on icelake.
1 parent c26db58 commit a860706

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

flang-rt/lib/runtime/character.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "flang/Common/uint128.h"
1515
#include "flang/Runtime/character.h"
1616
#include "flang/Runtime/cpp-type.h"
17+
#include "flang/Runtime/freestanding-tools.h"
1718
#include <algorithm>
1819
#include <cstring>
1920

@@ -293,6 +294,24 @@ inline RT_API_ATTRS std::size_t Index(const CHAR *x, std::size_t xLen,
293294
}
294295
return 0;
295296
}
297+
if (wantLen == 1) {
298+
// Trivial case for single character lookup.
299+
// We can use simple forward search.
300+
CHAR ch{want[0]};
301+
if constexpr (std::is_same_v<CHAR, char>) {
302+
if (auto pos{reinterpret_cast<const CHAR *>(
303+
Fortran::runtime::memchr(x, ch, xLen))}) {
304+
return pos - x + 1;
305+
}
306+
} else {
307+
for (std::size_t at{0}; at < xLen; ++at) {
308+
if (x[at] == ch) {
309+
return at + 1;
310+
}
311+
}
312+
}
313+
return 0;
314+
}
296315
// Non-trivial forward substring search: use a simplified form of
297316
// Boyer-Moore substring searching.
298317
for (std::size_t at{1}; at + wantLen - 1 <= xLen;) {

flang-rt/unittests/Runtime/CharacterTest.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ TYPED_TEST(SearchTests, IndexTests) {
354354
{"", "a", true, 0},
355355
{"aa", "a", false, 1},
356356
{"aa", "a", true, 2},
357+
{"aAA", "A", false, 2},
357358
{"Fortran that I ran", "that I ran", false, 9},
358359
{"Fortran that I ran", "that I ran", true, 9},
359360
{"Fortran that you ran", "that I ran", false, 0},

0 commit comments

Comments
 (0)