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: |