From bc25a5694c6e18e6738cf629d0522b29aadfeab6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 9 Dec 2019 22:35:02 -0600 Subject: [PATCH] [simd] Enable ksearch for (non-range) GlyphID search --- src/hb-array.hh | 44 +++++++++++++++++++++++++++++++++++++++++++- src/hb-simd.hh | 30 +++++++++++++++++++++++++----- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index 278befb85..a47f9d35e 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -347,7 +347,49 @@ struct hb_sorted_array_t : } #ifndef HB_NO_SIMD template , OT::RangeRecord))> + hb_enable_if (hb_is_same (hb_decay, OT::HBGlyphID))> + bool bsearch_impl (hb_codepoint_t x, unsigned *pos, hb_priority<1>) const + { +#ifdef HB_SIMD_VERIFY + unsigned p0; + bool f0 = hb_bsearch_impl (&p0, + x, + this->arrayZ, + this->length, + sizeof (Type), + _hb_cmp_method); + unsigned p1; + bool f1 = hb_simd_ksearch_glyphid (&p1, + x, + this->arrayZ, + this->length, + sizeof (Type)); + if (f0 != f1 || p0 != p1) + { + fprintf (stderr, "FAILED: Searching for %d; expected %d @ %d; got %d @ %d\n", + x, f0, p0, f1, p1); + for (unsigned i = 0; i < this->length; i++) + printf ("Glyph %d: %d\n", i, + (unsigned) this->arrayZ[i]); + } +#endif +#if 0 + if (likely (this->length < 81)) + return hb_bsearch_impl (pos, + x, + this->arrayZ, + this->length, + sizeof (Type), + _hb_cmp_method); +#endif + return hb_simd_ksearch_glyphid (pos, + x, + this->arrayZ, + this->length, + sizeof (Type)); + } + template , OT::RangeRecord) && false)> bool bsearch_impl (hb_codepoint_t x, unsigned *pos, hb_priority<1>) const { #ifdef HB_SIMD_VERIFY diff --git a/src/hb-simd.hh b/src/hb-simd.hh index b3bf46079..1a2874406 100644 --- a/src/hb-simd.hh +++ b/src/hb-simd.hh @@ -201,12 +201,14 @@ /* TODO: Test -mvzeroupper. */ + +template static inline bool -hb_simd_ksearch_glyphid_range (unsigned *pos, /* Out */ - hb_codepoint_t k, - const void *base, - size_t length, - size_t stride) +hb_simd_ksearch_glyphid (unsigned *pos, /* Out */ + hb_codepoint_t k, + const void *base, + size_t length, + size_t stride) { if (unlikely (k & ~0xFFFF)) { @@ -259,6 +261,14 @@ hb_simd_ksearch_glyphid_range (unsigned *pos, /* Out */ 0x0607,0x0405,0x0203,0x0001); V = _mm256_shuffle_epi8 (V, bswap16_shuffle); #endif + if (!is_range) + { + static const __m256i dup_shuffle = _mm256_set_epi16 (0x0D0C,0x0D0C,0x0908,0x0908, + 0x0504,0x0504,0x0100,0x0100, + 0x0D0C,0x0D0C,0x0908,0x0908, + 0x0504,0x0504,0x0100,0x0100); + V = _mm256_shuffle_epi8 (V, dup_shuffle); + } V = _mm256_add_epi16 (V, __32768x16); /* Compare and locate. */ @@ -278,6 +288,16 @@ hb_simd_ksearch_glyphid_range (unsigned *pos, /* Out */ return false; } +static inline bool +hb_simd_ksearch_glyphid_range (unsigned *pos, /* Out */ + hb_codepoint_t k, + const void *base, + size_t length, + size_t stride) +{ + return hb_simd_ksearch_glyphid (pos, k, base, length, stride); +} + #elif !defined(HB_NO_SIMD) #define HB_NO_SIMD