From d1523acf94b886289600c452155191eca6b983f5 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Fri, 20 Jun 2025 15:11:29 -0400 Subject: [PATCH] Improve scan codegen --- src/parser3.h | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/parser3.h b/src/parser3.h index 195892f..d1011cd 100644 --- a/src/parser3.h +++ b/src/parser3.h @@ -285,33 +285,40 @@ struct NumDfa { } // return value either points to the first byte which does not match, or // bufEnd. Leaves the dfa in the last state of the match. - const char *scan(const char *buf, const char *bufEnd) { +#ifdef __x86_64__ + __attribute__((target_clones("default", "bmi2"))) +#endif + const char * + scan(const char *buf, const char *bufEnd) { auto state_ = state; for (;;) { constexpr int kStride = 16; if (bufEnd - buf < kStride) [[unlikely]] { while (buf != bufEnd) { uint64_t row = num_dfa_table[uint8_t(*buf)]; - auto next = row >> (state_ & 63); - if ((next & 63) == 0) { + auto prev = state_; + state_ = (row >> (state_ & 63)) & 63; + if (state_ == 0) { + state_ = prev; break; } - state_ = next; ++buf; } state = state_; return buf; } + uint8_t prev[kStride + 1]; + prev[0] = state_; for (int i = 0; i < kStride; ++i) { uint64_t row = num_dfa_table[uint8_t(*buf)]; - auto next = row >> (state_ & 63); - if ((next & 63) == 0) { - state = state_; + prev[i + 1] = row >> (prev[i] & 63); + if ((prev[i + 1] & 63) == 0) { + state = prev[i]; return buf; } - state_ = next; ++buf; } + state_ = prev[kStride]; } }