Chromium Code Reviews| Index: include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h |
| diff --git a/include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h b/include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h |
| index 26d9cb6b2486bc3d76c32f3a2b33d7ee633ac67e..0f474ac721b716b65bf6d923387ce996b0e2171c 100644 |
| --- a/include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h |
| +++ b/include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h |
| @@ -20,6 +20,8 @@ |
| #include "llvm/Bitcode/NaCl/NaClBitCodes.h" |
| #include <vector> |
| +#include "llvm/Support/raw_ostream.h" |
|
jvoung (off chromium)
2013/05/14 23:47:14
what is this used for?
Karl
2013/05/17 20:52:18
Removed.
|
| + |
| namespace llvm { |
| class NaClBitstreamWriter { |
| @@ -33,7 +35,7 @@ class NaClBitstreamWriter { |
| /// CurCodeSize - This is the declared size of code values used for the |
| /// current block, in bits. |
| - unsigned CurCodeSize; |
| + NaClBitcodeSelectorAbbrev CurCodeSize; |
| /// BlockInfoCurBID - When emitting a BLOCKINFO_BLOCK, this is the currently |
| /// selected BLOCK ID. |
| @@ -43,10 +45,11 @@ class NaClBitstreamWriter { |
| std::vector<NaClBitCodeAbbrev*> CurAbbrevs; |
| struct Block { |
| - unsigned PrevCodeSize; |
| + NaClBitcodeSelectorAbbrev PrevCodeSize; |
| unsigned StartSizeWord; |
| std::vector<NaClBitCodeAbbrev*> PrevAbbrevs; |
| - Block(unsigned PCS, unsigned SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {} |
| + Block(const NaClBitcodeSelectorAbbrev& PCS, unsigned SSW) |
| + : PrevCodeSize(PCS), StartSizeWord(SSW) {} |
| }; |
| /// BlockScope - This tracks the current blocks that we have entered. |
| @@ -92,9 +95,21 @@ class NaClBitstreamWriter { |
| return Offset / 4; |
| } |
| + // Helper to EmitIntVBR to print out first chunk. One bit is for the sign, |
| + // and the remaining bits is to encode Val. |
| + void EmitIntVBRChunk(uint32_t Val, bool IsNegative, unsigned NumBits, |
|
Karl
2013/05/17 20:52:18
Removed. No longer used. Uses NaClEncodeSignRotate
|
| + bool IsFirstIteration) { |
| + if (IsFirstIteration) { |
| + if (IsNegative) Val &= (1 << NumBits); |
| + Emit(Val, NumBits+1); |
| + } else { |
| + Emit(Val, NumBits); |
| + } |
| + } |
| + |
| public: |
| explicit NaClBitstreamWriter(SmallVectorImpl<char> &O) |
| - : Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {} |
| + : Out(O), CurBit(0), CurValue(0), CurCodeSize() {} |
| ~NaClBitstreamWriter() { |
| assert(CurBit == 0 && "Unflused data remaining"); |
| @@ -156,6 +171,7 @@ public: |
| void EmitVBR(uint32_t Val, unsigned NumBits) { |
| assert(NumBits <= 32 && "Too many bits to emit!"); |
| + assert(NumBits > 1 && "Too few bits to emit!"); |
| uint32_t Threshold = 1U << (NumBits-1); |
| // Emit the bits with VBR encoding, NumBits-1 bits at a time. |
| @@ -169,6 +185,7 @@ public: |
| void EmitVBR64(uint64_t Val, unsigned NumBits) { |
| assert(NumBits <= 32 && "Too many bits to emit!"); |
| + assert(NumBits > 1 && "Too few bits to emit!"); |
| if ((uint32_t)Val == Val) |
| return EmitVBR((uint32_t)Val, NumBits); |
| @@ -184,9 +201,39 @@ public: |
| Emit((uint32_t)Val, NumBits); |
| } |
| + void EmitIntVBR(int32_t Val, unsigned NumBits) { |
|
jvoung (off chromium)
2013/05/14 23:47:14
There is static void emitSignedInt64(SmallVectorIm
Karl
2013/05/17 20:52:18
Removed. No longer used. Uses NaClEncodeSignRotate
|
| + // Same as unsigned version, except that the sign is captured |
| + // by prepending a sign bit. |
| + assert(NumBits < 32 && "Too many bits to emit!"); |
| + assert(NumBits > 1 && "Too few bits to emit!"); |
| + |
| + // Capture sign. |
| + bool IsNegative = false; |
| + uint32_t Value = static_cast<uint32_t>(Val); |
| + if (Val < 0) { |
| + IsNegative = true; |
| + Value = static_cast<uint32_t>(-Val); |
| + } |
| + |
| + uint32_t Threshold = 1U << (NumBits-1); |
| + bool IsFirstIteration = true; |
| + |
| + // Emit the bits with VBR encoding, NumBits-1 bits at a time. |
| + while (Value >= Threshold) { |
| + uint32_t Chunk = (Value & (Threshold-1)) | Threshold; |
| + EmitIntVBRChunk(Chunk, IsNegative, NumBits, IsFirstIteration); |
| + if (IsFirstIteration) IsFirstIteration = false; |
| + Value >>= NumBits-1; |
| + } |
| + EmitIntVBRChunk(Value, IsNegative, NumBits, IsFirstIteration); |
| + } |
| + |
| /// EmitCode - Emit the specified code. |
| void EmitCode(unsigned Val) { |
| - Emit(Val, CurCodeSize); |
| + if (CurCodeSize.UseFixed()) |
|
Karl
2013/05/17 20:52:18
Modified code to use fields since methods UseFixed
|
| + Emit(Val, CurCodeSize.UseNumBits()); |
| + else |
| + EmitVBR(Val, CurCodeSize.UseNumBits()); |
| } |
| //===--------------------------------------------------------------------===// |
| @@ -207,16 +254,21 @@ public: |
| return 0; |
| } |
| - void EnterSubblock(unsigned BlockID, unsigned CodeLen) { |
| + // Enter block using CodeLen bits to read the size of the code selector |
| + // associated with the block. |
| + void EnterSubblock(unsigned BlockID, |
| + const NaClBitcodeSelectorAbbrev& CodeLen) { |
| // Block header: |
| // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] |
| EmitCode(naclbitc::ENTER_SUBBLOCK); |
| EmitVBR(BlockID, naclbitc::BlockIDWidth); |
| - EmitVBR(CodeLen, naclbitc::CodeLenWidth); |
| + EmitIntVBR((CodeLen.UseFixed() |
|
jvoung (off chromium)
2013/05/14 23:47:14
How come this can be a negative value: -CodeLen.Us
Karl
2013/05/17 20:52:18
I modified this to be more explicit using:
Emit
|
| + ? CodeLen.UseNumBits() : -CodeLen.UseNumBits()), |
| + naclbitc::CodeLenWidth); |
| FlushToWord(); |
| unsigned BlockSizeWordIndex = GetWordIndex(); |
| - unsigned OldCodeSize = CurCodeSize; |
| + NaClBitcodeSelectorAbbrev OldCodeSize(CurCodeSize); |
| // Emit a placeholder, which will be replaced when the block is popped. |
| Emit(0, naclbitc::BlockSizeWidth); |
| @@ -239,6 +291,28 @@ public: |
| } |
| } |
| + // Enter block with no abbreviations. |
| + void EnterSubblock(unsigned BlockID) { |
| + NaClBitcodeSelectorAbbrev DefaultCodeLen; |
| + EnterSubblock(BlockID, DefaultCodeLen); |
| + } |
| + |
| + // Enter block with the given number of abbreviations. |
| + void EnterSubblock(unsigned BlockID, unsigned NumAbbrev) { |
| + NaClBitcodeSelectorAbbrev CodeLenAbbrev(NumAbbrev); |
| + EnterSubblock(BlockID, CodeLenAbbrev); |
| + } |
| + |
| + // Enter block with the given number of abbreviations NumAbbrev, |
| + // with the constraint that all abbreviations < FixedAbbrevCutoff will |
| + // be read using a single read. |
| + void EnterSubblock(unsigned BlockId, |
| + unsigned NumAbbrev, |
| + unsigned FixedAbbrevCutoff) { |
| + NaClBitcodeSelectorAbbrev CodeLenAbbrev(FixedAbbrevCutoff, NumAbbrev); |
| + EnterSubblock(BlockId, CodeLenAbbrev); |
| + } |
| + |
| void ExitBlock() { |
| assert(!BlockScope.empty() && "Block scope imbalance!"); |
| @@ -501,8 +575,8 @@ public: |
| //===--------------------------------------------------------------------===// |
| /// EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK. |
| - void EnterBlockInfoBlock(unsigned CodeWidth) { |
| - EnterSubblock(naclbitc::BLOCKINFO_BLOCK_ID, CodeWidth); |
| + void EnterBlockInfoBlock() { |
| + EnterSubblock(naclbitc::BLOCKINFO_BLOCK_ID); |
| BlockInfoCurBID = ~0U; |
| } |
| private: |