If capturing groups are used, the regex matcher handles something
like `(.*)suffix` by first doing a maximal match of `.*`, trying to
match `suffix` afterward, and then reducing the maximal stop
position one by one until this finally succeeds. This makes the
match quadratic in the length of the line (with large constant factors).
This is particularly problematic because regexes of this form are
ubiquitous in FileCheck (something like `[[VAR:%.*]] = ...` falls
in this category), making FileCheck executions much slower than
they have any right to be.
This implements a very crude optimization that checks if suffix
starts with a fixed character, and steps back to the last occurrence
of that character, instead of stepping back by one character at a
time. This drops FileCheck time on
clang/test/CodeGen/RISCV/rvv-intrinsics/vloxseg_mask.c from
7.3 seconds to 2.7 seconds.
An obvious further improvement would be to check more than one
character (once again, this is particularly relevant for FileCheck,
because the next character is usually a space, which happens to
have many occurrences).
This should help with https://github.com/llvm/llvm-project/issues/54821.
The standard library functions ::isprint/std::isprint have platform-
and locale-dependent behavior which makes LLVM's output less
predictable. In particular, regression tests my fail depending on the
implementation of these functions.
Implement llvm::isPrint in StringExtras.h with a standard behavior and
replace all uses of ::isprint/std::isprint by a call it llvm::isPrint.
The function is inlined and does not look up language settings so it
should perform better than the standard library's version.
Such a replacement has already been done for isdigit, isalpha, isxdigit
in r314883. gtest does the same in gtest-printers.cc using the following
justification:
// Returns true if c is a printable ASCII character. We test the
// value of c directly instead of calling isprint(), which is buggy on
// Windows Mobile.
inline bool IsPrintableAscii(wchar_t c) {
return 0x20 <= c && c <= 0x7E;
}
Similar issues have also been encountered by Julia:
https://github.com/JuliaLang/julia/issues/7416
I noticed the problem myself when on Windows isprint('\t') started to
evaluate to true (see https://stackoverflow.com/questions/51435249) and
thus caused several unit tests to fail. The result of isprint doesn't
seem to be well-defined even for ASCII characters. Therefore I suggest
to replace isprint by a platform-independent version.
Differential Revision: https://reviews.llvm.org/D49680
llvm-svn: 338034