Mercurial > libavcodec.hg
comparison vp56.h @ 12033:5de2b84a1fc3 libavcodec
Eliminate another redundant instruction in vp56/8 arithcoder
Necessary because of this GCC bug:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44474
To do this, convert some, but not all (!) of the variables in VP56RangeCoder
into local variables.
If we convert c->high into a local variable, gcc gets the stupids and refuses
to use a conditional move for the unpredictable main branch.
TODO: dispense with this bullshit and write an asm version.
author | darkshikari |
---|---|
date | Wed, 30 Jun 2010 23:59:27 +0000 |
parents | 572c81b3be19 |
children | 5a794f3f0d75 |
comparison
equal
deleted
inserted
replaced
12032:572c81b3be19 | 12033:5de2b84a1fc3 |
---|---|
192 c->code_word = bytestream_get_be16(&c->buffer); | 192 c->code_word = bytestream_get_be16(&c->buffer); |
193 } | 193 } |
194 | 194 |
195 static inline int vp56_rac_get_prob(VP56RangeCoder *c, uint8_t prob) | 195 static inline int vp56_rac_get_prob(VP56RangeCoder *c, uint8_t prob) |
196 { | 196 { |
197 /* Don't put c->high in a local variable; if we do that, gcc gets | |
198 * the stupids and turns the code below into a branch again. */ | |
199 int bits = c->bits; | |
200 unsigned long code_word = c->code_word; | |
197 unsigned int low = 1 + (((c->high - 1) * prob) >> 8); | 201 unsigned int low = 1 + (((c->high - 1) * prob) >> 8); |
198 unsigned int low_shift = low << 8; | 202 unsigned int low_shift = low << 8; |
199 int bit = c->code_word >= low_shift; | 203 int bit = code_word >= low_shift; |
200 int shift; | 204 int shift; |
201 | 205 |
206 /* Incantation to convince GCC to turn these into conditional moves | |
207 * instead of branches -- faster, as this branch is basically | |
208 * unpredictable. */ | |
202 c->high = bit ? c->high - low : low; | 209 c->high = bit ? c->high - low : low; |
203 c->code_word = bit ? c->code_word - low_shift : c->code_word; | 210 code_word = bit ? code_word - low_shift : code_word; |
204 | 211 |
205 /* normalize */ | 212 /* normalize */ |
206 shift = ff_h264_norm_shift[c->high] - 1; | 213 shift = ff_h264_norm_shift[c->high] - 1; |
207 c->high <<= shift; | 214 c->high <<= shift; |
208 c->code_word <<= shift; | 215 code_word <<= shift; |
209 c->bits += shift; | 216 bits += shift; |
210 if(c->bits >= 0 && c->buffer < c->end) { | 217 if(bits >= 0 && c->buffer < c->end) { |
211 c->code_word |= *c->buffer++ << c->bits; | 218 code_word |= *c->buffer++ << bits; |
212 c->bits -= 8; | 219 bits -= 8; |
213 } | 220 } |
221 c->bits = bits; | |
222 c->code_word = code_word; | |
214 return bit; | 223 return bit; |
215 } | 224 } |
216 | 225 |
217 static inline int vp56_rac_get(VP56RangeCoder *c) | 226 static inline int vp56_rac_get(VP56RangeCoder *c) |
218 { | 227 { |