Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:23

0001 //===- BitstreamWriter.h - Low-level bitstream writer interface -*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This header defines the BitstreamWriter class.  This class can be used to
0010 // write an arbitrary bitstream, regardless of its contents.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_BITSTREAM_BITSTREAMWRITER_H
0015 #define LLVM_BITSTREAM_BITSTREAMWRITER_H
0016 
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/ADT/SmallVector.h"
0019 #include "llvm/ADT/StringRef.h"
0020 #include "llvm/Bitstream/BitCodes.h"
0021 #include "llvm/Support/Casting.h"
0022 #include "llvm/Support/Endian.h"
0023 #include "llvm/Support/MathExtras.h"
0024 #include "llvm/Support/raw_ostream.h"
0025 #include <algorithm>
0026 #include <optional>
0027 #include <vector>
0028 
0029 namespace llvm {
0030 
0031 class BitstreamWriter {
0032   /// Owned buffer, used to init Buffer if the provided stream doesn't happen to
0033   /// be a buffer itself.
0034   SmallVector<char, 0> OwnBuffer;
0035   /// Internal buffer for unflushed bytes (unless there is no stream to flush
0036   /// to, case in which these are "the bytes"). The writer backpatches, so it is
0037   /// efficient to buffer.
0038   SmallVectorImpl<char> &Buffer;
0039 
0040   /// FS - The file stream that Buffer flushes to. If FS is a raw_fd_stream, the
0041   /// writer will incrementally flush at subblock boundaries. Otherwise flushing
0042   /// will happen at the end of BitstreamWriter's lifetime.
0043   raw_ostream *const FS;
0044 
0045   /// FlushThreshold - this is the threshold (unit B) to flush to FS, if FS is a
0046   /// raw_fd_stream.
0047   const uint64_t FlushThreshold;
0048 
0049   /// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use.
0050   unsigned CurBit = 0;
0051 
0052   /// CurValue - The current value. Only bits < CurBit are valid.
0053   uint32_t CurValue = 0;
0054 
0055   /// CurCodeSize - This is the declared size of code values used for the
0056   /// current block, in bits.
0057   unsigned CurCodeSize = 2;
0058 
0059   /// BlockInfoCurBID - When emitting a BLOCKINFO_BLOCK, this is the currently
0060   /// selected BLOCK ID.
0061   unsigned BlockInfoCurBID = 0;
0062 
0063   /// CurAbbrevs - Abbrevs installed at in this block.
0064   std::vector<std::shared_ptr<BitCodeAbbrev>> CurAbbrevs;
0065 
0066   // Support for retrieving a section of the output, for purposes such as
0067   // checksumming.
0068   std::optional<size_t> BlockFlushingStartPos;
0069 
0070   struct Block {
0071     unsigned PrevCodeSize;
0072     size_t StartSizeWord;
0073     std::vector<std::shared_ptr<BitCodeAbbrev>> PrevAbbrevs;
0074     Block(unsigned PCS, size_t SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {}
0075   };
0076 
0077   /// BlockScope - This tracks the current blocks that we have entered.
0078   std::vector<Block> BlockScope;
0079 
0080   /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks.
0081   /// These describe abbreviations that all blocks of the specified ID inherit.
0082   struct BlockInfo {
0083     unsigned BlockID;
0084     std::vector<std::shared_ptr<BitCodeAbbrev>> Abbrevs;
0085   };
0086   std::vector<BlockInfo> BlockInfoRecords;
0087 
0088   void WriteWord(unsigned Value) {
0089     Value =
0090         support::endian::byte_swap<uint32_t, llvm::endianness::little>(Value);
0091     Buffer.append(reinterpret_cast<const char *>(&Value),
0092                   reinterpret_cast<const char *>(&Value + 1));
0093   }
0094 
0095   uint64_t GetNumOfFlushedBytes() const {
0096     return fdStream() ? fdStream()->tell() : 0;
0097   }
0098 
0099   size_t GetBufferOffset() const {
0100     return Buffer.size() + GetNumOfFlushedBytes();
0101   }
0102 
0103   size_t GetWordIndex() const {
0104     size_t Offset = GetBufferOffset();
0105     assert((Offset & 3) == 0 && "Not 32-bit aligned");
0106     return Offset / 4;
0107   }
0108 
0109   void flushAndClear() {
0110     assert(FS);
0111     assert(!Buffer.empty());
0112     assert(!BlockFlushingStartPos &&
0113            "a call to markAndBlockFlushing should have been paired with a "
0114            "call to getMarkedBufferAndResumeFlushing");
0115     FS->write(Buffer.data(), Buffer.size());
0116     Buffer.clear();
0117   }
0118 
0119   /// If the related file stream is a raw_fd_stream, flush the buffer if its
0120   /// size is above a threshold. If \p OnClosing is true, flushing happens
0121   /// regardless of thresholds.
0122   void FlushToFile(bool OnClosing = false) {
0123     if (!FS || Buffer.empty())
0124       return;
0125     if (OnClosing)
0126       return flushAndClear();
0127     if (BlockFlushingStartPos)
0128       return;
0129     if (fdStream() && Buffer.size() > FlushThreshold)
0130       flushAndClear();
0131   }
0132 
0133   raw_fd_stream *fdStream() { return dyn_cast_or_null<raw_fd_stream>(FS); }
0134 
0135   const raw_fd_stream *fdStream() const {
0136     return dyn_cast_or_null<raw_fd_stream>(FS);
0137   }
0138 
0139   SmallVectorImpl<char> &getInternalBufferFromStream(raw_ostream &OutStream) {
0140     if (auto *SV = dyn_cast<raw_svector_ostream>(&OutStream))
0141       return SV->buffer();
0142     return OwnBuffer;
0143   }
0144 
0145 public:
0146   /// Create a BitstreamWriter over a raw_ostream \p OutStream.
0147   /// If \p OutStream is a raw_svector_ostream, the BitstreamWriter will write
0148   /// directly to the latter's buffer. In all other cases, the BitstreamWriter
0149   /// will use an internal buffer and flush at the end of its lifetime.
0150   ///
0151   /// In addition, if \p is a raw_fd_stream supporting seek, tell, and read
0152   /// (besides write), the BitstreamWriter will also flush incrementally, when a
0153   /// subblock is finished, and if the FlushThreshold is passed.
0154   ///
0155   /// NOTE: \p FlushThreshold's unit is MB.
0156   BitstreamWriter(raw_ostream &OutStream, uint32_t FlushThreshold = 512)
0157       : Buffer(getInternalBufferFromStream(OutStream)),
0158         FS(!isa<raw_svector_ostream>(OutStream) ? &OutStream : nullptr),
0159         FlushThreshold(uint64_t(FlushThreshold) << 20) {}
0160 
0161   /// Convenience constructor for users that start with a vector - avoids
0162   /// needing to wrap it in a raw_svector_ostream.
0163   BitstreamWriter(SmallVectorImpl<char> &Buff)
0164       : Buffer(Buff), FS(nullptr), FlushThreshold(0) {}
0165 
0166   ~BitstreamWriter() {
0167     FlushToWord();
0168     assert(BlockScope.empty() && CurAbbrevs.empty() && "Block imbalance");
0169     FlushToFile(/*OnClosing=*/true);
0170   }
0171 
0172   /// For scenarios where the user wants to access a section of the stream to
0173   /// (for example) compute some checksum, disable flushing and remember the
0174   /// position in the internal buffer where that happened. Must be paired with a
0175   /// call to getMarkedBufferAndResumeFlushing.
0176   void markAndBlockFlushing() {
0177     assert(!BlockFlushingStartPos);
0178     BlockFlushingStartPos = Buffer.size();
0179   }
0180 
0181   /// resumes flushing, but does not flush, and returns the section in the
0182   /// internal buffer starting from the position marked with
0183   /// markAndBlockFlushing. The return should be processed before any additional
0184   /// calls to this object, because those may cause a flush and invalidate the
0185   /// return.
0186   StringRef getMarkedBufferAndResumeFlushing() {
0187     assert(BlockFlushingStartPos);
0188     size_t Start = *BlockFlushingStartPos;
0189     BlockFlushingStartPos.reset();
0190     return {&Buffer[Start], Buffer.size() - Start};
0191   }
0192 
0193   /// Retrieve the current position in the stream, in bits.
0194   uint64_t GetCurrentBitNo() const { return GetBufferOffset() * 8 + CurBit; }
0195 
0196   /// Retrieve the number of bits currently used to encode an abbrev ID.
0197   unsigned GetAbbrevIDWidth() const { return CurCodeSize; }
0198 
0199   //===--------------------------------------------------------------------===//
0200   // Basic Primitives for emitting bits to the stream.
0201   //===--------------------------------------------------------------------===//
0202 
0203   /// Backpatch a byte in the output at the given bit offset with the specified
0204   /// value.
0205   void BackpatchByte(uint64_t BitNo, uint8_t NewByte) {
0206     using namespace llvm::support;
0207     uint64_t ByteNo = BitNo / 8;
0208     uint64_t StartBit = BitNo & 7;
0209     uint64_t NumOfFlushedBytes = GetNumOfFlushedBytes();
0210 
0211     if (ByteNo >= NumOfFlushedBytes) {
0212       assert((!endian::readAtBitAlignment<uint8_t, llvm::endianness::little,
0213                                           unaligned>(
0214                  &Buffer[ByteNo - NumOfFlushedBytes], StartBit)) &&
0215              "Expected to be patching over 0-value placeholders");
0216       endian::writeAtBitAlignment<uint8_t, llvm::endianness::little, unaligned>(
0217           &Buffer[ByteNo - NumOfFlushedBytes], NewByte, StartBit);
0218       return;
0219     }
0220 
0221     // If we don't have a raw_fd_stream, GetNumOfFlushedBytes() should have
0222     // returned 0, and we shouldn't be here.
0223     assert(fdStream() != nullptr);
0224     // If the byte offset to backpatch is flushed, use seek to backfill data.
0225     // First, save the file position to restore later.
0226     uint64_t CurPos = fdStream()->tell();
0227 
0228     // Copy data to update into Bytes from the file FS and the buffer Out.
0229     char Bytes[3]; // Use one more byte to silence a warning from Visual C++.
0230     size_t BytesNum = StartBit ? 2 : 1;
0231     size_t BytesFromDisk = std::min(static_cast<uint64_t>(BytesNum), NumOfFlushedBytes - ByteNo);
0232     size_t BytesFromBuffer = BytesNum - BytesFromDisk;
0233 
0234     // When unaligned, copy existing data into Bytes from the file FS and the
0235     // buffer Buffer so that it can be updated before writing. For debug builds
0236     // read bytes unconditionally in order to check that the existing value is 0
0237     // as expected.
0238 #ifdef NDEBUG
0239     if (StartBit)
0240 #endif
0241     {
0242       fdStream()->seek(ByteNo);
0243       ssize_t BytesRead = fdStream()->read(Bytes, BytesFromDisk);
0244       (void)BytesRead; // silence warning
0245       assert(BytesRead >= 0 && static_cast<size_t>(BytesRead) == BytesFromDisk);
0246       for (size_t i = 0; i < BytesFromBuffer; ++i)
0247         Bytes[BytesFromDisk + i] = Buffer[i];
0248       assert((!endian::readAtBitAlignment<uint8_t, llvm::endianness::little,
0249                                           unaligned>(Bytes, StartBit)) &&
0250              "Expected to be patching over 0-value placeholders");
0251     }
0252 
0253     // Update Bytes in terms of bit offset and value.
0254     endian::writeAtBitAlignment<uint8_t, llvm::endianness::little, unaligned>(
0255         Bytes, NewByte, StartBit);
0256 
0257     // Copy updated data back to the file FS and the buffer Out.
0258     fdStream()->seek(ByteNo);
0259     fdStream()->write(Bytes, BytesFromDisk);
0260     for (size_t i = 0; i < BytesFromBuffer; ++i)
0261       Buffer[i] = Bytes[BytesFromDisk + i];
0262 
0263     // Restore the file position.
0264     fdStream()->seek(CurPos);
0265   }
0266 
0267   void BackpatchHalfWord(uint64_t BitNo, uint16_t Val) {
0268     BackpatchByte(BitNo, (uint8_t)Val);
0269     BackpatchByte(BitNo + 8, (uint8_t)(Val >> 8));
0270   }
0271 
0272   void BackpatchWord(uint64_t BitNo, unsigned Val) {
0273     BackpatchHalfWord(BitNo, (uint16_t)Val);
0274     BackpatchHalfWord(BitNo + 16, (uint16_t)(Val >> 16));
0275   }
0276 
0277   void BackpatchWord64(uint64_t BitNo, uint64_t Val) {
0278     BackpatchWord(BitNo, (uint32_t)Val);
0279     BackpatchWord(BitNo + 32, (uint32_t)(Val >> 32));
0280   }
0281 
0282   void Emit(uint32_t Val, unsigned NumBits) {
0283     assert(NumBits && NumBits <= 32 && "Invalid value size!");
0284     assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!");
0285     CurValue |= Val << CurBit;
0286     if (CurBit + NumBits < 32) {
0287       CurBit += NumBits;
0288       return;
0289     }
0290 
0291     // Add the current word.
0292     WriteWord(CurValue);
0293 
0294     if (CurBit)
0295       CurValue = Val >> (32-CurBit);
0296     else
0297       CurValue = 0;
0298     CurBit = (CurBit+NumBits) & 31;
0299   }
0300 
0301   void FlushToWord() {
0302     if (CurBit) {
0303       WriteWord(CurValue);
0304       CurBit = 0;
0305       CurValue = 0;
0306     }
0307   }
0308 
0309   void EmitVBR(uint32_t Val, unsigned NumBits) {
0310     assert(NumBits <= 32 && "Too many bits to emit!");
0311     uint32_t Threshold = 1U << (NumBits-1);
0312 
0313     // Emit the bits with VBR encoding, NumBits-1 bits at a time.
0314     while (Val >= Threshold) {
0315       Emit((Val & ((1U << (NumBits - 1)) - 1)) | (1U << (NumBits - 1)),
0316            NumBits);
0317       Val >>= NumBits-1;
0318     }
0319 
0320     Emit(Val, NumBits);
0321   }
0322 
0323   void EmitVBR64(uint64_t Val, unsigned NumBits) {
0324     assert(NumBits <= 32 && "Too many bits to emit!");
0325     if ((uint32_t)Val == Val)
0326       return EmitVBR((uint32_t)Val, NumBits);
0327 
0328     uint32_t Threshold = 1U << (NumBits-1);
0329 
0330     // Emit the bits with VBR encoding, NumBits-1 bits at a time.
0331     while (Val >= Threshold) {
0332       Emit(((uint32_t)Val & ((1U << (NumBits - 1)) - 1)) |
0333                (1U << (NumBits - 1)),
0334            NumBits);
0335       Val >>= NumBits-1;
0336     }
0337 
0338     Emit((uint32_t)Val, NumBits);
0339   }
0340 
0341   /// EmitCode - Emit the specified code.
0342   void EmitCode(unsigned Val) {
0343     Emit(Val, CurCodeSize);
0344   }
0345 
0346   //===--------------------------------------------------------------------===//
0347   // Block Manipulation
0348   //===--------------------------------------------------------------------===//
0349 
0350   /// getBlockInfo - If there is block info for the specified ID, return it,
0351   /// otherwise return null.
0352   BlockInfo *getBlockInfo(unsigned BlockID) {
0353     // Common case, the most recent entry matches BlockID.
0354     if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
0355       return &BlockInfoRecords.back();
0356 
0357     for (BlockInfo &BI : BlockInfoRecords)
0358       if (BI.BlockID == BlockID)
0359         return &BI;
0360     return nullptr;
0361   }
0362 
0363   void EnterSubblock(unsigned BlockID, unsigned CodeLen) {
0364     // Block header:
0365     //    [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen]
0366     EmitCode(bitc::ENTER_SUBBLOCK);
0367     EmitVBR(BlockID, bitc::BlockIDWidth);
0368     EmitVBR(CodeLen, bitc::CodeLenWidth);
0369     FlushToWord();
0370 
0371     size_t BlockSizeWordIndex = GetWordIndex();
0372     unsigned OldCodeSize = CurCodeSize;
0373 
0374     // Emit a placeholder, which will be replaced when the block is popped.
0375     Emit(0, bitc::BlockSizeWidth);
0376 
0377     CurCodeSize = CodeLen;
0378 
0379     // Push the outer block's abbrev set onto the stack, start out with an
0380     // empty abbrev set.
0381     BlockScope.emplace_back(OldCodeSize, BlockSizeWordIndex);
0382     BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
0383 
0384     // If there is a blockinfo for this BlockID, add all the predefined abbrevs
0385     // to the abbrev list.
0386     if (BlockInfo *Info = getBlockInfo(BlockID))
0387       append_range(CurAbbrevs, Info->Abbrevs);
0388   }
0389 
0390   void ExitBlock() {
0391     assert(!BlockScope.empty() && "Block scope imbalance!");
0392     const Block &B = BlockScope.back();
0393 
0394     // Block tail:
0395     //    [END_BLOCK, <align4bytes>]
0396     EmitCode(bitc::END_BLOCK);
0397     FlushToWord();
0398 
0399     // Compute the size of the block, in words, not counting the size field.
0400     size_t SizeInWords = GetWordIndex() - B.StartSizeWord - 1;
0401     uint64_t BitNo = uint64_t(B.StartSizeWord) * 32;
0402 
0403     // Update the block size field in the header of this sub-block.
0404     BackpatchWord(BitNo, SizeInWords);
0405 
0406     // Restore the inner block's code size and abbrev table.
0407     CurCodeSize = B.PrevCodeSize;
0408     CurAbbrevs = std::move(B.PrevAbbrevs);
0409     BlockScope.pop_back();
0410     FlushToFile();
0411   }
0412 
0413   //===--------------------------------------------------------------------===//
0414   // Record Emission
0415   //===--------------------------------------------------------------------===//
0416 
0417 private:
0418   /// EmitAbbreviatedLiteral - Emit a literal value according to its abbrev
0419   /// record.  This is a no-op, since the abbrev specifies the literal to use.
0420   template<typename uintty>
0421   void EmitAbbreviatedLiteral(const BitCodeAbbrevOp &Op, uintty V) {
0422     assert(Op.isLiteral() && "Not a literal");
0423     // If the abbrev specifies the literal value to use, don't emit
0424     // anything.
0425     assert(V == Op.getLiteralValue() &&
0426            "Invalid abbrev for record!");
0427   }
0428 
0429   /// EmitAbbreviatedField - Emit a single scalar field value with the specified
0430   /// encoding.
0431   template<typename uintty>
0432   void EmitAbbreviatedField(const BitCodeAbbrevOp &Op, uintty V) {
0433     assert(!Op.isLiteral() && "Literals should use EmitAbbreviatedLiteral!");
0434 
0435     // Encode the value as we are commanded.
0436     switch (Op.getEncoding()) {
0437     default: llvm_unreachable("Unknown encoding!");
0438     case BitCodeAbbrevOp::Fixed:
0439       if (Op.getEncodingData())
0440         Emit((unsigned)V, (unsigned)Op.getEncodingData());
0441       break;
0442     case BitCodeAbbrevOp::VBR:
0443       if (Op.getEncodingData())
0444         EmitVBR64(V, (unsigned)Op.getEncodingData());
0445       break;
0446     case BitCodeAbbrevOp::Char6:
0447       Emit(BitCodeAbbrevOp::EncodeChar6((char)V), 6);
0448       break;
0449     }
0450   }
0451 
0452   /// EmitRecordWithAbbrevImpl - This is the core implementation of the record
0453   /// emission code.  If BlobData is non-null, then it specifies an array of
0454   /// data that should be emitted as part of the Blob or Array operand that is
0455   /// known to exist at the end of the record. If Code is specified, then
0456   /// it is the record code to emit before the Vals, which must not contain
0457   /// the code.
0458   template <typename uintty>
0459   void EmitRecordWithAbbrevImpl(unsigned Abbrev, ArrayRef<uintty> Vals,
0460                                 StringRef Blob, std::optional<unsigned> Code) {
0461     const char *BlobData = Blob.data();
0462     unsigned BlobLen = (unsigned) Blob.size();
0463     unsigned AbbrevNo = Abbrev-bitc::FIRST_APPLICATION_ABBREV;
0464     assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
0465     const BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo].get();
0466 
0467     EmitCode(Abbrev);
0468 
0469     unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos());
0470     if (Code) {
0471       assert(e && "Expected non-empty abbreviation");
0472       const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i++);
0473 
0474       if (Op.isLiteral())
0475         EmitAbbreviatedLiteral(Op, *Code);
0476       else {
0477         assert(Op.getEncoding() != BitCodeAbbrevOp::Array &&
0478                Op.getEncoding() != BitCodeAbbrevOp::Blob &&
0479                "Expected literal or scalar");
0480         EmitAbbreviatedField(Op, *Code);
0481       }
0482     }
0483 
0484     unsigned RecordIdx = 0;
0485     for (; i != e; ++i) {
0486       const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
0487       if (Op.isLiteral()) {
0488         assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
0489         EmitAbbreviatedLiteral(Op, Vals[RecordIdx]);
0490         ++RecordIdx;
0491       } else if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
0492         // Array case.
0493         assert(i + 2 == e && "array op not second to last?");
0494         const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
0495 
0496         // If this record has blob data, emit it, otherwise we must have record
0497         // entries to encode this way.
0498         if (BlobData) {
0499           assert(RecordIdx == Vals.size() &&
0500                  "Blob data and record entries specified for array!");
0501           // Emit a vbr6 to indicate the number of elements present.
0502           EmitVBR(static_cast<uint32_t>(BlobLen), 6);
0503 
0504           // Emit each field.
0505           for (unsigned i = 0; i != BlobLen; ++i)
0506             EmitAbbreviatedField(EltEnc, (unsigned char)BlobData[i]);
0507 
0508           // Know that blob data is consumed for assertion below.
0509           BlobData = nullptr;
0510         } else {
0511           // Emit a vbr6 to indicate the number of elements present.
0512           EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
0513 
0514           // Emit each field.
0515           for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx)
0516             EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
0517         }
0518       } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) {
0519         // If this record has blob data, emit it, otherwise we must have record
0520         // entries to encode this way.
0521 
0522         if (BlobData) {
0523           assert(RecordIdx == Vals.size() &&
0524                  "Blob data and record entries specified for blob operand!");
0525 
0526           assert(Blob.data() == BlobData && "BlobData got moved");
0527           assert(Blob.size() == BlobLen && "BlobLen got changed");
0528           emitBlob(Blob);
0529           BlobData = nullptr;
0530         } else {
0531           emitBlob(Vals.slice(RecordIdx));
0532         }
0533       } else {  // Single scalar field.
0534         assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
0535         EmitAbbreviatedField(Op, Vals[RecordIdx]);
0536         ++RecordIdx;
0537       }
0538     }
0539     assert(RecordIdx == Vals.size() && "Not all record operands emitted!");
0540     assert(BlobData == nullptr &&
0541            "Blob data specified for record that doesn't use it!");
0542   }
0543 
0544 public:
0545   /// Emit a blob, including flushing before and tail-padding.
0546   template <class UIntTy>
0547   void emitBlob(ArrayRef<UIntTy> Bytes, bool ShouldEmitSize = true) {
0548     // Emit a vbr6 to indicate the number of elements present.
0549     if (ShouldEmitSize)
0550       EmitVBR(static_cast<uint32_t>(Bytes.size()), 6);
0551 
0552     // Flush to a 32-bit alignment boundary.
0553     FlushToWord();
0554 
0555     // Emit literal bytes.
0556     assert(llvm::all_of(Bytes, [](UIntTy B) { return isUInt<8>(B); }));
0557     Buffer.append(Bytes.begin(), Bytes.end());
0558 
0559     // Align end to 32-bits.
0560     while (GetBufferOffset() & 3)
0561       Buffer.push_back(0);
0562   }
0563   void emitBlob(StringRef Bytes, bool ShouldEmitSize = true) {
0564     emitBlob(ArrayRef((const uint8_t *)Bytes.data(), Bytes.size()),
0565              ShouldEmitSize);
0566   }
0567 
0568   /// EmitRecord - Emit the specified record to the stream, using an abbrev if
0569   /// we have one to compress the output.
0570   template <typename Container>
0571   void EmitRecord(unsigned Code, const Container &Vals, unsigned Abbrev = 0) {
0572     if (!Abbrev) {
0573       // If we don't have an abbrev to use, emit this in its fully unabbreviated
0574       // form.
0575       auto Count = static_cast<uint32_t>(std::size(Vals));
0576       EmitCode(bitc::UNABBREV_RECORD);
0577       EmitVBR(Code, 6);
0578       EmitVBR(Count, 6);
0579       for (unsigned i = 0, e = Count; i != e; ++i)
0580         EmitVBR64(Vals[i], 6);
0581       return;
0582     }
0583 
0584     EmitRecordWithAbbrevImpl(Abbrev, ArrayRef(Vals), StringRef(), Code);
0585   }
0586 
0587   /// EmitRecordWithAbbrev - Emit a record with the specified abbreviation.
0588   /// Unlike EmitRecord, the code for the record should be included in Vals as
0589   /// the first entry.
0590   template <typename Container>
0591   void EmitRecordWithAbbrev(unsigned Abbrev, const Container &Vals) {
0592     EmitRecordWithAbbrevImpl(Abbrev, ArrayRef(Vals), StringRef(), std::nullopt);
0593   }
0594 
0595   /// EmitRecordWithBlob - Emit the specified record to the stream, using an
0596   /// abbrev that includes a blob at the end.  The blob data to emit is
0597   /// specified by the pointer and length specified at the end.  In contrast to
0598   /// EmitRecord, this routine expects that the first entry in Vals is the code
0599   /// of the record.
0600   template <typename Container>
0601   void EmitRecordWithBlob(unsigned Abbrev, const Container &Vals,
0602                           StringRef Blob) {
0603     EmitRecordWithAbbrevImpl(Abbrev, ArrayRef(Vals), Blob, std::nullopt);
0604   }
0605   template <typename Container>
0606   void EmitRecordWithBlob(unsigned Abbrev, const Container &Vals,
0607                           const char *BlobData, unsigned BlobLen) {
0608     return EmitRecordWithAbbrevImpl(Abbrev, ArrayRef(Vals),
0609                                     StringRef(BlobData, BlobLen), std::nullopt);
0610   }
0611 
0612   /// EmitRecordWithArray - Just like EmitRecordWithBlob, works with records
0613   /// that end with an array.
0614   template <typename Container>
0615   void EmitRecordWithArray(unsigned Abbrev, const Container &Vals,
0616                            StringRef Array) {
0617     EmitRecordWithAbbrevImpl(Abbrev, ArrayRef(Vals), Array, std::nullopt);
0618   }
0619   template <typename Container>
0620   void EmitRecordWithArray(unsigned Abbrev, const Container &Vals,
0621                            const char *ArrayData, unsigned ArrayLen) {
0622     return EmitRecordWithAbbrevImpl(
0623         Abbrev, ArrayRef(Vals), StringRef(ArrayData, ArrayLen), std::nullopt);
0624   }
0625 
0626   //===--------------------------------------------------------------------===//
0627   // Abbrev Emission
0628   //===--------------------------------------------------------------------===//
0629 
0630 private:
0631   // Emit the abbreviation as a DEFINE_ABBREV record.
0632   void EncodeAbbrev(const BitCodeAbbrev &Abbv) {
0633     EmitCode(bitc::DEFINE_ABBREV);
0634     EmitVBR(Abbv.getNumOperandInfos(), 5);
0635     for (unsigned i = 0, e = static_cast<unsigned>(Abbv.getNumOperandInfos());
0636          i != e; ++i) {
0637       const BitCodeAbbrevOp &Op = Abbv.getOperandInfo(i);
0638       Emit(Op.isLiteral(), 1);
0639       if (Op.isLiteral()) {
0640         EmitVBR64(Op.getLiteralValue(), 8);
0641       } else {
0642         Emit(Op.getEncoding(), 3);
0643         if (Op.hasEncodingData())
0644           EmitVBR64(Op.getEncodingData(), 5);
0645       }
0646     }
0647   }
0648 public:
0649 
0650   /// Emits the abbreviation \p Abbv to the stream.
0651   unsigned EmitAbbrev(std::shared_ptr<BitCodeAbbrev> Abbv) {
0652     EncodeAbbrev(*Abbv);
0653     CurAbbrevs.push_back(std::move(Abbv));
0654     return static_cast<unsigned>(CurAbbrevs.size())-1 +
0655       bitc::FIRST_APPLICATION_ABBREV;
0656   }
0657 
0658   //===--------------------------------------------------------------------===//
0659   // BlockInfo Block Emission
0660   //===--------------------------------------------------------------------===//
0661 
0662   /// EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK.
0663   void EnterBlockInfoBlock() {
0664     EnterSubblock(bitc::BLOCKINFO_BLOCK_ID, 2);
0665     BlockInfoCurBID = ~0U;
0666     BlockInfoRecords.clear();
0667   }
0668 private:
0669   /// SwitchToBlockID - If we aren't already talking about the specified block
0670   /// ID, emit a BLOCKINFO_CODE_SETBID record.
0671   void SwitchToBlockID(unsigned BlockID) {
0672     if (BlockInfoCurBID == BlockID) return;
0673     SmallVector<unsigned, 2> V;
0674     V.push_back(BlockID);
0675     EmitRecord(bitc::BLOCKINFO_CODE_SETBID, V);
0676     BlockInfoCurBID = BlockID;
0677   }
0678 
0679   BlockInfo &getOrCreateBlockInfo(unsigned BlockID) {
0680     if (BlockInfo *BI = getBlockInfo(BlockID))
0681       return *BI;
0682 
0683     // Otherwise, add a new record.
0684     BlockInfoRecords.emplace_back();
0685     BlockInfoRecords.back().BlockID = BlockID;
0686     return BlockInfoRecords.back();
0687   }
0688 
0689 public:
0690 
0691   /// EmitBlockInfoAbbrev - Emit a DEFINE_ABBREV record for the specified
0692   /// BlockID.
0693   unsigned EmitBlockInfoAbbrev(unsigned BlockID, std::shared_ptr<BitCodeAbbrev> Abbv) {
0694     SwitchToBlockID(BlockID);
0695     EncodeAbbrev(*Abbv);
0696 
0697     // Add the abbrev to the specified block record.
0698     BlockInfo &Info = getOrCreateBlockInfo(BlockID);
0699     Info.Abbrevs.push_back(std::move(Abbv));
0700 
0701     return Info.Abbrevs.size()-1+bitc::FIRST_APPLICATION_ABBREV;
0702   }
0703 };
0704 
0705 
0706 } // End llvm namespace
0707 
0708 #endif