]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Convert Outer Control Structure to Loop 2774/head
authorW. Felix Handte <w@felixhandte.com>
Mon, 11 Oct 2021 19:57:29 +0000 (15:57 -0400)
committerW. Felix Handte <w@felixhandte.com>
Tue, 12 Oct 2021 17:34:17 +0000 (13:34 -0400)
lib/compress/zstd_double_fast.c

index db95fe634a406830f8e5410d5c7bed2bd02367c6..9d19468cbaf24ceff21dad26fce545d47dace310 100644 (file)
@@ -104,152 +104,152 @@ size_t ZSTD_compressBlock_doubleFast_noDict_generic(
         if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
     }
 
-_start:
-
-    step = 1;
-    nextStep = ip + kStepIncr;
-    ip1 = ip + step;
-
-    if (ip1 > ilimit) {
-        goto _cleanup;
-    }
-
-    hl0 = ZSTD_hashPtr(ip, hBitsL, 8);
-    idxl0 = hashLong[hl0];
-    matchl0 = base + idxl0;
-
-    /* Main Search Loop */
-    do {
-        const size_t hs0 = ZSTD_hashPtr(ip, hBitsS, mls);
-        const U32 idxs0 = hashSmall[hs0];
-        curr = (U32)(ip-base);
-        matchs0 = base + idxs0;
-
-        hashLong[hl0] = hashSmall[hs0] = curr;   /* update hash tables */
-
-        /* check noDict repcode */
-        if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
-            mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
-            ip++;
-            ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH);
-            goto _match_stored;
+    /* Outer Loop: one iteration per match found and stored */
+    while (1) {
+        step = 1;
+        nextStep = ip + kStepIncr;
+        ip1 = ip + step;
+
+        if (ip1 > ilimit) {
+            goto _cleanup;
         }
 
-        hl1 = ZSTD_hashPtr(ip1, hBitsL, 8);
+        hl0 = ZSTD_hashPtr(ip, hBitsL, 8);
+        idxl0 = hashLong[hl0];
+        matchl0 = base + idxl0;
+
+        /* Inner Loop: one iteration per search / position */
+        do {
+            const size_t hs0 = ZSTD_hashPtr(ip, hBitsS, mls);
+            const U32 idxs0 = hashSmall[hs0];
+            curr = (U32)(ip-base);
+            matchs0 = base + idxs0;
+
+            hashLong[hl0] = hashSmall[hs0] = curr;   /* update hash tables */
+
+            /* check noDict repcode */
+            if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
+                mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
+                ip++;
+                ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH);
+                goto _match_stored;
+            }
+
+            hl1 = ZSTD_hashPtr(ip1, hBitsL, 8);
 
-        if (idxl0 > prefixLowestIndex) {
-            /* check prefix long match */
-            if (MEM_read64(matchl0) == MEM_read64(ip)) {
-                mLength = ZSTD_count(ip+8, matchl0+8, iend) + 8;
-                offset = (U32)(ip-matchl0);
-                while (((ip>anchor) & (matchl0>prefixLowest)) && (ip[-1] == matchl0[-1])) { ip--; matchl0--; mLength++; } /* catch up */
-                goto _match_found;
+            if (idxl0 > prefixLowestIndex) {
+                /* check prefix long match */
+                if (MEM_read64(matchl0) == MEM_read64(ip)) {
+                    mLength = ZSTD_count(ip+8, matchl0+8, iend) + 8;
+                    offset = (U32)(ip-matchl0);
+                    while (((ip>anchor) & (matchl0>prefixLowest)) && (ip[-1] == matchl0[-1])) { ip--; matchl0--; mLength++; } /* catch up */
+                    goto _match_found;
+                }
             }
-        }
 
-        idxl1 = hashLong[hl1];
-        matchl1 = base + idxl1;
+            idxl1 = hashLong[hl1];
+            matchl1 = base + idxl1;
 
-        if (idxs0 > prefixLowestIndex) {
-            /* check prefix short match */
-            if (MEM_read32(matchs0) == MEM_read32(ip)) {
-                goto _search_next_long;
+            if (idxs0 > prefixLowestIndex) {
+                /* check prefix short match */
+                if (MEM_read32(matchs0) == MEM_read32(ip)) {
+                    goto _search_next_long;
+                }
             }
-        }
 
-        if (ip1 >= nextStep) {
-            PREFETCH_L1(ip1 + 64);
-            PREFETCH_L1(ip1 + 128);
-            step++;
-            nextStep += kStepIncr;
-        }
-        ip = ip1;
-        ip1 += step;
+            if (ip1 >= nextStep) {
+                PREFETCH_L1(ip1 + 64);
+                PREFETCH_L1(ip1 + 128);
+                step++;
+                nextStep += kStepIncr;
+            }
+            ip = ip1;
+            ip1 += step;
 
-        hl0 = hl1;
-        idxl0 = idxl1;
-        matchl0 = matchl1;
-#if defined(__aarch64__)
-        PREFETCH_L1(ip+256);
-#endif
-    } while (ip1 <= ilimit);
+            hl0 = hl1;
+            idxl0 = idxl1;
+            matchl0 = matchl1;
+    #if defined(__aarch64__)
+            PREFETCH_L1(ip+256);
+    #endif
+        } while (ip1 <= ilimit);
 
 _cleanup:
