]> git.ipfire.org Git - thirdparty/xz.git/commitdiff
liblzma: Optimize literal_subcoder() macro slightly.
authorLasse Collin <lasse.collin@tukaani.org>
Mon, 12 Feb 2024 15:09:10 +0000 (17:09 +0200)
committerLasse Collin <lasse.collin@tukaani.org>
Wed, 14 Feb 2024 16:31:16 +0000 (18:31 +0200)
src/liblzma/lzma/lzma_common.h
src/liblzma/lzma/lzma_decoder.c
src/liblzma/lzma/lzma_encoder.c
src/liblzma/lzma/lzma_encoder_optimum_normal.c
src/liblzma/lzma/lzma_encoder_private.h

index d46b8502b2d1e7376596bb9c84d3e5189b3ac2b5..c3c587f090ecb9228a2e84fd45b04833d29edd6f 100644 (file)
@@ -125,31 +125,33 @@ typedef enum {
 ///
 /// Match byte is used when the previous LZMA symbol was something else than
 /// a literal (that is, it was some kind of match).
-#define LITERAL_CODER_SIZE 0x300
+#define LITERAL_CODER_SIZE UINT32_C(0x300)
 
 /// Maximum number of literal coders
 #define LITERAL_CODERS_MAX (1 << LZMA_LCLP_MAX)
 
+/// Calculates the literal_mask that literal_subcoder() needs.
+#define literal_mask_calc(lc, lp) \
+       ((UINT32_C(0x100) << (lp)) - (UINT32_C(0x100) >> (lc)))
+
 /// Locate the literal coder for the next literal byte. The choice depends on
 ///   - the lowest literal_pos_bits bits of the position of the current
 ///     byte; and
 ///   - the highest literal_context_bits bits of the previous byte.
-#define literal_subcoder(probs, lc, lp_mask, pos, prev_byte) \
-       ((probs)[(((pos) & (lp_mask)) << (lc)) \
-                       + ((uint32_t)(prev_byte) >> (8U - (lc)))])
+#define literal_subcoder(probs, lc, literal_mask, pos, prev_byte) \
+       ((probs) + UINT32_C(3) * \
+               (((((pos) << 8) + (prev_byte)) & (literal_mask)) << (lc)))
 
 
 static inline void
-literal_init(probability (*probs)[LITERAL_CODER_SIZE],
-               uint32_t lc, uint32_t lp)
+literal_init(probability *probs, uint32_t lc, uint32_t lp)
 {
        assert(lc + lp <= LZMA_LCLP_MAX);
 
-       const uint32_t coders = 1U << (lc + lp);
+       const size_t coders = LITERAL_CODER_SIZE << (lc + lp);
 
-       for (uint32_t i = 0; i < coders; ++i)
-               for (uint32_t j = 0; j < LITERAL_CODER_SIZE; ++j)
-                       bit_reset(probs[i][j]);
+       for (size_t i = 0; i < coders; ++i)
+               bit_reset(probs[i]);
 
        return;
 }
index 81149006409f0fc05f53095249400db83822d71f..66d2818dd5653bc3ad8b7793982e0b8c4bc45e1a 100644 (file)
@@ -109,7 +109,7 @@ typedef struct {
        ///////////////////
 
        /// Literals; see comments in lzma_common.h.
-       probability literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];
+       probability literal[LITERAL_CODERS_MAX * LITERAL_CODER_SIZE];
 
        /// If 1, it's a match. Otherwise it's a single 8-bit literal.
        probability is_match[STATES][POS_STATES_MAX];
@@ -168,7 +168,7 @@ typedef struct {
 
        uint32_t pos_mask; // (1U << pb) - 1
        uint32_t literal_context_bits;
-       uint32_t literal_pos_mask;
+       uint32_t literal_mask;
 
        /// Uncompressed size as bytes, or LZMA_VLI_UNKNOWN if end of
        /// payload marker is expected.
@@ -280,7 +280,7 @@ lzma_decode(void *coder_ptr, lzma_dict *restrict dictptr,
        uint32_t offset = coder->offset;
        uint32_t len = coder->len;
 
-       const uint32_t literal_pos_mask = coder->literal_pos_mask;
+       const uint32_t literal_mask = coder->literal_mask;
        const uint32_t literal_context_bits = coder->literal_context_bits;
 
        // Temporary variables
@@ -359,7 +359,7 @@ lzma_decode(void *coder_ptr, lzma_dict *restrict dictptr,
                        // Get the correct probability array from lp and
                        // lc params.
                        probs = literal_subcoder(coder->literal,
-                                       literal_context_bits, literal_pos_mask,
+                                       literal_context_bits, literal_mask,
                                        dict.pos, dict_get0(&dict));
 
                        if (is_literal_state(state)) {
@@ -684,7 +684,7 @@ slow:
                        rc_update_0(coder->is_match[state][pos_state]);
 
                        probs = literal_subcoder(coder->literal,
-                                       literal_context_bits, literal_pos_mask,
+                                       literal_context_bits, literal_mask,
                                        dict.pos, dict_get0(&dict));
                        symbol = 1;
 
@@ -1034,7 +1034,7 @@ lzma_decoder_reset(void *coder_ptr, const void *opt)
        literal_init(coder->literal, options->lc, options->lp);
 
        coder->literal_context_bits = options->lc;
-       coder->literal_pos_mask = (1U << options->lp) - 1;
+       coder->literal_mask = literal_mask_calc(options->lc, options->lp);
 
        // State
        coder->state = STATE_LIT_LIT;
index 89d4f4e522fdb1f65f9a4eaf85fa2e962fb2d80f..543ca321c3c22c63b9aaef98c4ee0abb4723ec9d 100644 (file)
@@ -48,7 +48,7 @@ literal(lzma_lzma1_encoder *coder, lzma_mf *mf, uint32_t position)
        const uint8_t cur_byte = mf->buffer[
                        mf->read_pos - mf->read_ahead];
        probability *subcoder = literal_subcoder(coder->literal,
-                       coder->literal_context_bits, coder->literal_pos_mask,
+                       coder->literal_context_bits, coder->literal_mask,
                        position, mf->buffer[mf->read_pos - mf->read_ahead - 1]);
 
        if (is_literal_state(coder->state)) {
@@ -282,7 +282,7 @@ encode_init(lzma_lzma1_encoder *coder, lzma_mf *mf)
                mf_skip(mf, 1);
                mf->read_ahead = 0;
                rc_bit(&coder->rc, &coder->is_match[0][0], 0);
-               rc_bittree(&coder->rc, coder->literal[0], 8, mf->buffer[0]);
+               rc_bittree(&coder->rc, coder->literal + 0, 8, mf->buffer[0]);
                ++coder->uncomp_size;
        }
 
@@ -534,7 +534,7 @@ lzma_lzma_encoder_reset(lzma_lzma1_encoder *coder,
 
        coder->pos_mask = (1U << options->pb) - 1;
        coder->literal_context_bits = options->lc;
-       coder->literal_pos_mask = (1U << options->lp) - 1;
+       coder->literal_mask = literal_mask_calc(options->lc, options->lp);
 
        // Range coder
        rc_reset(&coder->rc);
index 6b384fe0d19bf80119acac99b897b33d1baccd90..a6c0398f3af319efdb7017f37d4947133c4287d4 100644 (file)
@@ -23,7 +23,7 @@ get_literal_price(const lzma_lzma1_encoder *const coder, const uint32_t pos,
                uint32_t match_byte, uint32_t symbol)
 {
        const probability *const subcoder = literal_subcoder(coder->literal,
-                       coder->literal_context_bits, coder->literal_pos_mask,
+                       coder->literal_context_bits, coder->literal_mask,
                        pos, prev_byte);
 
        uint32_t price = 0;
index 6c79b0a06a78a3886799d88447eb6cb83a9cd054..eeea5e9c12891423ef4307dbdbb5ee7f6c648d11 100644 (file)
@@ -115,10 +115,10 @@ struct lzma_lzma1_encoder_s {
 
        uint32_t pos_mask;         ///< (1 << pos_bits) - 1
        uint32_t literal_context_bits;
-       uint32_t literal_pos_mask;
+       uint32_t literal_mask;
 
        // These are the same as in lzma_decoder.c. See comments there.
-       probability literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];
+       probability literal[LITERAL_CODERS_MAX * LITERAL_CODER_SIZE];
        probability is_match[STATES][POS_STATES_MAX];
        probability is_rep[STATES];
        probability is_rep0[STATES];