]> wimlib.net Git - wimlib/commitdiff
decompress_common.h: Optimize bitstream_ensure_bits()
authorEric Biggers <ebiggers3@gmail.com>
Sat, 26 Jul 2014 23:38:08 +0000 (18:38 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Sat, 26 Jul 2014 23:38:08 +0000 (18:38 -0500)
include/wimlib/compiler.h
include/wimlib/decompress_common.h

index c6e22e98d649d5cb42937eabdaf52472fb8af408..fd8942f15bf025bec6aa5485fcfadc07402d2096 100644 (file)
@@ -30,6 +30,7 @@
 #      define unlikely(x) __builtin_expect(!!(x), 0)
 #      define inline inline __attribute__((always_inline))
 #      define prefetch(x) __builtin_prefetch(x)
+#      define is_constant(x) __builtin_constant_p(x)
 #else
 #      define WIMLIBAPI
 #      define _always_inline_attribute inline
@@ -42,6 +43,7 @@
 #      define likely(x) (x)
 #      define unlikely(x) (x)
 #      define prefetch(x)
+#      define is_constant(x) (0)
 #endif /* __GNUC__ */
 
 #endif /* _WIMLIB_COMPILER_H */
index fab3c3e009413c4ef9ed4b9f0a4a6a3a672cc1a9..7428e3207eb9430f2c8da7df6917deadb5dfece8 100644 (file)
@@ -56,15 +56,27 @@ init_input_bitstream(struct input_bitstream *istream,
 static inline void
 bitstream_ensure_bits(struct input_bitstream *istream, unsigned num_bits)
 {
-       for (int nbits = num_bits; (int)istream->bitsleft < nbits; nbits -= 16) {
-               u16 nextword;
-               unsigned shift;
+       u16 nextword;
+       unsigned shift;
 
-               if (unlikely(istream->data_bytes_left < 2)) {
-                       istream->bitsleft = num_bits;
-                       return;
-               }
+       /* This currently works for at most 17 bits.  */
+       wimlib_assert2(num_bits <= 17);
 
+       if (istream->bitsleft >= num_bits)
+               return;
+
+       nextword = le16_to_cpu(*(const le16*)istream->data);
+       shift = sizeof(istream->bitbuf) * 8 - 16 - istream->bitsleft;
+       istream->bitbuf |= (u32)nextword << shift;
+       istream->data += 2;
+       istream->bitsleft += 16;
+       istream->data_bytes_left -= 2;
+
+       /* Help the compiler: If it's known at compile-time that num_bits <= 16,
+        * a second word will never be needed.  */
+       if (!(is_constant(num_bits) && num_bits <= 16) &&
+           unlikely(istream->bitsleft < num_bits))
+       {
                nextword = le16_to_cpu(*(const le16*)istream->data);
                shift = sizeof(istream->bitbuf) * 8 - 16 - istream->bitsleft;
                istream->bitbuf |= (u32)nextword << shift;