1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

Read 64 bits at a time in the bitcode reader.

The reading of 64 bit values could still be optimized, but at least this cuts
down on the number of virtual calls to fetch more data.

llvm-svn: 221865
This commit is contained in:
Rafael Espindola 2014-11-13 07:23:22 +00:00
parent 477bb4ae3d
commit ad6b4ce7dc
3 changed files with 17 additions and 20 deletions

View File

@ -177,11 +177,11 @@ class BitstreamCursor {
/// follow the word size of the host machine for efficiency. We use word_t in /// follow the word size of the host machine for efficiency. We use word_t in
/// places that are aware of this to make it perfectly explicit what is going /// places that are aware of this to make it perfectly explicit what is going
/// on. /// on.
typedef uint32_t word_t; typedef size_t word_t;
word_t CurWord; word_t CurWord;
/// This is the number of bits in CurWord that are valid. This is always from /// This is the number of bits in CurWord that are valid. This is always from
/// [0...31/63] inclusive (depending on word size). /// [0...bits_of(size_t)-1] inclusive.
unsigned BitsInCurWord; unsigned BitsInCurWord;
// This is the declared size of code values used for the current block, in // This is the declared size of code values used for the current block, in
@ -333,7 +333,6 @@ public:
Size = NextChar; Size = NextChar;
return; return;
} }
assert(BytesRead == sizeof(Array));
// Handle big-endian byte-swapping if necessary. // Handle big-endian byte-swapping if necessary.
support::detail::packed_endian_specific_integral< support::detail::packed_endian_specific_integral<
@ -341,20 +340,22 @@ public:
memcpy(&EndianValue, Array, sizeof(Array)); memcpy(&EndianValue, Array, sizeof(Array));
CurWord = EndianValue; CurWord = EndianValue;
NextChar += sizeof(word_t); NextChar += BytesRead;
BitsInCurWord = sizeof(word_t) * 8; BitsInCurWord = BytesRead * 8;
} }
uint32_t Read(unsigned NumBits) { uint32_t Read(unsigned NumBits) {
assert(NumBits && NumBits <= 32 && assert(NumBits && NumBits <= 32 &&
"Cannot return zero or more than 32 bits!"); "Cannot return zero or more than 32 bits!");
static const unsigned Mask = sizeof(word_t) > 4 ? 0x3f : 0x1f;
// If the field is fully contained by CurWord, return it quickly. // If the field is fully contained by CurWord, return it quickly.
if (BitsInCurWord >= NumBits) { if (BitsInCurWord >= NumBits) {
uint32_t R = uint32_t(CurWord) & (~0U >> (32-NumBits)); uint32_t R = uint32_t(CurWord) & (~0U >> (32-NumBits));
// Use a mask to avoid undefined behavior. // Use a mask to avoid undefined behavior.
CurWord >>= (NumBits & 0x1f); CurWord >>= (NumBits & Mask);
BitsInCurWord -= NumBits; BitsInCurWord -= NumBits;
return R; return R;
@ -369,10 +370,11 @@ public:
if (BitsLeft > BitsInCurWord) if (BitsLeft > BitsInCurWord)
return 0; return 0;
uint32_t R2 = uint32_t(CurWord) & (~0U >> (sizeof(word_t) * 8 - BitsLeft)); uint32_t R2 =
uint32_t(CurWord) & (~word_t(0) >> (sizeof(word_t) * 8 - BitsLeft));
// Use a mask to avoid undefined behavior. // Use a mask to avoid undefined behavior.
CurWord >>= (BitsLeft & 0x1f); CurWord >>= (BitsLeft & Mask);
BitsInCurWord -= BitsLeft; BitsInCurWord -= BitsLeft;

View File

@ -71,14 +71,10 @@ private:
size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped], size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped],
kChunkSize); kChunkSize);
BytesRead += bytes; BytesRead += bytes;
if (bytes < kChunkSize) { if (BytesRead <= Pos) { // reached EOF/ran out of bytes
assert((!ObjectSize || BytesRead >= Pos) && ObjectSize = BytesRead;
"Unexpected short read fetching bitcode"); EOFReached = true;
if (BytesRead <= Pos) { // reached EOF/ran out of bytes return false;
ObjectSize = BytesRead;
EOFReached = true;
return false;
}
} }
} }
return true; return true;

View File

@ -90,13 +90,12 @@ uint64_t StreamingMemoryObject::getExtent() const {
uint64_t StreamingMemoryObject::readBytes(uint8_t *Buf, uint64_t Size, uint64_t StreamingMemoryObject::readBytes(uint8_t *Buf, uint64_t Size,
uint64_t Address) const { uint64_t Address) const {
fetchToPos(Address + Size - 1); fetchToPos(Address + Size - 1);
uint64_t BufferSize = Bytes.size() - BytesSkipped; if (Address >= BytesRead)
if (Address >= BufferSize)
return 0; return 0;
uint64_t End = Address + Size; uint64_t End = Address + Size;
if (End > BufferSize) if (End > BytesRead)
End = BufferSize; End = BytesRead;
Size = End - Address; Size = End - Address;
assert(Size >= 0); assert(Size >= 0);
memcpy(Buf, &Bytes[Address + BytesSkipped], Size); memcpy(Buf, &Bytes[Address + BytesSkipped], Size);