OSDN Git Service

Read 64 bits at a time in the bitcode reader.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 13 Nov 2014 07:23:22 +0000 (07:23 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 13 Nov 2014 07:23:22 +0000 (07:23 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221865 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Bitcode/BitstreamReader.h
include/llvm/Support/StreamingMemoryObject.h
lib/Support/StreamingMemoryObject.cpp

index 41e50e1..c45f5fc 100644 (file)
@@ -177,11 +177,11 @@ class BitstreamCursor {
   /// 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
   /// on.
-  typedef uint32_t word_t;
+  typedef size_t word_t;
   word_t CurWord;
 
   /// 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;
 
   // This is the declared size of code values used for the current block, in
@@ -333,7 +333,6 @@ public:
       Size = NextChar;
       return;
     }
-    assert(BytesRead == sizeof(Array));
 
     // Handle big-endian byte-swapping if necessary.
     support::detail::packed_endian_specific_integral<
@@ -341,20 +340,22 @@ public:
     memcpy(&EndianValue, Array, sizeof(Array));
 
     CurWord = EndianValue;
-    NextChar += sizeof(word_t);
-    BitsInCurWord = sizeof(word_t) * 8;
+    NextChar += BytesRead;
+    BitsInCurWord = BytesRead * 8;
   }
 
   uint32_t Read(unsigned NumBits) {
     assert(NumBits && NumBits <= 32 &&
            "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 (BitsInCurWord >= NumBits) {
       uint32_t R = uint32_t(CurWord) & (~0U >> (32-NumBits));
 
       // Use a mask to avoid undefined behavior.
-      CurWord >>= (NumBits & 0x1f);
+      CurWord >>= (NumBits & Mask);
 
       BitsInCurWord -= NumBits;
       return R;
@@ -369,10 +370,11 @@ public:
     if (BitsLeft > BitsInCurWord)
       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.
-    CurWord >>= (BitsLeft & 0x1f);
+    CurWord >>= (BitsLeft & Mask);
 
     BitsInCurWord -= BitsLeft;
 
index 9325a02..6957c6e 100644 (file)
@@ -71,14 +71,10 @@ private:
       size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped],
                                         kChunkSize);
       BytesRead += bytes;
-      if (bytes < kChunkSize) {
-        assert((!ObjectSize || BytesRead >= Pos) &&
-               "Unexpected short read fetching bitcode");
-        if (BytesRead <= Pos) { // reached EOF/ran out of bytes
-          ObjectSize = BytesRead;
-          EOFReached = true;
-          return false;
-        }
+      if (BytesRead <= Pos) { // reached EOF/ran out of bytes
+        ObjectSize = BytesRead;
+        EOFReached = true;
+        return false;
       }
     }
     return true;
index b3723d0..f0eb831 100644 (file)
@@ -90,13 +90,12 @@ uint64_t StreamingMemoryObject::getExtent() const {
 uint64_t StreamingMemoryObject::readBytes(uint8_t *Buf, uint64_t Size,
                                           uint64_t Address) const {
   fetchToPos(Address + Size - 1);
-  uint64_t BufferSize = Bytes.size() - BytesSkipped;
-  if (Address >= BufferSize)
+  if (Address >= BytesRead)
     return 0;
 
   uint64_t End = Address + Size;
-  if (End > BufferSize)
-    End = BufferSize;
+  if (End > BytesRead)
+    End = BytesRead;
   Size = End - Address;
   assert(Size >= 0);
   memcpy(Buf, &Bytes[Address + BytesSkipped], Size);