]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Clean up slide_hash_c code.
authorHans Kristian Rosbach <hk-git@circlestorm.org>
Tue, 14 Jul 2026 21:16:58 +0000 (23:16 +0200)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Thu, 16 Jul 2026 13:02:16 +0000 (15:02 +0200)
Also remove the original loop that GCC is still struggling to
vectorize at -O2.

arch/generic/slide_hash_c.c

index 0078b1098aef347e8b6ed1a2aafebbd9c1836260..d10b067d04f930fe5f810ab5e66b912cab7a9983 100644 (file)
 #include "deflate.h"
 
 /* ===========================================================================
- * Slide the hash table when sliding the window down (could be avoided with 32
- * bit values at the expense of memory usage). We slide even when level == 0 to
- * keep the hash table consistent if we switch back to level > 0 later.
+ * Slide the hash table when sliding the window down
  */
-static inline void slide_hash_c_chain(Pos *table, uint32_t entries, uint16_t wsize) {
-#ifdef NOT_TWEAK_COMPILER
-    table += entries;
-    do {
-        unsigned m;
-        m = *--table;
-        *table = (Pos)(m >= wsize ? m-wsize : 0);
-        /* If entries is not on any hash chain, prev[entries] is garbage but
-         * its value will never be used.
-         */
-    } while (--entries);
-#else
-    {
-    /* As of I make this change, gcc (4.8.*) isn't able to vectorize
-     * this hot loop using saturated-subtraction on x86-64 architecture.
-     * To avoid this defect, we can change the loop such that
-     *    o. the pointer advance forward, and
-     *    o. demote the variable 'm' to be local to the loop, and
-     *       choose type "Pos" (instead of 'unsigned int') for the
-     *       variable to avoid unnecessary zero-extension.
-     */
-        unsigned int i;
-        Pos *q = table;
-        for (i = 0; i < entries; i++) {
-            Pos m = *q;
-            Pos t = (Pos)wsize;
-            *q++ = (Pos)(m >= t ? m-t: 0);
-        }
+static inline void slide_hash_c_chain(Pos *table, uint32_t entries, Pos wsize) {
+    Pos *q = table;
+    for (uint32_t i = 0; i < entries; i++) {
+        Pos m = *q;
+        *q++ = (m >= wsize) ? m - wsize : 0;
     }
-#endif /* NOT_TWEAK_COMPILER */
+    /* If entries is not on any hash chain, prev[entries] is garbage but
+     * its value will never be used.
+     */
 }
 
 Z_INTERNAL void slide_hash_c(deflate_state *s) {
-    uint16_t wsize = (uint16_t)s->w_size;
+    Pos wsize = (Pos)s->w_size;
 
     slide_hash_c_chain(s->head, HASH_SIZE, wsize);
     slide_hash_c_chain(s->prev, wsize, wsize);