Allow BackpatchWord to be called for non-32-bit aligned words, and
authorTeresa Johnson <tejohnson@google.com>
Wed, 16 Sep 2015 20:41:43 +0000 (20:41 +0000)
committerTeresa Johnson <tejohnson@google.com>
Wed, 16 Sep 2015 20:41:43 +0000 (20:41 +0000)
from outside the BitstreamWriter.

Split out of patch D12536 (Function bitcode index in Value Symbol Table
and lazy reading support), which will use it to patch in the VST offset.

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

include/llvm/Bitcode/BitstreamWriter.h

index 490911f1ce18032d1bfd73805d00b3fcf2321e31..df07204bc7cdc3648051b1c6f52ced549e975a8f 100644 (file)
@@ -63,12 +63,6 @@ class BitstreamWriter {
   };
   std::vector<BlockInfo> BlockInfoRecords;
 
-  // BackpatchWord - Backpatch a 32-bit word in the output with the specified
-  // value.
-  void BackpatchWord(unsigned ByteNo, unsigned NewWord) {
-    support::endian::write32le(&Out[ByteNo], NewWord);
-  }
-
   void WriteByte(unsigned char Value) {
     Out.push_back(Value);
   }
@@ -105,6 +99,23 @@ public:
   // Basic Primitives for emitting bits to the stream.
   //===--------------------------------------------------------------------===//
 
+  /// Backpatch a 32-bit word in the output at the given bit offset
+  /// with the specified value.
+  void BackpatchWord(uint64_t BitNo, unsigned NewWord) {
+    unsigned ByteNo = BitNo / 8;
+    if ((BitNo & 7) == 0) {
+      // Already 8-bit aligned
+      support::endian::write32le(&Out[ByteNo], NewWord);
+    } else {
+      uint64_t CurDWord = support::endian::read64le(&Out[ByteNo]);
+      unsigned StartBit = BitNo & 7;
+      // Currently expect to backpatch 0-value placeholders.
+      assert(((CurDWord >> StartBit) & 0xffffffff) == 0);
+      CurDWord |= NewWord << StartBit;
+      support::endian::write64le(&Out[ByteNo], CurDWord);
+    }
+  }
+
   void Emit(uint32_t Val, unsigned NumBits) {
     assert(NumBits && NumBits <= 32 && "Invalid value size!");
     assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!");
@@ -234,10 +245,10 @@ public:
 
     // Compute the size of the block, in words, not counting the size field.
     unsigned SizeInWords = GetWordIndex() - B.StartSizeWord - 1;
-    unsigned ByteNo = B.StartSizeWord*4;
+    uint64_t BitNo = B.StartSizeWord * 32;
 
     // Update the block size field in the header of this sub-block.
-    BackpatchWord(ByteNo, SizeInWords);
+    BackpatchWord(BitNo, SizeInWords);
 
     // Restore the inner block's code size and abbrev table.
     CurCodeSize = B.PrevCodeSize;