Improve scan codegen

This commit is contained in:
2025-06-20 15:11:29 -04:00
parent 2be21c5453
commit d1523acf94

View File

@@ -285,33 +285,40 @@ struct NumDfa {
} }
// return value either points to the first byte which does not match, or // return value either points to the first byte which does not match, or
// bufEnd. Leaves the dfa in the last state of the match. // 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; auto state_ = state;
for (;;) { for (;;) {
constexpr int kStride = 16; constexpr int kStride = 16;
if (bufEnd - buf < kStride) [[unlikely]] { if (bufEnd - buf < kStride) [[unlikely]] {
while (buf != bufEnd) { while (buf != bufEnd) {
uint64_t row = num_dfa_table[uint8_t(*buf)]; uint64_t row = num_dfa_table[uint8_t(*buf)];
auto next = row >> (state_ & 63); auto prev = state_;
if ((next & 63) == 0) { state_ = (row >> (state_ & 63)) & 63;
if (state_ == 0) {
state_ = prev;
break; break;
} }
state_ = next;
++buf; ++buf;
} }
state = state_; state = state_;
return buf; return buf;
} }
uint8_t prev[kStride + 1];
prev[0] = state_;
for (int i = 0; i < kStride; ++i) { for (int i = 0; i < kStride; ++i) {
uint64_t row = num_dfa_table[uint8_t(*buf)]; uint64_t row = num_dfa_table[uint8_t(*buf)];
auto next = row >> (state_ & 63); prev[i + 1] = row >> (prev[i] & 63);
if ((next & 63) == 0) { if ((prev[i + 1] & 63) == 0) {
state = state_; state = prev[i];
return buf; return buf;
} }
state_ = next;
++buf; ++buf;
} }
state_ = prev[kStride];
} }
} }