LLVM 17.0.0git
BitstreamWriter.h
Go to the documentation of this file.
1//===- BitstreamWriter.h - Low-level bitstream writer interface -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This header defines the BitstreamWriter class. This class can be used to
10// write an arbitrary bitstream, regardless of its contents.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_BITSTREAM_BITSTREAMWRITER_H
15#define LLVM_BITSTREAM_BITSTREAMWRITER_H
16
17#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/StringRef.h"
21#include "llvm/Support/Endian.h"
24#include <algorithm>
25#include <optional>
26#include <vector>
27
28namespace llvm {
29
31 /// Out - The buffer that keeps unflushed bytes.
33
34 /// FS - The file stream that Out flushes to. If FS is nullptr, it does not
35 /// support read or seek, Out cannot be flushed until all data are written.
36 raw_fd_stream *FS;
37
38 /// FlushThreshold - If FS is valid, this is the threshold (unit B) to flush
39 /// FS.
40 const uint64_t FlushThreshold;
41
42 /// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use.
43 unsigned CurBit;
44
45 /// CurValue - The current value. Only bits < CurBit are valid.
46 uint32_t CurValue;
47
48 /// CurCodeSize - This is the declared size of code values used for the
49 /// current block, in bits.
50 unsigned CurCodeSize;
51
52 /// BlockInfoCurBID - When emitting a BLOCKINFO_BLOCK, this is the currently
53 /// selected BLOCK ID.
54 unsigned BlockInfoCurBID;
55
56 /// CurAbbrevs - Abbrevs installed at in this block.
57 std::vector<std::shared_ptr<BitCodeAbbrev>> CurAbbrevs;
58
59 struct Block {
60 unsigned PrevCodeSize;
61 size_t StartSizeWord;
62 std::vector<std::shared_ptr<BitCodeAbbrev>> PrevAbbrevs;
63 Block(unsigned PCS, size_t SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {}
64 };
65
66 /// BlockScope - This tracks the current blocks that we have entered.
67 std::vector<Block> BlockScope;
68
69 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks.
70 /// These describe abbreviations that all blocks of the specified ID inherit.
71 struct BlockInfo {
72 unsigned BlockID;
73 std::vector<std::shared_ptr<BitCodeAbbrev>> Abbrevs;
74 };
75 std::vector<BlockInfo> BlockInfoRecords;
76
77 void WriteWord(unsigned Value) {
78 Value = support::endian::byte_swap<uint32_t, support::little>(Value);
79 Out.append(reinterpret_cast<const char *>(&Value),
80 reinterpret_cast<const char *>(&Value + 1));
81 }
82
83 uint64_t GetNumOfFlushedBytes() const { return FS ? FS->tell() : 0; }
84
85 size_t GetBufferOffset() const { return Out.size() + GetNumOfFlushedBytes(); }
86
87 size_t GetWordIndex() const {
88 size_t Offset = GetBufferOffset();
89 assert((Offset & 3) == 0 && "Not 32-bit aligned");
90 return Offset / 4;
91 }
92
93 /// If the related file stream supports reading, seeking and writing, flush
94 /// the buffer if its size is above a threshold.
95 void FlushToFile() {
96 if (!FS)
97 return;
98 if (Out.size() < FlushThreshold)
99 return;
100 FS->write((char *)&Out.front(), Out.size());
101 Out.clear();
102 }
103
104public:
105 /// Create a BitstreamWriter that writes to Buffer \p O.
106 ///
107 /// \p FS is the file stream that \p O flushes to incrementally. If \p FS is
108 /// null, \p O does not flush incrementially, but writes to disk at the end.
109 ///
110 /// \p FlushThreshold is the threshold (unit M) to flush \p O if \p FS is
111 /// valid. Flushing only occurs at (sub)block boundaries.
113 uint32_t FlushThreshold = 512)
114 : Out(O), FS(FS), FlushThreshold(FlushThreshold << 20), CurBit(0),
115 CurValue(0), CurCodeSize(2) {}
116
118 assert(CurBit == 0 && "Unflushed data remaining");
119 assert(BlockScope.empty() && CurAbbrevs.empty() && "Block imbalance");
120 }
121
122 /// Retrieve the current position in the stream, in bits.
123 uint64_t GetCurrentBitNo() const { return GetBufferOffset() * 8 + CurBit; }
124
125 /// Retrieve the number of bits currently used to encode an abbrev ID.
126 unsigned GetAbbrevIDWidth() const { return CurCodeSize; }
127
128 //===--------------------------------------------------------------------===//
129 // Basic Primitives for emitting bits to the stream.
130 //===--------------------------------------------------------------------===//
131
132 /// Backpatch a 32-bit word in the output at the given bit offset
133 /// with the specified value.
134 void BackpatchWord(uint64_t BitNo, unsigned NewWord) {
135 using namespace llvm::support;
136 uint64_t ByteNo = BitNo / 8;
137 uint64_t StartBit = BitNo & 7;
138 uint64_t NumOfFlushedBytes = GetNumOfFlushedBytes();
139
140 if (ByteNo >= NumOfFlushedBytes) {
141 assert((!endian::readAtBitAlignment<uint32_t, little, unaligned>(
142 &Out[ByteNo - NumOfFlushedBytes], StartBit)) &&
143 "Expected to be patching over 0-value placeholders");
144 endian::writeAtBitAlignment<uint32_t, little, unaligned>(
145 &Out[ByteNo - NumOfFlushedBytes], NewWord, StartBit);
146 return;
147 }
148
149 // If the byte offset to backpatch is flushed, use seek to backfill data.
150 // First, save the file position to restore later.
151 uint64_t CurPos = FS->tell();
152
153 // Copy data to update into Bytes from the file FS and the buffer Out.
154 char Bytes[9]; // Use one more byte to silence a warning from Visual C++.
155 size_t BytesNum = StartBit ? 8 : 4;
156 size_t BytesFromDisk = std::min(static_cast<uint64_t>(BytesNum), NumOfFlushedBytes - ByteNo);
157 size_t BytesFromBuffer = BytesNum - BytesFromDisk;
158
159 // When unaligned, copy existing data into Bytes from the file FS and the
160 // buffer Out so that it can be updated before writing. For debug builds
161 // read bytes unconditionally in order to check that the existing value is 0
162 // as expected.
163#ifdef NDEBUG
164 if (StartBit)
165#endif
166 {
167 FS->seek(ByteNo);
168 ssize_t BytesRead = FS->read(Bytes, BytesFromDisk);
169 (void)BytesRead; // silence warning
170 assert(BytesRead >= 0 && static_cast<size_t>(BytesRead) == BytesFromDisk);
171 for (size_t i = 0; i < BytesFromBuffer; ++i)
172 Bytes[BytesFromDisk + i] = Out[i];
173 assert((!endian::readAtBitAlignment<uint32_t, little, unaligned>(
174 Bytes, StartBit)) &&
175 "Expected to be patching over 0-value placeholders");
176 }
177
178 // Update Bytes in terms of bit offset and value.
179 endian::writeAtBitAlignment<uint32_t, little, unaligned>(Bytes, NewWord,
180 StartBit);
181
182 // Copy updated data back to the file FS and the buffer Out.
183 FS->seek(ByteNo);
184 FS->write(Bytes, BytesFromDisk);
185 for (size_t i = 0; i < BytesFromBuffer; ++i)
186 Out[i] = Bytes[BytesFromDisk + i];
187
188 // Restore the file position.
189 FS->seek(CurPos);
190 }
191
193 BackpatchWord(BitNo, (uint32_t)Val);
194 BackpatchWord(BitNo + 32, (uint32_t)(Val >> 32));
195 }
196
197 void Emit(uint32_t Val, unsigned NumBits) {
198 assert(NumBits && NumBits <= 32 && "Invalid value size!");
199 assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!");
200 CurValue |= Val << CurBit;
201 if (CurBit + NumBits < 32) {
202 CurBit += NumBits;
203 return;
204 }
205
206 // Add the current word.
207 WriteWord(CurValue);
208
209 if (CurBit)
210 CurValue = Val >> (32-CurBit);
211 else
212 CurValue = 0;
213 CurBit = (CurBit+NumBits) & 31;
214 }
215
216 void FlushToWord() {
217 if (CurBit) {
218 WriteWord(CurValue);
219 CurBit = 0;
220 CurValue = 0;
221 }
222 }
223
224 void EmitVBR(uint32_t Val, unsigned NumBits) {
225 assert(NumBits <= 32 && "Too many bits to emit!");
226 uint32_t Threshold = 1U << (NumBits-1);
227
228 // Emit the bits with VBR encoding, NumBits-1 bits at a time.
229 while (Val >= Threshold) {
230 Emit((Val & ((1 << (NumBits-1))-1)) | (1 << (NumBits-1)), NumBits);
231 Val >>= NumBits-1;
232 }
233
234 Emit(Val, NumBits);
235 }
236
237 void EmitVBR64(uint64_t Val, unsigned NumBits) {
238 assert(NumBits <= 32 && "Too many bits to emit!");
239 if ((uint32_t)Val == Val)
240 return EmitVBR((uint32_t)Val, NumBits);
241
242 uint32_t Threshold = 1U << (NumBits-1);
243
244 // Emit the bits with VBR encoding, NumBits-1 bits at a time.
245 while (Val >= Threshold) {
246 Emit(((uint32_t)Val & ((1 << (NumBits - 1)) - 1)) | (1 << (NumBits - 1)),
247 NumBits);
248 Val >>= NumBits-1;
249 }
250
251 Emit((uint32_t)Val, NumBits);
252 }
253
254 /// EmitCode - Emit the specified code.
255 void EmitCode(unsigned Val) {
256 Emit(Val, CurCodeSize);
257 }
258
259 //===--------------------------------------------------------------------===//
260 // Block Manipulation
261 //===--------------------------------------------------------------------===//
262
263 /// getBlockInfo - If there is block info for the specified ID, return it,
264 /// otherwise return null.
265 BlockInfo *getBlockInfo(unsigned BlockID) {
266 // Common case, the most recent entry matches BlockID.
267 if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
268 return &BlockInfoRecords.back();
269
270 for (BlockInfo &BI : BlockInfoRecords)
271 if (BI.BlockID == BlockID)
272 return &BI;
273 return nullptr;
274 }
275
276 void EnterSubblock(unsigned BlockID, unsigned CodeLen) {
277 // Block header:
278 // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen]
280 EmitVBR(BlockID, bitc::BlockIDWidth);
281 EmitVBR(CodeLen, bitc::CodeLenWidth);
282 FlushToWord();
283
284 size_t BlockSizeWordIndex = GetWordIndex();
285 unsigned OldCodeSize = CurCodeSize;
286
287 // Emit a placeholder, which will be replaced when the block is popped.
289
290 CurCodeSize = CodeLen;
291
292 // Push the outer block's abbrev set onto the stack, start out with an
293 // empty abbrev set.
294 BlockScope.emplace_back(OldCodeSize, BlockSizeWordIndex);
295 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
296
297 // If there is a blockinfo for this BlockID, add all the predefined abbrevs
298 // to the abbrev list.
299 if (BlockInfo *Info = getBlockInfo(BlockID))
300 append_range(CurAbbrevs, Info->Abbrevs);
301 }
302
303 void ExitBlock() {
304 assert(!BlockScope.empty() && "Block scope imbalance!");
305 const Block &B = BlockScope.back();
306
307 // Block tail:
308 // [END_BLOCK, <align4bytes>]
310 FlushToWord();
311
312 // Compute the size of the block, in words, not counting the size field.
313 size_t SizeInWords = GetWordIndex() - B.StartSizeWord - 1;
314 uint64_t BitNo = uint64_t(B.StartSizeWord) * 32;
315
316 // Update the block size field in the header of this sub-block.
317 BackpatchWord(BitNo, SizeInWords);
318
319 // Restore the inner block's code size and abbrev table.
320 CurCodeSize = B.PrevCodeSize;
321 CurAbbrevs = std::move(B.PrevAbbrevs);
322 BlockScope.pop_back();
323 FlushToFile();
324 }
325
326 //===--------------------------------------------------------------------===//
327 // Record Emission
328 //===--------------------------------------------------------------------===//
329
330private:
331 /// EmitAbbreviatedLiteral - Emit a literal value according to its abbrev
332 /// record. This is a no-op, since the abbrev specifies the literal to use.
333 template<typename uintty>
334 void EmitAbbreviatedLiteral(const BitCodeAbbrevOp &Op, uintty V) {
335 assert(Op.isLiteral() && "Not a literal");
336 // If the abbrev specifies the literal value to use, don't emit
337 // anything.
338 assert(V == Op.getLiteralValue() &&
339 "Invalid abbrev for record!");
340 }
341
342 /// EmitAbbreviatedField - Emit a single scalar field value with the specified
343 /// encoding.
344 template<typename uintty>
345 void EmitAbbreviatedField(const BitCodeAbbrevOp &Op, uintty V) {
346 assert(!Op.isLiteral() && "Literals should use EmitAbbreviatedLiteral!");
347
348 // Encode the value as we are commanded.
349 switch (Op.getEncoding()) {
350 default: llvm_unreachable("Unknown encoding!");
352 if (Op.getEncodingData())
353 Emit((unsigned)V, (unsigned)Op.getEncodingData());
354 break;
356 if (Op.getEncodingData())
357 EmitVBR64(V, (unsigned)Op.getEncodingData());
358 break;
361 break;
362 }
363 }
364
365 /// EmitRecordWithAbbrevImpl - This is the core implementation of the record
366 /// emission code. If BlobData is non-null, then it specifies an array of
367 /// data that should be emitted as part of the Blob or Array operand that is
368 /// known to exist at the end of the record. If Code is specified, then
369 /// it is the record code to emit before the Vals, which must not contain
370 /// the code.
371 template <typename uintty>
372 void EmitRecordWithAbbrevImpl(unsigned Abbrev, ArrayRef<uintty> Vals,
373 StringRef Blob, std::optional<unsigned> Code) {
374 const char *BlobData = Blob.data();
375 unsigned BlobLen = (unsigned) Blob.size();
376 unsigned AbbrevNo = Abbrev-bitc::FIRST_APPLICATION_ABBREV;
377 assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
378 const BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo].get();
379
380 EmitCode(Abbrev);
381
382 unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos());
383 if (Code) {
384 assert(e && "Expected non-empty abbreviation");
385 const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i++);
386
387 if (Op.isLiteral())
388 EmitAbbreviatedLiteral(Op, *Code);
389 else {
390 assert(Op.getEncoding() != BitCodeAbbrevOp::Array &&
391 Op.getEncoding() != BitCodeAbbrevOp::Blob &&
392 "Expected literal or scalar");
393 EmitAbbreviatedField(Op, *Code);
394 }
395 }
396
397 unsigned RecordIdx = 0;
398 for (; i != e; ++i) {
399 const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
400 if (Op.isLiteral()) {
401 assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
402 EmitAbbreviatedLiteral(Op, Vals[RecordIdx]);
403 ++RecordIdx;
404 } else if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
405 // Array case.
406 assert(i + 2 == e && "array op not second to last?");
407 const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
408
409 // If this record has blob data, emit it, otherwise we must have record
410 // entries to encode this way.
411 if (BlobData) {
412 assert(RecordIdx == Vals.size() &&
413 "Blob data and record entries specified for array!");
414 // Emit a vbr6 to indicate the number of elements present.
415 EmitVBR(static_cast<uint32_t>(BlobLen), 6);
416
417 // Emit each field.
418 for (unsigned i = 0; i != BlobLen; ++i)
419 EmitAbbreviatedField(EltEnc, (unsigned char)BlobData[i]);
420
421 // Know that blob data is consumed for assertion below.
422 BlobData = nullptr;
423 } else {
424 // Emit a vbr6 to indicate the number of elements present.
425 EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
426
427 // Emit each field.
428 for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx)
429 EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
430 }
431 } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) {
432 // If this record has blob data, emit it, otherwise we must have record
433 // entries to encode this way.
434
435 if (BlobData) {
436 assert(RecordIdx == Vals.size() &&
437 "Blob data and record entries specified for blob operand!");
438
439 assert(Blob.data() == BlobData && "BlobData got moved");
440 assert(Blob.size() == BlobLen && "BlobLen got changed");
441 emitBlob(Blob);
442 BlobData = nullptr;
443 } else {
444 emitBlob(Vals.slice(RecordIdx));
445 }
446 } else { // Single scalar field.
447 assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
448 EmitAbbreviatedField(Op, Vals[RecordIdx]);
449 ++RecordIdx;
450 }
451 }
452 assert(RecordIdx == Vals.size() && "Not all record operands emitted!");
453 assert(BlobData == nullptr &&
454 "Blob data specified for record that doesn't use it!");
455 }
456
457public:
458 /// Emit a blob, including flushing before and tail-padding.
459 template <class UIntTy>
460 void emitBlob(ArrayRef<UIntTy> Bytes, bool ShouldEmitSize = true) {
461 // Emit a vbr6 to indicate the number of elements present.
462 if (ShouldEmitSize)
463 EmitVBR(static_cast<uint32_t>(Bytes.size()), 6);
464
465 // Flush to a 32-bit alignment boundary.
466 FlushToWord();
467
468 // Emit literal bytes.
469 assert(llvm::all_of(Bytes, [](UIntTy B) { return isUInt<8>(B); }));
470 Out.append(Bytes.begin(), Bytes.end());
471
472 // Align end to 32-bits.
473 while (GetBufferOffset() & 3)
474 Out.push_back(0);
475 }
476 void emitBlob(StringRef Bytes, bool ShouldEmitSize = true) {
477 emitBlob(ArrayRef((const uint8_t *)Bytes.data(), Bytes.size()),
478 ShouldEmitSize);
479 }
480
481 /// EmitRecord - Emit the specified record to the stream, using an abbrev if
482 /// we have one to compress the output.
483 template <typename Container>
484 void EmitRecord(unsigned Code, const Container &Vals, unsigned Abbrev = 0) {
485 if (!Abbrev) {
486 // If we don't have an abbrev to use, emit this in its fully unabbreviated
487 // form.
488 auto Count = static_cast<uint32_t>(std::size(Vals));
490 EmitVBR(Code, 6);
491 EmitVBR(Count, 6);
492 for (unsigned i = 0, e = Count; i != e; ++i)
493 EmitVBR64(Vals[i], 6);
494 return;
495 }
496
497 EmitRecordWithAbbrevImpl(Abbrev, ArrayRef(Vals), StringRef(), Code);
498 }
499
500 /// EmitRecordWithAbbrev - Emit a record with the specified abbreviation.
501 /// Unlike EmitRecord, the code for the record should be included in Vals as
502 /// the first entry.
503 template <typename Container>
504 void EmitRecordWithAbbrev(unsigned Abbrev, const Container &Vals) {
505 EmitRecordWithAbbrevImpl(Abbrev, ArrayRef(Vals), StringRef(), std::nullopt);
506 }
507
508 /// EmitRecordWithBlob - Emit the specified record to the stream, using an
509 /// abbrev that includes a blob at the end. The blob data to emit is
510 /// specified by the pointer and length specified at the end. In contrast to
511 /// EmitRecord, this routine expects that the first entry in Vals is the code
512 /// of the record.
513 template <typename Container>
514 void EmitRecordWithBlob(unsigned Abbrev, const Container &Vals,
515 StringRef Blob) {
516 EmitRecordWithAbbrevImpl(Abbrev, ArrayRef(Vals), Blob, std::nullopt);
517 }
518 template <typename Container>
519 void EmitRecordWithBlob(unsigned Abbrev, const Container &Vals,
520 const char *BlobData, unsigned BlobLen) {
521 return EmitRecordWithAbbrevImpl(Abbrev, ArrayRef(Vals),
522 StringRef(BlobData, BlobLen), std::nullopt);
523 }
524
525 /// EmitRecordWithArray - Just like EmitRecordWithBlob, works with records
526 /// that end with an array.
527 template <typename Container>
528 void EmitRecordWithArray(unsigned Abbrev, const Container &Vals,
529 StringRef Array) {
530 EmitRecordWithAbbrevImpl(Abbrev, ArrayRef(Vals), Array, std::nullopt);
531 }
532 template <typename Container>
533 void EmitRecordWithArray(unsigned Abbrev, const Container &Vals,
534 const char *ArrayData, unsigned ArrayLen) {
535 return EmitRecordWithAbbrevImpl(
536 Abbrev, ArrayRef(Vals), StringRef(ArrayData, ArrayLen), std::nullopt);
537 }
538
539 //===--------------------------------------------------------------------===//
540 // Abbrev Emission
541 //===--------------------------------------------------------------------===//
542
543private:
544 // Emit the abbreviation as a DEFINE_ABBREV record.
545 void EncodeAbbrev(const BitCodeAbbrev &Abbv) {
547 EmitVBR(Abbv.getNumOperandInfos(), 5);
548 for (unsigned i = 0, e = static_cast<unsigned>(Abbv.getNumOperandInfos());
549 i != e; ++i) {
550 const BitCodeAbbrevOp &Op = Abbv.getOperandInfo(i);
551 Emit(Op.isLiteral(), 1);
552 if (Op.isLiteral()) {
553 EmitVBR64(Op.getLiteralValue(), 8);
554 } else {
555 Emit(Op.getEncoding(), 3);
556 if (Op.hasEncodingData())
557 EmitVBR64(Op.getEncodingData(), 5);
558 }
559 }
560 }
561public:
562
563 /// Emits the abbreviation \p Abbv to the stream.
564 unsigned EmitAbbrev(std::shared_ptr<BitCodeAbbrev> Abbv) {
565 EncodeAbbrev(*Abbv);
566 CurAbbrevs.push_back(std::move(Abbv));
567 return static_cast<unsigned>(CurAbbrevs.size())-1 +
569 }
570
571 //===--------------------------------------------------------------------===//
572 // BlockInfo Block Emission
573 //===--------------------------------------------------------------------===//
574
575 /// EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK.
578 BlockInfoCurBID = ~0U;
579 BlockInfoRecords.clear();
580 }
581private:
582 /// SwitchToBlockID - If we aren't already talking about the specified block
583 /// ID, emit a BLOCKINFO_CODE_SETBID record.
584 void SwitchToBlockID(unsigned BlockID) {
585 if (BlockInfoCurBID == BlockID) return;
587 V.push_back(BlockID);
589 BlockInfoCurBID = BlockID;
590 }
591
592 BlockInfo &getOrCreateBlockInfo(unsigned BlockID) {
593 if (BlockInfo *BI = getBlockInfo(BlockID))
594 return *BI;
595
596 // Otherwise, add a new record.
597 BlockInfoRecords.emplace_back();
598 BlockInfoRecords.back().BlockID = BlockID;
599 return BlockInfoRecords.back();
600 }
601
602public:
603
604 /// EmitBlockInfoAbbrev - Emit a DEFINE_ABBREV record for the specified
605 /// BlockID.
606 unsigned EmitBlockInfoAbbrev(unsigned BlockID, std::shared_ptr<BitCodeAbbrev> Abbv) {
607 SwitchToBlockID(BlockID);
608 EncodeAbbrev(*Abbv);
609
610 // Add the abbrev to the specified block record.
611 BlockInfo &Info = getOrCreateBlockInfo(BlockID);
612 Info.Abbrevs.push_back(std::move(Abbv));
613
614 return Info.Abbrevs.size()-1+bitc::FIRST_APPLICATION_ABBREV;
615 }
616};
617
618
619} // End llvm namespace
620
621#endif
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
dxil metadata DXIL Metadata Emit
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
iterator end() const
Definition: ArrayRef.h:152
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
iterator begin() const
Definition: ArrayRef.h:151
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.
Definition: ArrayRef.h:193
BitCodeAbbrevOp - This describes one or more operands in an abbreviation.
Definition: BitCodes.h:33
static unsigned EncodeChar6(char C)
Definition: BitCodes.h:83
BitCodeAbbrev - This class represents an abbreviation record.
Definition: BitCodes.h:103
unsigned getNumOperandInfos() const
Definition: BitCodes.h:112
const BitCodeAbbrevOp & getOperandInfo(unsigned N) const
Definition: BitCodes.h:115
unsigned EmitAbbrev(std::shared_ptr< BitCodeAbbrev > Abbv)
Emits the abbreviation Abbv to the stream.
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 Emit(uint32_t Val, unsigned NumBits)
void emitBlob(ArrayRef< UIntTy > Bytes, bool ShouldEmitSize=true)
Emit a blob, including flushing before and tail-padding.
void EmitCode(unsigned Val)
EmitCode - Emit the specified code.
void EmitRecordWithBlob(unsigned Abbrev, const Container &Vals, const char *BlobData, unsigned BlobLen)
void EmitRecordWithArray(unsigned Abbrev, const Container &Vals, const char *ArrayData, unsigned ArrayLen)
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...
unsigned EmitBlockInfoAbbrev(unsigned BlockID, std::shared_ptr< BitCodeAbbrev > Abbv)
EmitBlockInfoAbbrev - Emit a DEFINE_ABBREV record for the specified BlockID.
BlockInfo * getBlockInfo(unsigned BlockID)
getBlockInfo - If there is block info for the specified ID, return it, otherwise return null.
void EmitVBR64(uint64_t Val, unsigned NumBits)
void EmitRecordWithArray(unsigned Abbrev, const Container &Vals, StringRef Array)
EmitRecordWithArray - Just like EmitRecordWithBlob, works with records that end with an array.
void EnterBlockInfoBlock()
EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK.
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 EmitVBR(uint32_t Val, unsigned NumBits)
void BackpatchWord64(uint64_t BitNo, uint64_t Val)
BitstreamWriter(SmallVectorImpl< char > &O, raw_fd_stream *FS=nullptr, uint32_t FlushThreshold=512)
Create a BitstreamWriter that writes to Buffer O.
void emitBlob(StringRef Bytes, bool ShouldEmitSize=true)
void EnterSubblock(unsigned BlockID, unsigned CodeLen)
unsigned GetAbbrevIDWidth() const
Retrieve the number of bits currently used to encode an abbrev ID.
uint64_t GetCurrentBitNo() const
Retrieve the current position in the stream, in bits.
void EmitRecordWithAbbrev(unsigned Abbrev, const Container &Vals)
EmitRecordWithAbbrev - Emit a record with the specified abbreviation.
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:687
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:131
LLVM Value Representation.
Definition: Value.h:74
A raw_ostream of a file for reading/writing/seeking.
Definition: raw_ostream.h:611
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ BLOCKINFO_CODE_SETBID
Definition: BitCodeEnums.h:81
@ BLOCKINFO_BLOCK_ID
BLOCKINFO_BLOCK is used to define metadata about blocks, for example, standard abbrevs that should be...
Definition: BitCodeEnums.h:69
@ DEFINE_ABBREV
DEFINE_ABBREV - Defines an abbrev for the current block.
Definition: BitCodeEnums.h:53
@ FIRST_APPLICATION_ABBREV
Definition: BitCodeEnums.h:60
constexpr double e
Definition: MathExtras.h:31
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:406
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1819
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
Definition: STLExtras.h:2129