[flang-rt] Simplify INDEX with len-1 SUBSTRING. (#137889)

The len-1 case is noticeably slower than gfortran's straightforward
implementation
075611b646/libgfortran/intrinsics/string_intrinsics_inc.c (L253)
This change speeds up a simple microkernel by 37% on icelake.
This commit is contained in:
Slava Zakharin
2025-04-30 08:25:06 -07:00
committed by GitHub
parent c26db586a0
commit a8607063f3
2 changed files with 20 additions and 0 deletions

View File

@@ -14,6 +14,7 @@
#include "flang/Common/uint128.h"
#include "flang/Runtime/character.h"
#include "flang/Runtime/cpp-type.h"
#include "flang/Runtime/freestanding-tools.h"
#include <algorithm>
#include <cstring>
@@ -293,6 +294,24 @@ inline RT_API_ATTRS std::size_t Index(const CHAR *x, std::size_t xLen,
}
return 0;
}
if (wantLen == 1) {
// Trivial case for single character lookup.
// We can use simple forward search.
CHAR ch{want[0]};
if constexpr (std::is_same_v<CHAR, char>) {
if (auto pos{reinterpret_cast<const CHAR *>(
Fortran::runtime::memchr(x, ch, xLen))}) {
return pos - x + 1;
}
} else {
for (std::size_t at{0}; at < xLen; ++at) {
if (x[at] == ch) {
return at + 1;
}
}
}
return 0;
}
// Non-trivial forward substring search: use a simplified form of
// Boyer-Moore substring searching.
for (std::size_t at{1}; at + wantLen - 1 <= xLen;) {

View File

@@ -354,6 +354,7 @@ TYPED_TEST(SearchTests, IndexTests) {
{"", "a", true, 0},
{"aa", "a", false, 1},
{"aa", "a", true, 2},
{"aAA", "A", false, 2},
{"Fortran that I ran", "that I ran", false, 9},
{"Fortran that I ran", "that I ran", true, 9},
{"Fortran that you ran", "that I ran", false, 0},