]> wimlib.net Git - wimlib/blobdiff - src/lzx_decompress.c
lzx_decompress: redeclare input_bitstream above main loop
[wimlib] / src / lzx_decompress.c
index cce98e32a96904f850f5da6d3e10c2f11b9f39b5..5747d327270717ae6892c257374088e4dfec789d 100644 (file)
@@ -118,7 +118,7 @@ struct lzx_decompressor {
 } _aligned_attribute(DECODE_TABLE_ALIGNMENT);
 
 /* Read a Huffman-encoded symbol using the precode. */
-static inline unsigned
+static forceinline unsigned
 read_presym(const struct lzx_decompressor *d, struct input_bitstream *is)
 {
        return read_huffsym(is, d->precode_decode_table,
@@ -126,7 +126,7 @@ read_presym(const struct lzx_decompressor *d, struct input_bitstream *is)
 }
 
 /* Read a Huffman-encoded symbol using the main code. */
-static inline unsigned
+static forceinline unsigned
 read_mainsym(const struct lzx_decompressor *d, struct input_bitstream *is)
 {
        return read_huffsym(is, d->maincode_decode_table,
@@ -134,7 +134,7 @@ read_mainsym(const struct lzx_decompressor *d, struct input_bitstream *is)
 }
 
 /* Read a Huffman-encoded symbol using the length code. */
-static inline unsigned
+static forceinline unsigned
 read_lensym(const struct lzx_decompressor *d, struct input_bitstream *is)
 {
        return read_huffsym(is, d->lencode_decode_table,
@@ -142,7 +142,7 @@ read_lensym(const struct lzx_decompressor *d, struct input_bitstream *is)
 }
 
 /* Read a Huffman-encoded symbol using the aligned offset code. */
-static inline unsigned
+static forceinline unsigned
 read_alignedsym(const struct lzx_decompressor *d, struct input_bitstream *is)
 {
        return read_huffsym(is, d->alignedcode_decode_table,
@@ -332,10 +332,19 @@ lzx_read_block_header(struct lzx_decompressor *d, struct input_bitstream *is,
 
 /* Decompress a block of LZX-compressed data. */
 static int
-lzx_decompress_block(struct lzx_decompressor *d, struct input_bitstream *is,
+lzx_decompress_block(struct lzx_decompressor *d, struct input_bitstream *_is,
                     int block_type, u32 block_size,
                     u8 * const out_begin, u8 *out_next, u32 recent_offsets[])
 {
+       /*
+        * Redeclare the input bitstream on the stack.  This shouldn't be
+        * needed, but it can improve the main loop's performance significantly
+        * with both gcc and clang, apparently because the compiler otherwise
+        * gets confused and doesn't properly allocate registers for
+        * 'is->bitbuf' et al. and/or thinks 'is->next' may point into 'is'.
+        */
+       struct input_bitstream is_onstack = *_is;
+       struct input_bitstream *is = &is_onstack;
        u8 * const block_end = out_next + block_size;
        unsigned min_aligned_offset_slot;
 
@@ -435,6 +444,7 @@ lzx_decompress_block(struct lzx_decompressor *d, struct input_bitstream *is,
                out_next += length;
        } while (out_next != block_end);
 
+       *_is = is_onstack;
        return 0;
 }