15 #ifndef LLVM_BITCODE_BITSTREAMWRITER_H
16 #define LLVM_BITCODE_BITSTREAMWRITER_H
40 unsigned BlockInfoCurBID;
43 std::vector<BitCodeAbbrev*> CurAbbrevs;
46 unsigned PrevCodeSize;
47 unsigned StartSizeWord;
48 std::vector<BitCodeAbbrev*> PrevAbbrevs;
49 Block(
unsigned PCS,
unsigned SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {}
53 std::vector<Block> BlockScope;
59 std::vector<BitCodeAbbrev*> Abbrevs;
61 std::vector<BlockInfo> BlockInfoRecords;
65 void BackpatchWord(
unsigned ByteNo,
unsigned NewWord) {
66 Out[ByteNo++] = (
unsigned char)(NewWord >> 0);
67 Out[ByteNo++] = (
unsigned char)(NewWord >> 8);
68 Out[ByteNo++] = (
unsigned char)(NewWord >> 16);
69 Out[ByteNo ] = (
unsigned char)(NewWord >> 24);
72 void WriteByte(
unsigned char Value) {
76 void WriteWord(
unsigned Value) {
77 unsigned char Bytes[4] = {
78 (
unsigned char)(Value >> 0),
79 (
unsigned char)(Value >> 8),
80 (
unsigned char)(Value >> 16),
81 (
unsigned char)(Value >> 24) };
82 Out.
append(&Bytes[0], &Bytes[4]);
85 unsigned GetBufferOffset()
const {
89 unsigned GetWordIndex()
const {
90 unsigned Offset = GetBufferOffset();
91 assert((Offset & 3) == 0 &&
"Not 32-bit aligned");
97 : Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {}
100 assert(CurBit == 0 &&
"Unflused data remaining");
101 assert(BlockScope.empty() && CurAbbrevs.empty() &&
"Block imbalance");
104 while (!BlockInfoRecords.empty()) {
105 BlockInfo &Info = BlockInfoRecords.back();
107 for (
unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size());
109 Info.Abbrevs[i]->dropRef();
110 BlockInfoRecords.pop_back();
121 void Emit(uint32_t Val,
unsigned NumBits) {
122 assert(NumBits && NumBits <= 32 &&
"Invalid value size!");
123 assert((Val & ~(~0U >> (32-NumBits))) == 0 &&
"High bits set!");
124 CurValue |= Val << CurBit;
125 if (CurBit + NumBits < 32) {
134 CurValue = Val >> (32-CurBit);
137 CurBit = (CurBit+NumBits) & 31;
140 void Emit64(uint64_t Val,
unsigned NumBits) {
142 Emit((uint32_t)Val, NumBits);
144 Emit((uint32_t)Val, 32);
145 Emit((uint32_t)(Val >> 32), NumBits-32);
157 void EmitVBR(uint32_t Val,
unsigned NumBits) {
158 assert(NumBits <= 32 &&
"Too many bits to emit!");
162 while (Val >= Threshold) {
163 Emit((Val & ((1 << (NumBits-1))-1)) | (1 << (NumBits-1)), NumBits);
171 assert(NumBits <= 32 &&
"Too many bits to emit!");
172 if ((uint32_t)Val == Val)
173 return EmitVBR((uint32_t)Val, NumBits);
178 while (Val >= Threshold) {
179 Emit(((uint32_t)Val & ((1 << (NumBits-1))-1)) |
180 (1 << (NumBits-1)), NumBits);
184 Emit((uint32_t)Val, NumBits);
189 Emit(Val, CurCodeSize);
200 if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
201 return &BlockInfoRecords.back();
203 for (
unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size());
205 if (BlockInfoRecords[i].BlockID == BlockID)
206 return &BlockInfoRecords[i];
218 unsigned BlockSizeWordIndex = GetWordIndex();
219 unsigned OldCodeSize = CurCodeSize;
224 CurCodeSize = CodeLen;
228 BlockScope.push_back(Block(OldCodeSize, BlockSizeWordIndex));
229 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
234 for (
unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size());
236 CurAbbrevs.push_back(Info->Abbrevs[i]);
237 Info->Abbrevs[i]->addRef();
243 assert(!BlockScope.empty() &&
"Block scope imbalance!");
246 for (
unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size());
248 CurAbbrevs[i]->dropRef();
250 const Block &B = BlockScope.back();
258 unsigned SizeInWords = GetWordIndex() - B.StartSizeWord - 1;
259 unsigned ByteNo = B.StartSizeWord*4;
262 BackpatchWord(ByteNo, SizeInWords);
265 CurCodeSize = B.PrevCodeSize;
266 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
267 BlockScope.pop_back();
277 template<
typename u
intty>
279 assert(Op.
isLiteral() &&
"Not a literal");
283 "Invalid abbrev for record!");
288 template<
typename u
intty>
289 void EmitAbbreviatedField(
const BitCodeAbbrevOp &Op, uintty V) {
290 assert(!Op.isLiteral() &&
"Literals should use EmitAbbreviatedLiteral!");
293 switch (Op.getEncoding()) {
296 if (Op.getEncodingData())
300 if (Op.getEncodingData())
301 EmitVBR64(V, (
unsigned)Op.getEncodingData());
313 template<
typename u
intty>
314 void EmitRecordWithAbbrevImpl(
unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
316 const char *BlobData = Blob.data();
317 unsigned BlobLen = (
unsigned) Blob.size();
319 assert(AbbrevNo < CurAbbrevs.size() &&
"Invalid abbrev #!");
320 BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo];
324 unsigned RecordIdx = 0;
325 for (
unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos());
327 const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
328 if (Op.isLiteral()) {
329 assert(RecordIdx < Vals.size() &&
"Invalid abbrev/record");
330 EmitAbbreviatedLiteral(Op, Vals[RecordIdx]);
334 assert(i+2 == e &&
"array op not second to last?");
335 const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
340 assert(RecordIdx == Vals.size() &&
341 "Blob data and record entries specified for array!");
343 EmitVBR(static_cast<uint32_t>(BlobLen), 6);
346 for (
unsigned i = 0; i != BlobLen; ++i)
347 EmitAbbreviatedField(EltEnc, (
unsigned char)BlobData[i]);
353 EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
356 for (
unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx)
357 EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
365 EmitVBR(static_cast<uint32_t>(BlobLen), 6);
366 assert(RecordIdx == Vals.size() &&
367 "Blob data and record entries specified for blob operand!");
369 EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
377 for (
unsigned i = 0; i != BlobLen; ++i)
378 WriteByte((
unsigned char)BlobData[i]);
383 for (
unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx) {
385 "Value too large to emit as blob");
386 WriteByte((
unsigned char)Vals[RecordIdx]);
391 while (GetBufferOffset() & 3)
394 assert(RecordIdx < Vals.size() &&
"Invalid abbrev/record");
395 EmitAbbreviatedField(Op, Vals[RecordIdx]);
399 assert(RecordIdx == Vals.size() &&
"Not all record operands emitted!");
400 assert(BlobData == 0 &&
401 "Blob data specified for record that doesn't use it!");
408 template<
typename u
intty>
410 unsigned Abbrev = 0) {
417 for (
unsigned i = 0, e = static_cast<unsigned>(Vals.
size()); i != e; ++i)
431 template<
typename u
intty>
433 EmitRecordWithAbbrevImpl(Abbrev, Vals,
StringRef());
441 template<
typename u
intty>
444 EmitRecordWithAbbrevImpl(Abbrev, Vals, Blob);
446 template<
typename u
intty>
448 const char *BlobData,
unsigned BlobLen) {
449 return EmitRecordWithAbbrevImpl(Abbrev, Vals,
StringRef(BlobData, BlobLen));
454 template<
typename u
intty>
457 EmitRecordWithAbbrevImpl(Abbrev, Vals, Array);
459 template<
typename u
intty>
461 const char *ArrayData,
unsigned ArrayLen) {
462 return EmitRecordWithAbbrevImpl(Abbrev, Vals,
StringRef(ArrayData,
495 CurAbbrevs.push_back(Abbv);
496 return static_cast<unsigned>(CurAbbrevs.size())-1 +
497 bitc::FIRST_APPLICATION_ABBREV;
507 BlockInfoCurBID = ~0U;
512 void SwitchToBlockID(
unsigned BlockID) {
513 if (BlockInfoCurBID == BlockID)
return;
517 BlockInfoCurBID = BlockID;
520 BlockInfo &getOrCreateBlockInfo(
unsigned BlockID) {
525 BlockInfoRecords.push_back(BlockInfo());
526 BlockInfoRecords.back().BlockID = BlockID;
527 return BlockInfoRecords.back();
535 SwitchToBlockID(BlockID);
539 BlockInfo &Info = getOrCreateBlockInfo(BlockID);
540 Info.Abbrevs.push_back(Abbv);
bool isUInt< 8 >(uint64_t x)
void push_back(const T &Elt)
void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl< uintty > &Vals, const char *ArrayData, unsigned ArrayLen)
const BitCodeAbbrevOp & getOperandInfo(unsigned N) const
iterator insert(iterator I, const T &Elt)
void EmitRecord(unsigned Code, SmallVectorImpl< uintty > &Vals, unsigned Abbrev=0)
static unsigned EncodeChar6(char C)
uint64_t GetCurrentBitNo() const
Retrieve the current position in the stream, in bits.
void EnterBlockInfoBlock(unsigned CodeWidth)
EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK.
#define llvm_unreachable(msg)
void Emit(uint32_t Val, unsigned NumBits)
uint64_t getEncodingData() const
void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl< uintty > &Vals, StringRef Array)
void EnterSubblock(unsigned BlockID, unsigned CodeLen)
bool hasEncodingData() const
void EmitCode(unsigned Val)
EmitCode - Emit the specified code.
unsigned EmitAbbrev(BitCodeAbbrev *Abbv)
unsigned EmitBlockInfoAbbrev(unsigned BlockID, BitCodeAbbrev *Abbv)
void EmitVBR(uint32_t Val, unsigned NumBits)
void append(in_iter in_start, in_iter in_end)
uint64_t getLiteralValue() const
BlockInfo * getBlockInfo(unsigned BlockID)
void EmitRecordWithBlob(unsigned Abbrev, SmallVectorImpl< uintty > &Vals, StringRef Blob)
void EmitRecordWithAbbrev(unsigned Abbrev, SmallVectorImpl< uintty > &Vals)
void Emit64(uint64_t Val, unsigned NumBits)
BitstreamWriter(SmallVectorImpl< char > &O)
static int const Threshold
unsigned getNumOperandInfos() const
void EmitVBR64(uint64_t Val, unsigned NumBits)
LLVM Value Representation.
void EmitRecordWithBlob(unsigned Abbrev, SmallVectorImpl< uintty > &Vals, const char *BlobData, unsigned BlobLen)
Encoding getEncoding() const