Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

rework the Bitstream reader to actually work a machine word at a time…

…, instead of 32-bits at a time.

This cuts in half the number of virtual methods called to refill that word when compiling on a 64-bit
host, and will make 64-bit read operations faster.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173072 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information...
commit 02b206f6d817b005799cbeca119376c034679212 1 parent 69582cf
Chris Lattner authored

Showing 1 changed file with 49 additions and 21 deletions. Show diff stats Hide diff stats

  1. +49 21 include/llvm/Bitcode/BitstreamReader.h
70 include/llvm/Bitcode/BitstreamReader.h
@@ -170,12 +170,17 @@ class BitstreamCursor {
170 170 BitstreamReader *BitStream;
171 171 size_t NextChar;
172 172
173   - /// CurWord - This is the current data we have pulled from the stream but have
174   - /// not returned to the client.
175   - uint32_t CurWord;
  173 +
  174 + /// CurWord/word_t - This is the current data we have pulled from the stream
  175 + /// but have not returned to the client. This is specifically and
  176 + /// intentionally defined to follow the word size of the host machine for
  177 + /// efficiency. We use word_t in places that are aware of this to make it
  178 + /// perfectly explicit what is going on.
  179 + typedef size_t word_t;
  180 + word_t CurWord;
176 181
177 182 /// BitsInCurWord - This is the number of bits in CurWord that are valid. This
178   - /// is always from [0...31] inclusive.
  183 + /// is always from [0...31/63] inclusive (depending on word size).
179 184 unsigned BitsInCurWord;
180 185
181 186 // CurCodeSize - This is the declared size of code values used for the current
@@ -318,8 +323,8 @@ class BitstreamCursor {
318 323
319 324 /// JumpToBit - Reset the stream to the specified bit number.
320 325 void JumpToBit(uint64_t BitNo) {
321   - uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3;
322   - uintptr_t WordBitNo = uintptr_t(BitNo) & 31;
  326 + uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1);
  327 + unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1));
323 328 assert(canSkipToPos(ByteNo) && "Invalid location");
324 329
325 330 // Move the cursor to the right word.
@@ -328,8 +333,12 @@ class BitstreamCursor {
328 333 CurWord = 0;
329 334
330 335 // Skip over any bits that are already consumed.
331   - if (WordBitNo)
332   - Read(static_cast<unsigned>(WordBitNo));
  336 + if (WordBitNo) {
  337 + if (sizeof(word_t) > 4)
  338 + Read64(WordBitNo);
  339 + else
  340 + Read(WordBitNo);
  341 + }
333 342 }
334 343
335 344
@@ -337,7 +346,7 @@ class BitstreamCursor {
337 346 assert(NumBits <= 32 && "Cannot return more than 32 bits!");
338 347 // If the field is fully contained by CurWord, return it quickly.
339 348 if (BitsInCurWord >= NumBits) {
340   - uint32_t R = CurWord & ((1U << NumBits)-1);
  349 + uint32_t R = uint32_t(CurWord) & (~0U >> (32-NumBits));
341 350 CurWord >>= NumBits;
342 351 BitsInCurWord -= NumBits;
343 352 return R;
@@ -350,24 +359,32 @@ class BitstreamCursor {
350 359 return 0;
351 360 }
352 361
353   - unsigned R = CurWord;
  362 + uint32_t R = uint32_t(CurWord);
354 363
355 364 // Read the next word from the stream.
356   - CurWord = getWord(NextChar);
357   - NextChar += 4;
  365 + uint8_t buf[sizeof(word_t)] = {0};
  366 + BitStream->getBitcodeBytes().readBytes(NextChar, sizeof(buf), buf, NULL);
  367 +
  368 + typedef support::detail::packed_endian_specific_integral
  369 + <word_t, support::little, support::unaligned> Endian_T;
  370 + CurWord = *reinterpret_cast<Endian_T*>(buf);
  371 +
  372 + NextChar += sizeof(word_t);
358 373
359 374 // Extract NumBits-BitsInCurWord from what we just read.
360 375 unsigned BitsLeft = NumBits-BitsInCurWord;
361 376
362   - // Be careful here, BitsLeft is in the range [1..32] inclusive.
363   - R |= (CurWord & (~0U >> (32-BitsLeft))) << BitsInCurWord;
  377 + // Be careful here, BitsLeft is in the range [1..32]/[1..64] inclusive.
  378 + R |= uint32_t((CurWord & (word_t(~0ULL) >> (sizeof(word_t)*8-BitsLeft)))
  379 + << BitsInCurWord);
364 380
365   - // BitsLeft bits have just been used up from CurWord.
366   - if (BitsLeft != 32)
  381 + // BitsLeft bits have just been used up from CurWord. BitsLeft is in the
  382 + // range [1..32]/[1..64] so be careful how we shift.
  383 + if (BitsLeft != sizeof(word_t)*8)
367 384 CurWord >>= BitsLeft;
368 385 else
369 386 CurWord = 0;
370   - BitsInCurWord = 32-BitsLeft;
  387 + BitsInCurWord = sizeof(word_t)*8-BitsLeft;
371 388 return R;
372 389 }
373 390
@@ -416,10 +433,21 @@ class BitstreamCursor {
416 433 }
417 434 }
418 435
  436 +private:
419 437 void SkipToFourByteBoundary() {
  438 + // If word_t is 64-bits and if we've read less than 32 bits, just dump
  439 + // the bits we have up to the next 32-bit boundary.
  440 + if (sizeof(word_t) > 4 &&
  441 + BitsInCurWord > 32) {
  442 + CurWord >>= BitsInCurWord-32;
  443 + BitsInCurWord = 32;
  444 + return;
  445 + }
  446 +
420 447 BitsInCurWord = 0;
421 448 CurWord = 0;
422 449 }
  450 +public:
423 451
424 452 unsigned ReadCode() {
425 453 return Read(CurCodeSize);
@@ -443,15 +471,15 @@ class BitstreamCursor {
443 471 // don't care what code widths are used inside of it.
444 472 ReadVBR(bitc::CodeLenWidth);
445 473 SkipToFourByteBoundary();
446   - unsigned NumWords = Read(bitc::BlockSizeWidth);
  474 + unsigned NumFourBytes = Read(bitc::BlockSizeWidth);
447 475
448 476 // Check that the block wasn't partially defined, and that the offset isn't
449 477 // bogus.
450   - size_t SkipTo = NextChar + NumWords*4;
451   - if (AtEndOfStream() || !canSkipToPos(SkipTo))
  478 + size_t SkipTo = GetCurrentBitNo() + NumFourBytes*4*8;
  479 + if (AtEndOfStream() || !canSkipToPos(SkipTo/8))
452 480 return true;
453 481
454   - NextChar = SkipTo;
  482 + JumpToBit(SkipTo);
455 483 return false;
456 484 }
457 485

0 comments on commit 02b206f

Please sign in to comment.
Something went wrong with that request. Please try again.