15 #ifndef LLVM_BITCODE_BITSTREAMWRITER_H 16 #define LLVM_BITCODE_BITSTREAMWRITER_H 43 unsigned BlockInfoCurBID;
46 std::vector<std::shared_ptr<BitCodeAbbrev>> CurAbbrevs;
49 unsigned PrevCodeSize;
51 std::vector<std::shared_ptr<BitCodeAbbrev>> PrevAbbrevs;
52 Block(
unsigned PCS,
size_t SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {}
56 std::vector<Block> BlockScope;
62 std::vector<std::shared_ptr<BitCodeAbbrev>> Abbrevs;
64 std::vector<BlockInfo> BlockInfoRecords;
66 void WriteByte(
unsigned char Value) {
70 void WriteWord(
unsigned Value) {
71 Value = support::endian::byte_swap<uint32_t, support::little>(Value);
72 Out.
append(reinterpret_cast<const char *>(&Value),
73 reinterpret_cast<const char *>(&Value + 1));
76 size_t GetBufferOffset()
const {
return Out.
size(); }
78 size_t GetWordIndex()
const {
79 size_t Offset = GetBufferOffset();
80 assert((Offset & 3) == 0 &&
"Not 32-bit aligned");
86 : Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {}
89 assert(CurBit == 0 &&
"Unflushed data remaining");
90 assert(BlockScope.empty() && CurAbbrevs.empty() &&
"Block imbalance");
107 unsigned ByteNo = BitNo / 8;
108 assert((!endian::readAtBitAlignment<uint32_t, little, unaligned>(
109 &Out[ByteNo], BitNo & 7)) &&
110 "Expected to be patching over 0-value placeholders");
111 endian::writeAtBitAlignment<uint32_t, little, unaligned>(
112 &Out[ByteNo], NewWord, BitNo & 7);
121 assert(NumBits && NumBits <= 32 &&
"Invalid value size!");
122 assert((Val & ~(~0U >> (32-NumBits))) == 0 &&
"High bits set!");
123 CurValue |= Val << CurBit;
124 if (CurBit + NumBits < 32) {
133 CurValue = Val >> (32-CurBit);
136 CurBit = (CurBit+NumBits) & 31;
148 assert(NumBits <= 32 &&
"Too many bits to emit!");
152 while (Val >= Threshold) {
153 Emit((Val & ((1 << (NumBits-1))-1)) | (1 << (NumBits-1)), NumBits);
161 assert(NumBits <= 32 &&
"Too many bits to emit!");
168 while (Val >= Threshold) {
170 (1 << (NumBits-1)), NumBits);
179 Emit(Val, CurCodeSize);
190 if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
191 return &BlockInfoRecords.back();
193 for (
unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size());
195 if (BlockInfoRecords[i].BlockID == BlockID)
196 return &BlockInfoRecords[i];
208 size_t BlockSizeWordIndex = GetWordIndex();
209 unsigned OldCodeSize = CurCodeSize;
214 CurCodeSize = CodeLen;
218 BlockScope.emplace_back(OldCodeSize, BlockSizeWordIndex);
219 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
224 CurAbbrevs.insert(CurAbbrevs.end(),
Info->Abbrevs.begin(),
225 Info->Abbrevs.end());
230 assert(!BlockScope.empty() &&
"Block scope imbalance!");
231 const Block &
B = BlockScope.back();
239 size_t SizeInWords = GetWordIndex() - B.StartSizeWord - 1;
240 uint64_t BitNo = uint64_t(B.StartSizeWord) * 32;
246 CurCodeSize = B.PrevCodeSize;
247 CurAbbrevs = std::move(B.PrevAbbrevs);
248 BlockScope.pop_back();
258 template<
typename u
intty>
264 "Invalid abbrev for record!");
269 template<
typename u
intty>
271 assert(!Op.
isLiteral() &&
"Literals should use EmitAbbreviatedLiteral!");
296 template <
typename u
intty>
299 const char *BlobData = Blob.
data();
302 assert(AbbrevNo < CurAbbrevs.size() &&
"Invalid abbrev #!");
307 unsigned i = 0, e =
static_cast<unsigned>(Abbv->getNumOperandInfos());
309 assert(e &&
"Expected non-empty abbreviation");
313 EmitAbbreviatedLiteral(Op, Code.
getValue());
317 "Expected literal or scalar");
318 EmitAbbreviatedField(Op, Code.
getValue());
322 unsigned RecordIdx = 0;
323 for (; i != e; ++i) {
326 assert(RecordIdx < Vals.
size() &&
"Invalid abbrev/record");
327 EmitAbbreviatedLiteral(Op, Vals[RecordIdx]);
331 assert(i + 2 == e &&
"array op not second to last?");
338 "Blob data and record entries specified for array!");
340 EmitVBR(static_cast<uint32_t>(BlobLen), 6);
343 for (
unsigned i = 0; i != BlobLen; ++i)
344 EmitAbbreviatedField(EltEnc, (
unsigned char)BlobData[i]);
350 EmitVBR(static_cast<uint32_t>(Vals.
size()-RecordIdx), 6);
353 for (
unsigned e = Vals.
size(); RecordIdx != e; ++RecordIdx)
354 EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
362 "Blob data and record entries specified for blob operand!");
364 assert(Blob.
data() == BlobData &&
"BlobData got moved");
365 assert(Blob.
size() == BlobLen &&
"BlobLen got changed");
372 assert(RecordIdx < Vals.
size() &&
"Invalid abbrev/record");
373 EmitAbbreviatedField(Op, Vals[RecordIdx]);
377 assert(RecordIdx == Vals.
size() &&
"Not all record operands emitted!");
378 assert(BlobData ==
nullptr &&
379 "Blob data specified for record that doesn't use it!");
384 template <
class UIntTy>
394 for (
const auto &
B : Bytes) {
396 WriteByte((
unsigned char)
B);
400 while (GetBufferOffset() & 3)
410 template <
typename Container>
411 void EmitRecord(
unsigned Code,
const Container &Vals,
unsigned Abbrev = 0) {
419 for (
unsigned i = 0, e = Count; i != e; ++i)
430 template <
typename Container>
440 template <
typename Container>
445 template <
typename Container>
447 const char *BlobData,
unsigned BlobLen) {
448 return EmitRecordWithAbbrevImpl(Abbrev,
makeArrayRef(Vals),
454 template <
typename Container>
459 template <
typename Container>
461 const char *ArrayData,
unsigned ArrayLen) {
462 return EmitRecordWithAbbrevImpl(Abbrev,
makeArrayRef(Vals),
495 CurAbbrevs.push_back(std::move(Abbv));
496 return static_cast<unsigned>(CurAbbrevs.size())-1 +
507 BlockInfoCurBID = ~0U;
508 BlockInfoRecords.clear();
513 void SwitchToBlockID(
unsigned BlockID) {
514 if (BlockInfoCurBID == BlockID)
return;
518 BlockInfoCurBID = BlockID;
521 BlockInfo &getOrCreateBlockInfo(
unsigned BlockID) {
526 BlockInfoRecords.emplace_back();
527 BlockInfoRecords.back().BlockID = BlockID;
528 return BlockInfoRecords.back();
536 SwitchToBlockID(BlockID);
540 BlockInfo &
Info = getOrCreateBlockInfo(BlockID);
541 Info.Abbrevs.push_back(std::move(Abbv));
Encoding getEncoding() const
BLOCKINFO_BLOCK is used to define metadata about blocks, for example, standard abbrevs that should be...
This class represents lattice values for constants.
void push_back(const T &Elt)
BitCodeAbbrev - This class represents an abbreviation record.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
uint64_t GetCurrentBitNo() const
Retrieve the current position in the stream, in bits.
unsigned GetAbbrevIDWidth() const
Retrieve the number of bits currently used to encode an abbrev ID.
uint64_t getLiteralValue() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
static unsigned EncodeChar6(char C)
void EmitRecordWithArray(unsigned Abbrev, const Container &Vals, const char *ArrayData, unsigned ArrayLen)
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
void BackpatchWord(uint64_t BitNo, unsigned NewWord)
Backpatch a 32-bit word in the output at the given bit offset with the specified value.
void Emit(uint32_t Val, unsigned NumBits)
void EnterBlockInfoBlock()
EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK.
void EmitRecordWithAbbrev(unsigned Abbrev, const Container &Vals)
EmitRecordWithAbbrev - Emit a record with the specified abbreviation.
const T & getValue() const LLVM_LVALUE_FUNCTION
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
const BitCodeAbbrevOp & getOperandInfo(unsigned N) const
void EmitRecord(unsigned Code, const Container &Vals, unsigned Abbrev=0)
EmitRecord - Emit the specified record to the stream, using an abbrev if we have one to compress the ...
void EnterSubblock(unsigned BlockID, unsigned CodeLen)
Analysis containing CSE Info
void BackpatchWord64(uint64_t BitNo, uint64_t Val)
void EmitCode(unsigned Val)
EmitCode - Emit the specified code.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
constexpr bool isUInt< 8 >(uint64_t x)
size_t size() const
size - Get the array size.
void EmitRecordWithBlob(unsigned Abbrev, const Container &Vals, const char *BlobData, unsigned BlobLen)
BitCodeAbbrevOp - This describes one or more operands in an abbreviation.
void EmitVBR(uint32_t Val, unsigned NumBits)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void emitBlob(StringRef Bytes, bool ShouldEmitSize=true)
unsigned EmitAbbrev(std::shared_ptr< BitCodeAbbrev > Abbv)
EmitAbbrev - This emits an abbreviation to the stream.
BlockInfo * getBlockInfo(unsigned BlockID)
getBlockInfo - If there is block info for the specified ID, return it, otherwise return null...
void EmitRecordWithArray(unsigned Abbrev, const Container &Vals, StringRef Array)
EmitRecordWithArray - Just like EmitRecordWithBlob, works with records that end with an array...
void EmitRecordWithBlob(unsigned Abbrev, const Container &Vals, StringRef Blob)
EmitRecordWithBlob - Emit the specified record to the stream, using an abbrev that includes a blob at...
DEFINE_ABBREV - Defines an abbrev for the current block.
static cl::opt< unsigned > Threshold("loop-unswitch-threshold", cl::desc("Max loop size to unswitch"), cl::init(100), cl::Hidden)
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array...
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
unsigned getNumOperandInfos() const
uint64_t getEncodingData() const
BitstreamWriter(SmallVectorImpl< char > &O)
bool hasEncodingData() const
void EmitVBR64(uint64_t Val, unsigned NumBits)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
StringRef - Represent a constant reference to a string, i.e.
void emitBlob(ArrayRef< UIntTy > Bytes, bool ShouldEmitSize=true)
Emit a blob, including flushing before and tail-padding.
unsigned EmitBlockInfoAbbrev(unsigned BlockID, std::shared_ptr< BitCodeAbbrev > Abbv)
EmitBlockInfoAbbrev - Emit a DEFINE_ABBREV record for the specified BlockID.