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..b4123261a0fa6a62fb94b2503abd786e97d4d47d 100644 |
--- a/include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h |
+++ b/include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h |
@@ -33,7 +33,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 +43,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. |
@@ -94,7 +95,7 @@ class NaClBitstreamWriter { |
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 +157,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 +171,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); |
@@ -186,7 +189,10 @@ public: |
/// EmitCode - Emit the specified code. |
void EmitCode(unsigned Val) { |
- Emit(Val, CurCodeSize); |
+ if (CurCodeSize.IsFixed) |
+ Emit(Val, CurCodeSize.NumBits); |
+ else |
+ EmitVBR(Val, CurCodeSize.NumBits); |
} |
//===--------------------------------------------------------------------===// |
@@ -207,16 +213,22 @@ public: |
return 0; |
} |
- void EnterSubblock(unsigned BlockID, unsigned CodeLen) { |
+private: |
+ // Enter block using CodeLen bits to read the size of the code |
+ // selector associated with the block. |
+ void EnterSubblock(unsigned BlockID, |
+ const NaClBitcodeSelectorAbbrev& CodeLen, |
+ BlockInfo *Info) { |
// Block header: |
// [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] |
EmitCode(naclbitc::ENTER_SUBBLOCK); |
EmitVBR(BlockID, naclbitc::BlockIDWidth); |
- EmitVBR(CodeLen, naclbitc::CodeLenWidth); |
+ assert(CodeLen.IsFixed && "Block codelens must be fixed"); |
+ EmitVBR(CodeLen.NumBits, 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); |
@@ -230,7 +242,7 @@ public: |
// If there is a blockinfo for this BlockID, add all the predefined abbrevs |
// to the abbrev list. |
- if (BlockInfo *Info = getBlockInfo(BlockID)) { |
+ if (Info) { |
for (unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size()); |
i != e; ++i) { |
CurAbbrevs.push_back(Info->Abbrevs[i]); |
@@ -239,6 +251,31 @@ public: |
} |
} |
+public: |
+ /// \brief Enter block using CodeLen bits to read the size of the code |
+ /// selector associated with the block. |
+ void EnterSubblock(unsigned BlockID, |
+ const NaClBitcodeSelectorAbbrev& CodeLen) { |
+ EnterSubblock(BlockID, CodeLen, getBlockInfo(BlockID)); |
+ } |
+ |
+ /// \brief Enter block, using a code length based on the number of |
+ /// (global) BlockInfo entries defined for the block. Note: This |
+ /// should be used only if the block doesn't define any local abbreviations. |
+ void EnterSubblock(unsigned BlockID) { |
+ BlockInfo *Info = getBlockInfo(BlockID); |
+ size_t NumAbbrevs = Info ? Info->Abbrevs.size() : 0; |
+ NaClBitcodeSelectorAbbrev DefaultCodeLen( |
+ naclbitc::DEFAULT_MAX_ABBREV+NumAbbrevs); |
+ EnterSubblock(BlockID, DefaultCodeLen, Info); |
+ } |
+ |
+ /// \brief Enter block with the given number of abbreviations. |
+ void EnterSubblock(unsigned BlockID, unsigned NumAbbrev) { |
+ NaClBitcodeSelectorAbbrev CodeLenAbbrev(NumAbbrev); |
+ EnterSubblock(BlockID, CodeLenAbbrev); |
+ } |
+ |
void ExitBlock() { |
assert(!BlockScope.empty() && "Block scope imbalance!"); |
@@ -501,8 +538,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: |