From 8e9c6b63fcba9406cea6b742859e7730e0e2e8a9 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 26 Jul 2014 18:38:08 -0500 Subject: [PATCH] decompress_common.h: Optimize bitstream_ensure_bits() --- include/wimlib/compiler.h | 2 ++ include/wimlib/decompress_common.h | 26 +++++++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/include/wimlib/compiler.h b/include/wimlib/compiler.h index c6e22e98..fd8942f1 100644 --- a/include/wimlib/compiler.h +++ b/include/wimlib/compiler.h @@ -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 */ diff --git a/include/wimlib/decompress_common.h b/include/wimlib/decompress_common.h index fab3c3e0..7428e320 100644 --- a/include/wimlib/decompress_common.h +++ b/include/wimlib/decompress_common.h @@ -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; -- 2.43.0