-    /* save reps for next block */
-    rep[0] = offset_1 ? offset_1 : offsetSaved;
-    rep[1] = offset_2 ? offset_2 : offsetSaved;
+        /* save reps for next block */
+        rep[0] = offset_1 ? offset_1 : offsetSaved;
+        rep[1] = offset_2 ? offset_2 : offsetSaved;
 
-    /* Return the last literals size */
-    return (size_t)(iend - anchor);
+        /* Return the last literals size */
+        return (size_t)(iend - anchor);
 
 _search_next_long:
 
-    /* check prefix long +1 match */
-    if (idxl1 > prefixLowestIndex) {
-        if (MEM_read64(matchl1) == MEM_read64(ip1)) {
-            ip = ip1;
-            mLength = ZSTD_count(ip+8, matchl1+8, iend) + 8;
-            offset = (U32)(ip-matchl1);
-            while (((ip>anchor) & (matchl1>prefixLowest)) && (ip[-1] == matchl1[-1])) { ip--; matchl1--; mLength++; } /* catch up */
-            goto _match_found;
+        /* check prefix long +1 match */
+        if (idxl1 > prefixLowestIndex) {
+            if (MEM_read64(matchl1) == MEM_read64(ip1)) {
+                ip = ip1;
+                mLength = ZSTD_count(ip+8, matchl1+8, iend) + 8;
+                offset = (U32)(ip-matchl1);
+                while (((ip>anchor) & (matchl1>prefixLowest)) && (ip[-1] == matchl1[-1])) { ip--; matchl1--; mLength++; } /* catch up */
+                goto _match_found;
+            }
         }
-    }
 
-    /* if no long +1 match, explore the short match we found */
-    mLength = ZSTD_count(ip+4, matchs0+4, iend) + 4;
-    offset = (U32)(ip - matchs0);
-    while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* catch up */
+        /* if no long +1 match, explore the short match we found */
+        mLength = ZSTD_count(ip+4, matchs0+4, iend) + 4;
+        offset = (U32)(ip - matchs0);
+        while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* catch up */
 
-    /* fall-through */
+        /* fall-through */
 
 _match_found: /* requires ip, offset, mLength */
-    offset_2 = offset_1;
-    offset_1 = offset;
-
-    if (step < 4) {
-        /* It is unsafe to write this value back to the hashtable when ip1 is
-         * greater than or equal to the new ip we will have after we're done
-         * processing this match. Rather than perform that test directly
-         * (ip1 >= ip + mLength), which costs speed in practice, we do a simpler
-         * more predictable test. The minmatch even if we take a short match is
-         * 4 bytes, so as long as step, the distance between ip and ip1
-         * (initially) is less than 4, we know ip1 < new ip. */
-        hashLong[hl1] = (U32)(ip1 - base);
-    }
+        offset_2 = offset_1;
+        offset_1 = offset;
+
+        if (step < 4) {
+            /* It is unsafe to write this value back to the hashtable when ip1 is
+             * greater than or equal to the new ip we will have after we're done
+             * processing this match. Rather than perform that test directly
+             * (ip1 >= ip + mLength), which costs speed in practice, we do a simpler
+             * more predictable test. The minmatch even if we take a short match is
+             * 4 bytes, so as long as step, the distance between ip and ip1
+             * (initially) is less than 4, we know ip1 < new ip. */
+            hashLong[hl1] = (U32)(ip1 - base);
+        }
 
-    ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+        ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
 
 _match_stored:
-    /* match found */
-    ip += mLength;
-    anchor = ip;
-
-    if (ip <= ilimit) {
-        /* Complementary insertion */
-        /* done after iLimit test, as candidates could be > iend-8 */
-        {   U32 const indexToInsert = curr+2;
-            hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;
-            hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
-            hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;
-            hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base);
-        }
+        /* match found */
+        ip += mLength;
+        anchor = ip;
 
-        /* check immediate repcode */
-        while ( (ip <= ilimit)
-             && ( (offset_2>0)
-                & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
-            /* store sequence */
-            size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
-            U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff;  /* swap offset_2 <=> offset_1 */
-            hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
-            hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
-            ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, rLength-MINMATCH);
-            ip += rLength;
-            anchor = ip;
-            continue;   /* faster when present ... (?) */
-    }   }
+        if (ip <= ilimit) {
+            /* Complementary insertion */
+            /* done after iLimit test, as candidates could be > iend-8 */
+            {   U32 const indexToInsert = curr+2;
+                hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;
+                hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
+                hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;
+                hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base);
+            }
 
-    goto _start;
+            /* check immediate repcode */
+            while ( (ip <= ilimit)
+                 && ( (offset_2>0)
+                    & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
+                /* store sequence */
+                size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
+                U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff;  /* swap offset_2 <=> offset_1 */
+                hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
+                hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
+                ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, rLength-MINMATCH);
+                ip += rLength;
+                anchor = ip;
+                continue;   /* faster when present ... (?) */
+            }
+        }
+    }
 }