diff options
Diffstat (limited to 'include/coverage-64.h')
-rw-r--r-- | include/coverage-64.h | 91 |
1 files changed, 60 insertions, 31 deletions
diff --git a/include/coverage-64.h b/include/coverage-64.h index aab79d79..a094531b 100644 --- a/include/coverage-64.h +++ b/include/coverage-64.h @@ -5,7 +5,8 @@ #include <immintrin.h> #endif -u32 skim(const u64 *virgin, const u64 *current, const u64 *current_end); +u32 skim(const u64* const* virgins, size_t num, + const u64 *current, const u64 *current_end); u64 classify_word(u64 word); inline u64 classify_word(u64 word) { @@ -74,6 +75,9 @@ inline void classify_counts(afl_forkserver_t *fsrv) { /* Updates the virgin bits, then reflects whether a new count or a new tuple is * seen in ret. */ + +/* Updates the virgin bits, then reflects whether a new count or a new tuple is + * seen in ret. */ inline void discover_word(u8 *ret, u64 *current, u64 *virgin) { /* Optimize for (*current & *virgin) == 0 - i.e., no bits in current bitmap @@ -108,9 +112,11 @@ inline void discover_word(u8 *ret, u64 *current, u64 *virgin) { #if defined(__AVX512F__) && defined(__AVX512DQ__) #define PACK_SIZE 64 -inline u32 skim(const u64 *virgin, const u64 *current, const u64 *current_end) { +inline u32 skim(const u64* const* virgins, size_t num, + const u64 *current, const u64 *current_end) { - for (; current != current_end; virgin += 8, current += 8) { + size_t idx = 0; + for (; current < current_end; idx += 8, current += 8) { __m512i value = *(__m512i *)current; __mmask8 mask = _mm512_testn_epi64_mask(value, value); @@ -118,18 +124,24 @@ inline u32 skim(const u64 *virgin, const u64 *current, const u64 *current_end) { /* All bytes are zero. */ if (likely(mask == 0xff)) continue; - /* Look for nonzero bytes and check for new bits. */ #define UNROLL(x) \ - if (unlikely(!(mask & (1 << x)) && classify_word(current[x]) & virgin[x])) \ - return 1 - UNROLL(0); - UNROLL(1); - UNROLL(2); - UNROLL(3); - UNROLL(4); - UNROLL(5); - UNROLL(6); - UNROLL(7); + if (unlikely(!(mask & (1 << x)))) { \ + u64 classified = classify_word(current[x]); \ + for (size_t i = 0; i < num; ++i) { \ + if (classified & virgins[i][idx + x]) \ + return 1; \ + } \ + } + + UNROLL(0) + UNROLL(1) + UNROLL(2) + UNROLL(3) + UNROLL(4) + UNROLL(5) + UNROLL(6) + UNROLL(7) + #undef UNROLL } @@ -142,11 +154,13 @@ inline u32 skim(const u64 *virgin, const u64 *current, const u64 *current_end) { #if !defined(PACK_SIZE) && defined(__AVX2__) #define PACK_SIZE 32 -inline u32 skim(const u64 *virgin, const u64 *current, const u64 *current_end) { +inline u32 skim(const u64* const* virgins, size_t num, + const u64 *current, const u64 *current_end) { __m256i zeroes = _mm256_setzero_si256(); - for (; current < current_end; virgin += 4, current += 4) { + size_t idx = 0; + for (; current < current_end; idx += 4, current += 4) { __m256i value = *(__m256i *)current; __m256i cmp = _mm256_cmpeq_epi64(value, zeroes); @@ -156,14 +170,18 @@ inline u32 skim(const u64 *virgin, const u64 *current, const u64 *current_end) { if (likely(mask == (u32)-1)) continue; /* Look for nonzero bytes and check for new bits. */ - if (unlikely(!(mask & 0xff) && classify_word(current[0]) & virgin[0])) - return 1; - if (unlikely(!(mask & 0xff00) && classify_word(current[1]) & virgin[1])) - return 1; - if (unlikely(!(mask & 0xff0000) && classify_word(current[2]) & virgin[2])) - return 1; - if (unlikely(!(mask & 0xff000000) && classify_word(current[3]) & virgin[3])) - return 1; + #define UNROLL(j) \ + if (unlikely(!(mask & (0xff << (j * 8))))) { \ + u64 classified = classify_word(current[j]); \ + for (size_t i = 0; i < num; ++i) \ + if (classified & virgins[i][idx + j]) \ + return 1; \ + } + UNROLL(0) + UNROLL(1) + UNROLL(2) + UNROLL(3) + #undef UNROLL } @@ -175,15 +193,26 @@ inline u32 skim(const u64 *virgin, const u64 *current, const u64 *current_end) { #if !defined(PACK_SIZE) #define PACK_SIZE 32 -inline u32 skim(const u64 *virgin, const u64 *current, const u64 *current_end) { - - for (; current < current_end; virgin += 4, current += 4) { +inline u32 skim(const u64* const* virgins, size_t num, + const u64 *current, const u64 *current_end) { + + size_t idx = 0; + for (; current < current_end; idx += 4, current += 4) { + + #define UNROLL(j) \ + if (unlikely(current[j])) { \ + u64 classified = classify_word(current[j]); \ + for (size_t i = 0; i < num; ++i) \ + if (classified & virgins[i][idx + j]) \ + return 1; \ + } - if (unlikely(current[0] && classify_word(current[0]) & virgin[0])) return 1; - if (unlikely(current[1] && classify_word(current[1]) & virgin[1])) return 1; - if (unlikely(current[2] && classify_word(current[2]) & virgin[2])) return 1; - if (unlikely(current[3] && classify_word(current[3]) & virgin[3])) return 1; + UNROLL(0) + UNROLL(1) + UNROLL(2) + UNROLL(3) + #undef UNROLL } return 0; |