| 941 | #endif |
| 942 | |
| 943 | const void* Prog::PrefixAccel_FrontAndBack(const void* data, size_t size) { |
| 944 | DCHECK_GE(prefix_size_, 2); |
| 945 | if (size < prefix_size_) |
| 946 | return NULL; |
| 947 | // Don't bother searching the last prefix_size_-1 bytes for prefix_front_. |
| 948 | // This also means that probing for prefix_back_ doesn't go out of bounds. |
| 949 | size -= prefix_size_-1; |
| 950 | |
| 951 | #if defined(__AVX2__) |
| 952 | // Use AVX2 to look for prefix_front_ and prefix_back_ 32 bytes at a time. |
| 953 | if (size >= sizeof(__m256i)) { |
| 954 | const __m256i* fp = reinterpret_cast<const __m256i*>( |
| 955 | reinterpret_cast<const char*>(data)); |
| 956 | const __m256i* bp = reinterpret_cast<const __m256i*>( |
| 957 | reinterpret_cast<const char*>(data) + prefix_size_-1); |
| 958 | const __m256i* endfp = fp + size/sizeof(__m256i); |
| 959 | const __m256i f_set1 = _mm256_set1_epi8(prefix_front_); |
| 960 | const __m256i b_set1 = _mm256_set1_epi8(prefix_back_); |
| 961 | while (fp != endfp) { |
| 962 | const __m256i f_loadu = _mm256_loadu_si256(fp++); |
| 963 | const __m256i b_loadu = _mm256_loadu_si256(bp++); |
| 964 | const __m256i f_cmpeq = _mm256_cmpeq_epi8(f_set1, f_loadu); |
| 965 | const __m256i b_cmpeq = _mm256_cmpeq_epi8(b_set1, b_loadu); |
| 966 | const int fb_testz = _mm256_testz_si256(f_cmpeq, b_cmpeq); |
| 967 | if (fb_testz == 0) { // ZF: 1 means zero, 0 means non-zero. |
| 968 | const __m256i fb_and = _mm256_and_si256(f_cmpeq, b_cmpeq); |
| 969 | const int fb_movemask = _mm256_movemask_epi8(fb_and); |
| 970 | const int fb_ctz = FindLSBSet(fb_movemask); |
| 971 | return reinterpret_cast<const char*>(fp-1) + fb_ctz; |
| 972 | } |
| 973 | } |
| 974 | data = fp; |
| 975 | size = size%sizeof(__m256i); |
| 976 | } |
| 977 | #endif |
| 978 | |
| 979 | const char* p0 = reinterpret_cast<const char*>(data); |
| 980 | for (const char* p = p0;; p++) { |
| 981 | DCHECK_GE(size, static_cast<size_t>(p-p0)); |
| 982 | p = reinterpret_cast<const char*>(memchr(p, prefix_front_, size - (p-p0))); |
| 983 | if (p == NULL || p[prefix_size_-1] == prefix_back_) |
| 984 | return p; |
| 985 | } |
| 986 | } |
| 987 | |
| 988 | } // namespace re2 |
nothing calls this directly
no test coverage detected