15 #ifndef LLVM_BITCODE_BITSTREAMWRITER_H
16 #define LLVM_BITCODE_BITSTREAMWRITER_H
41 unsigned BlockInfoCurBID;
44 std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> CurAbbrevs;
47 unsigned PrevCodeSize;
48 unsigned StartSizeWord;
49 std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> PrevAbbrevs;
50 Block(
unsigned PCS,
unsigned SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {}
54 std::vector<Block> BlockScope;
60 std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> Abbrevs;
62 std::vector<BlockInfo> BlockInfoRecords;
66 void BackpatchWord(
unsigned ByteNo,
unsigned NewWord) {
70 void WriteByte(
unsigned char Value) {
74 void WriteWord(
unsigned Value) {
75 Value = support::endian::byte_swap<uint32_t, support::little>(Value);
76 Out.
append(reinterpret_cast<const char *>(&Value),
77 reinterpret_cast<const char *>(&Value + 1));
80 unsigned GetBufferOffset()
const {
84 unsigned GetWordIndex()
const {
85 unsigned Offset = GetBufferOffset();
86 assert((Offset & 3) == 0 &&
"Not 32-bit aligned");
92 : Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {}
95 assert(CurBit == 0 &&
"Unflushed data remaining");
96 assert(BlockScope.empty() && CurAbbrevs.empty() &&
"Block imbalance");
106 void Emit(uint32_t Val,
unsigned NumBits) {
107 assert(NumBits && NumBits <= 32 &&
"Invalid value size!");
108 assert((Val & ~(~0U >> (32-NumBits))) == 0 &&
"High bits set!");
109 CurValue |= Val << CurBit;
110 if (CurBit + NumBits < 32) {
119 CurValue = Val >> (32-CurBit);
122 CurBit = (CurBit+NumBits) & 31;
125 void Emit64(uint64_t Val,
unsigned NumBits) {
127 Emit((uint32_t)Val, NumBits);
129 Emit((uint32_t)Val, 32);
130 Emit((uint32_t)(Val >> 32), NumBits-32);
142 void EmitVBR(uint32_t Val,
unsigned NumBits) {
143 assert(NumBits <= 32 &&
"Too many bits to emit!");
147 while (Val >= Threshold) {
148 Emit((Val & ((1 << (NumBits-1))-1)) | (1 << (NumBits-1)), NumBits);
156 assert(NumBits <= 32 &&
"Too many bits to emit!");
157 if ((uint32_t)Val == Val)
158 return EmitVBR((uint32_t)Val, NumBits);
163 while (Val >= Threshold) {
164 Emit(((uint32_t)Val & ((1 << (NumBits-1))-1)) |
165 (1 << (NumBits-1)), NumBits);
169 Emit((uint32_t)Val, NumBits);
174 Emit(Val, CurCodeSize);
185 if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
186 return &BlockInfoRecords.back();
188 for (
unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size());
190 if (BlockInfoRecords[i].BlockID == BlockID)
191 return &BlockInfoRecords[i];
203 unsigned BlockSizeWordIndex = GetWordIndex();
204 unsigned OldCodeSize = CurCodeSize;
209 CurCodeSize = CodeLen;
213 BlockScope.emplace_back(OldCodeSize, BlockSizeWordIndex);
214 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
219 CurAbbrevs.insert(CurAbbrevs.end(), Info->Abbrevs.begin(),
220 Info->Abbrevs.end());
225 assert(!BlockScope.empty() &&
"Block scope imbalance!");
226 const Block &B = BlockScope.back();
234 unsigned SizeInWords = GetWordIndex() - B.StartSizeWord - 1;
235 unsigned ByteNo = B.StartSizeWord*4;
238 BackpatchWord(ByteNo, SizeInWords);
241 CurCodeSize = B.PrevCodeSize;
242 CurAbbrevs = std::move(B.PrevAbbrevs);
243 BlockScope.pop_back();
253 template<
typename u
intty>
255 assert(Op.
isLiteral() &&
"Not a literal");
259 "Invalid abbrev for record!");
264 template<
typename u
intty>
265 void EmitAbbreviatedField(
const BitCodeAbbrevOp &Op, uintty V) {
266 assert(!Op.isLiteral() &&
"Literals should use EmitAbbreviatedLiteral!");
269 switch (Op.getEncoding()) {
272 if (Op.getEncodingData())
276 if (Op.getEncodingData())
277 EmitVBR64(V, (
unsigned)Op.getEncodingData());
289 template<
typename u
intty>
290 void EmitRecordWithAbbrevImpl(
unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
292 const char *BlobData = Blob.data();
293 unsigned BlobLen = (
unsigned) Blob.size();
295 assert(AbbrevNo < CurAbbrevs.size() &&
"Invalid abbrev #!");
296 const BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo].get();
300 unsigned RecordIdx = 0;
301 for (
unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos());
303 const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
304 if (Op.isLiteral()) {
305 assert(RecordIdx < Vals.size() &&
"Invalid abbrev/record");
306 EmitAbbreviatedLiteral(Op, Vals[RecordIdx]);
310 assert(i+2 == e &&
"array op not second to last?");
311 const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
316 assert(RecordIdx == Vals.size() &&
317 "Blob data and record entries specified for array!");
319 EmitVBR(static_cast<uint32_t>(BlobLen), 6);
322 for (
unsigned i = 0; i != BlobLen; ++i)
323 EmitAbbreviatedField(EltEnc, (
unsigned char)BlobData[i]);
329 EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
332 for (
unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx)
333 EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
341 EmitVBR(static_cast<uint32_t>(BlobLen), 6);
342 assert(RecordIdx == Vals.size() &&
343 "Blob data and record entries specified for blob operand!");
345 EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
353 for (
unsigned i = 0; i != BlobLen; ++i)
354 WriteByte((
unsigned char)BlobData[i]);
359 for (
unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx) {
361 "Value too large to emit as blob");
362 WriteByte((
unsigned char)Vals[RecordIdx]);
367 while (GetBufferOffset() & 3)
370 assert(RecordIdx < Vals.size() &&
"Invalid abbrev/record");
371 EmitAbbreviatedField(Op, Vals[RecordIdx]);
375 assert(RecordIdx == Vals.size() &&
"Not all record operands emitted!");
376 assert(BlobData ==
nullptr &&
377 "Blob data specified for record that doesn't use it!");
384 template<
typename u
intty>
386 unsigned Abbrev = 0) {
393 for (
unsigned i = 0, e = static_cast<unsigned>(Vals.
size()); i != e; ++i)
407 template<
typename u
intty>
409 EmitRecordWithAbbrevImpl(Abbrev, Vals,
StringRef());
417 template<
typename u
intty>
420 EmitRecordWithAbbrevImpl(Abbrev, Vals, Blob);
422 template<
typename u
intty>
424 const char *BlobData,
unsigned BlobLen) {
425 return EmitRecordWithAbbrevImpl(Abbrev, Vals,
StringRef(BlobData, BlobLen));
430 template<
typename u
intty>
433 EmitRecordWithAbbrevImpl(Abbrev, Vals, Array);
435 template<
typename u
intty>
437 const char *ArrayData,
unsigned ArrayLen) {
438 return EmitRecordWithAbbrevImpl(Abbrev, Vals,
StringRef(ArrayData,
471 CurAbbrevs.push_back(Abbv);
472 return static_cast<unsigned>(CurAbbrevs.size())-1 +
473 bitc::FIRST_APPLICATION_ABBREV;
483 BlockInfoCurBID = ~0U;
488 void SwitchToBlockID(
unsigned BlockID) {
489 if (BlockInfoCurBID == BlockID)
return;
493 BlockInfoCurBID = BlockID;
496 BlockInfo &getOrCreateBlockInfo(
unsigned BlockID) {
501 BlockInfoRecords.emplace_back();
502 BlockInfoRecords.back().BlockID = BlockID;
503 return BlockInfoRecords.back();
511 SwitchToBlockID(BlockID);
515 BlockInfo &Info = getOrCreateBlockInfo(BlockID);
516 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)
BLOCKINFO_BLOCK is used to define metadata about blocks, for example, standard abbrevs that should be...
BitCodeAbbrev - This class represents an abbreviation record.
const BitCodeAbbrevOp & getOperandInfo(unsigned N) const
void EmitRecord(unsigned Code, SmallVectorImpl< uintty > &Vals, unsigned Abbrev=0)
EmitRecord - Emit the specified record to the stream, using an abbrev if we have one to compress the ...
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)
Marks that the current location is not supposed to be reachable.
void Emit(uint32_t Val, unsigned NumBits)
uint64_t getEncodingData() const
void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl< uintty > &Vals, StringRef Array)
EmitRecordWithArray - Just like EmitRecordWithBlob, works with records that end with an array...
void EnterSubblock(unsigned BlockID, unsigned CodeLen)
bool hasEncodingData() const
void EmitCode(unsigned Val)
EmitCode - Emit the specified code.
unsigned EmitAbbrev(BitCodeAbbrev *Abbv)
EmitAbbrev - This emits an abbreviation to the stream.
BitCodeAbbrevOp - This describes one or more operands in an abbreviation.
unsigned EmitBlockInfoAbbrev(unsigned BlockID, BitCodeAbbrev *Abbv)
EmitBlockInfoAbbrev - Emit a DEFINE_ABBREV record for the specified BlockID.
void write32le(void *p, uint32_t v)
void EmitVBR(uint32_t Val, unsigned NumBits)
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
uint64_t getLiteralValue() const
BlockInfo * getBlockInfo(unsigned BlockID)
getBlockInfo - If there is block info for the specified ID, return it, otherwise return null...
void EmitRecordWithBlob(unsigned Abbrev, SmallVectorImpl< uintty > &Vals, StringRef Blob)
EmitRecordWithBlob - Emit the specified record to the stream, using an abbrev that includes a blob at...
void EmitRecordWithAbbrev(unsigned Abbrev, SmallVectorImpl< uintty > &Vals)
EmitRecordWithAbbrev - Emit a record with the specified abbreviation.
void Emit64(uint64_t Val, unsigned NumBits)
DEFINE_ABBREV - Defines an abbrev for the current block.
iterator insert(iterator I, T &&Elt)
BitstreamWriter(SmallVectorImpl< char > &O)
static int const Threshold
TODO: Write a new FunctionPass AliasAnalysis so that it can keep a cache.
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)
StringRef - Represent a constant reference to a string, i.e.
Encoding getEncoding() const