LCOV - code coverage report
Current view: top level - include/llvm/Bitcode - BitstreamWriter.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 189 193 97.9 %
Date: 2017-09-14 15:23:50 Functions: 38 40 95.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- BitstreamWriter.h - Low-level bitstream writer interface -*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This header defines the BitstreamWriter class.  This class can be used to
      11             : // write an arbitrary bitstream, regardless of its contents.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_BITCODE_BITSTREAMWRITER_H
      16             : #define LLVM_BITCODE_BITSTREAMWRITER_H
      17             : 
      18             : #include "llvm/ADT/ArrayRef.h"
      19             : #include "llvm/ADT/Optional.h"
      20             : #include "llvm/ADT/SmallVector.h"
      21             : #include "llvm/ADT/StringRef.h"
      22             : #include "llvm/Bitcode/BitCodes.h"
      23             : #include "llvm/Support/Endian.h"
      24             : #include <vector>
      25             : 
      26             : namespace llvm {
      27             : 
      28             : class BitstreamWriter {
      29             :   SmallVectorImpl<char> &Out;
      30             : 
      31             :   /// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use.
      32             :   unsigned CurBit;
      33             : 
      34             :   /// CurValue - The current value.  Only bits < CurBit are valid.
      35             :   uint32_t CurValue;
      36             : 
      37             :   /// CurCodeSize - This is the declared size of code values used for the
      38             :   /// current block, in bits.
      39             :   unsigned CurCodeSize;
      40             : 
      41             :   /// BlockInfoCurBID - When emitting a BLOCKINFO_BLOCK, this is the currently
      42             :   /// selected BLOCK ID.
      43             :   unsigned BlockInfoCurBID;
      44             : 
      45             :   /// CurAbbrevs - Abbrevs installed at in this block.
      46             :   std::vector<std::shared_ptr<BitCodeAbbrev>> CurAbbrevs;
      47             : 
      48      110602 :   struct Block {
      49             :     unsigned PrevCodeSize;
      50             :     size_t StartSizeWord;
      51             :     std::vector<std::shared_ptr<BitCodeAbbrev>> PrevAbbrevs;
      52      158408 :     Block(unsigned PCS, size_t SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {}
      53             :   };
      54             : 
      55             :   /// BlockScope - This tracks the current blocks that we have entered.
      56             :   std::vector<Block> BlockScope;
      57             : 
      58             :   /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks.
      59             :   /// These describe abbreviations that all blocks of the specified ID inherit.
      60       65392 :   struct BlockInfo {
      61             :     unsigned BlockID;
      62             :     std::vector<std::shared_ptr<BitCodeAbbrev>> Abbrevs;
      63             :   };
      64             :   std::vector<BlockInfo> BlockInfoRecords;
      65             : 
      66             :   void WriteByte(unsigned char Value) {
      67   135865236 :     Out.push_back(Value);
      68             :   }
      69             : 
      70             :   void WriteWord(unsigned Value) {
      71    33016046 :     Value = support::endian::byte_swap<uint32_t, support::little>(Value);
      72    16508023 :     Out.append(reinterpret_cast<const char *>(&Value),
      73             :                reinterpret_cast<const char *>(&Value + 1));
      74             :   }
      75             : 
      76     5967000 :   size_t GetBufferOffset() const { return Out.size(); }
      77             : 
      78             :   size_t GetWordIndex() const {
      79      316814 :     size_t Offset = GetBufferOffset();
      80             :     assert((Offset & 3) == 0 && "Not 32-bit aligned");
      81      158407 :     return Offset / 4;
      82             :   }
      83             : 
      84             : public:
      85             :   explicit BitstreamWriter(SmallVectorImpl<char> &O)
      86       30732 :     : Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {}
      87             : 
      88        7673 :   ~BitstreamWriter() {
      89             :     assert(CurBit == 0 && "Unflushed data remaining");
      90             :     assert(BlockScope.empty() && CurAbbrevs.empty() && "Block imbalance");
      91        7673 :   }
      92             : 
      93             :   /// \brief Retrieve the current position in the stream, in bits.
      94     5366368 :   uint64_t GetCurrentBitNo() const { return GetBufferOffset() * 8 + CurBit; }
      95             : 
      96             :   /// \brief Retrieve the number of bits currently used to encode an abbrev ID.
      97             :   unsigned GetAbbrevIDWidth() const { return CurCodeSize; }
      98             : 
      99             :   //===--------------------------------------------------------------------===//
     100             :   // Basic Primitives for emitting bits to the stream.
     101             :   //===--------------------------------------------------------------------===//
     102             : 
     103             :   /// Backpatch a 32-bit word in the output at the given bit offset
     104             :   /// with the specified value.
     105             :   void BackpatchWord(uint64_t BitNo, unsigned NewWord) {
     106             :     using namespace llvm::support;
     107       82988 :     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       86773 :     endian::writeAtBitAlignment<uint32_t, little, unaligned>(
     112      165976 :         &Out[ByteNo], NewWord, BitNo & 7);
     113             :   }
     114             : 
     115          78 :   void BackpatchWord64(uint64_t BitNo, uint64_t Val) {
     116         156 :     BackpatchWord(BitNo, (uint32_t)Val);
     117         156 :     BackpatchWord(BitNo + 32, (uint32_t)(Val >> 32));
     118          78 :   }
     119             : 
     120    91057142 :   void Emit(uint32_t Val, unsigned NumBits) {
     121             :     assert(NumBits && NumBits <= 32 && "Invalid value size!");
     122             :     assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!");
     123    91057142 :     CurValue |= Val << CurBit;
     124    91057142 :     if (CurBit + NumBits < 32) {
     125    74800052 :       CurBit += NumBits;
     126    74800052 :       return;
     127             :     }
     128             : 
     129             :     // Add the current word.
     130    32514179 :     WriteWord(CurValue);
     131             : 
     132    16257089 :     if (CurBit)
     133    16177700 :       CurValue = Val >> (32-CurBit);
     134             :     else
     135       79389 :       CurValue = 0;
     136    16257089 :     CurBit = (CurBit+NumBits) & 31;
     137             :   }
     138             : 
     139      257381 :   void FlushToWord() {
     140      257381 :     if (CurBit) {
     141      501866 :       WriteWord(CurValue);
     142      250933 :       CurBit = 0;
     143      250933 :       CurValue = 0;
     144             :     }
     145      257381 :   }
     146             : 
     147    46645357 :   void EmitVBR(uint32_t Val, unsigned NumBits) {
     148             :     assert(NumBits <= 32 && "Too many bits to emit!");
     149    46645357 :     uint32_t Threshold = 1U << (NumBits-1);
     150             : 
     151             :     // Emit the bits with VBR encoding, NumBits-1 bits at a time.
     152   116467299 :     while (Val >= Threshold) {
     153    34910970 :       Emit((Val & ((1 << (NumBits-1))-1)) | (1 << (NumBits-1)), NumBits);
     154    34910971 :       Val >>= NumBits-1;
     155             :     }
     156             : 
     157    46645358 :     Emit(Val, NumBits);
     158    46645379 :   }
     159             : 
     160    40129282 :   void EmitVBR64(uint64_t Val, unsigned NumBits) {
     161             :     assert(NumBits <= 32 && "Too many bits to emit!");
     162    40129282 :     if ((uint32_t)Val == Val)
     163    40128060 :       return EmitVBR((uint32_t)Val, NumBits);
     164             : 
     165        1222 :     uint32_t Threshold = 1U << (NumBits-1);
     166             : 
     167             :     // Emit the bits with VBR encoding, NumBits-1 bits at a time.
     168       30056 :     while (Val >= Threshold) {
     169       28834 :       Emit(((uint32_t)Val & ((1 << (NumBits-1))-1)) |
     170       14417 :            (1 << (NumBits-1)), NumBits);
     171       14417 :       Val >>= NumBits-1;
     172             :     }
     173             : 
     174        1222 :     Emit((uint32_t)Val, NumBits);
     175             :   }
     176             : 
     177             :   /// EmitCode - Emit the specified code.
     178             :   void EmitCode(unsigned Val) {
     179     4062445 :     Emit(Val, CurCodeSize);
     180             :   }
     181             : 
     182             :   //===--------------------------------------------------------------------===//
     183             :   // Block Manipulation
     184             :   //===--------------------------------------------------------------------===//
     185             : 
     186             :   /// getBlockInfo - If there is block info for the specified ID, return it,
     187             :   /// otherwise return null.
     188             :   BlockInfo *getBlockInfo(unsigned BlockID) {
     189             :     // Common case, the most recent entry matches BlockID.
     190      373675 :     if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
     191      108940 :       return &BlockInfoRecords.back();
     192             : 
     193      254764 :     for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size());
     194      171756 :          i != e; ++i)
     195      202638 :       if (BlockInfoRecords[i].BlockID == BlockID)
     196             :         return &BlockInfoRecords[i];
     197             :     return nullptr;
     198             :   }
     199             : 
     200       79204 :   void EnterSubblock(unsigned BlockID, unsigned CodeLen) {
     201             :     // Block header:
     202             :     //    [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen]
     203       79204 :     EmitCode(bitc::ENTER_SUBBLOCK);
     204       79204 :     EmitVBR(BlockID, bitc::BlockIDWidth);
     205       79204 :     EmitVBR(CodeLen, bitc::CodeLenWidth);
     206       79204 :     FlushToWord();
     207             : 
     208       79204 :     size_t BlockSizeWordIndex = GetWordIndex();
     209       79204 :     unsigned OldCodeSize = CurCodeSize;
     210             : 
     211             :     // Emit a placeholder, which will be replaced when the block is popped.
     212       79204 :     Emit(0, bitc::BlockSizeWidth);
     213             : 
     214       79204 :     CurCodeSize = CodeLen;
     215             : 
     216             :     // Push the outer block's abbrev set onto the stack, start out with an
     217             :     // empty abbrev set.
     218       79204 :     BlockScope.emplace_back(OldCodeSize, BlockSizeWordIndex);
     219      237612 :     BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
     220             : 
     221             :     // If there is a blockinfo for this BlockID, add all the predefined abbrevs
     222             :     // to the abbrev list.
     223       79204 :     if (BlockInfo *Info = getBlockInfo(BlockID)) {
     224       59142 :       CurAbbrevs.insert(CurAbbrevs.end(), Info->Abbrevs.begin(),
     225       98570 :                         Info->Abbrevs.end());
     226             :     }
     227       79204 :   }
     228             : 
     229       79203 :   void ExitBlock() {
     230             :     assert(!BlockScope.empty() && "Block scope imbalance!");
     231      158406 :     const Block &B = BlockScope.back();
     232             : 
     233             :     // Block tail:
     234             :     //    [END_BLOCK, <align4bytes>]
     235       79203 :     EmitCode(bitc::END_BLOCK);
     236       79203 :     FlushToWord();
     237             : 
     238             :     // Compute the size of the block, in words, not counting the size field.
     239       79203 :     size_t SizeInWords = GetWordIndex() - B.StartSizeWord - 1;
     240       79203 :     uint64_t BitNo = uint64_t(B.StartSizeWord) * 32;
     241             : 
     242             :     // Update the block size field in the header of this sub-block.
     243      158406 :     BackpatchWord(BitNo, SizeInWords);
     244             : 
     245             :     // Restore the inner block's code size and abbrev table.
     246       79203 :     CurCodeSize = B.PrevCodeSize;
     247       79203 :     CurAbbrevs = std::move(B.PrevAbbrevs);
     248       79204 :     BlockScope.pop_back();
     249       79204 :   }
     250             : 
     251             :   //===--------------------------------------------------------------------===//
     252             :   // Record Emission
     253             :   //===--------------------------------------------------------------------===//
     254             : 
     255             : private:
     256             :   /// EmitAbbreviatedLiteral - Emit a literal value according to its abbrev
     257             :   /// record.  This is a no-op, since the abbrev specifies the literal to use.
     258             :   template<typename uintty>
     259             :   void EmitAbbreviatedLiteral(const BitCodeAbbrevOp &Op, uintty V) {
     260             :     assert(Op.isLiteral() && "Not a literal");
     261             :     // If the abbrev specifies the literal value to use, don't emit
     262             :     // anything.
     263             :     assert(V == Op.getLiteralValue() &&
     264             :            "Invalid abbrev for record!");
     265             :   }
     266             : 
     267             :   /// EmitAbbreviatedField - Emit a single scalar field value with the specified
     268             :   /// encoding.
     269             :   template<typename uintty>
     270     5529619 :   void EmitAbbreviatedField(const BitCodeAbbrevOp &Op, uintty V) {
     271             :     assert(!Op.isLiteral() && "Literals should use EmitAbbreviatedLiteral!");
     272             : 
     273             :     // Encode the value as we are commanded.
     274     5529619 :     switch (Op.getEncoding()) {
     275           0 :     default: llvm_unreachable("Unknown encoding!");
     276     2824041 :     case BitCodeAbbrevOp::Fixed:
     277     2824041 :       if (Op.getEncodingData())
     278     2823613 :         Emit((unsigned)V, (unsigned)Op.getEncodingData());
     279             :       break;
     280     2391869 :     case BitCodeAbbrevOp::VBR:
     281     2391869 :       if (Op.getEncodingData())
     282     2391869 :         EmitVBR64(V, (unsigned)Op.getEncodingData());
     283             :       break;
     284      313709 :     case BitCodeAbbrevOp::Char6:
     285      627418 :       Emit(BitCodeAbbrevOp::EncodeChar6((char)V), 6);
     286      313709 :       break;
     287             :     }
     288     5529619 :   }
     289             : 
     290             :   /// EmitRecordWithAbbrevImpl - This is the core implementation of the record
     291             :   /// emission code.  If BlobData is non-null, then it specifies an array of
     292             :   /// data that should be emitted as part of the Blob or Array operand that is
     293             :   /// known to exist at the end of the record. If Code is specified, then
     294             :   /// it is the record code to emit before the Vals, which must not contain
     295             :   /// the code.
     296             :   template <typename uintty>
     297      742236 :   void EmitRecordWithAbbrevImpl(unsigned Abbrev, ArrayRef<uintty> Vals,
     298             :                                 StringRef Blob, Optional<unsigned> Code) {
     299      742236 :     const char *BlobData = Blob.data();
     300      742236 :     unsigned BlobLen = (unsigned) Blob.size();
     301      742236 :     unsigned AbbrevNo = Abbrev-bitc::FIRST_APPLICATION_ABBREV;
     302             :     assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
     303     1484472 :     const BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo].get();
     304             : 
     305      742236 :     EmitCode(Abbrev);
     306             : 
     307     1484472 :     unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos());
     308      742236 :     if (Code) {
     309             :       assert(e && "Expected non-empty abbreviation");
     310      970628 :       const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i++);
     311             : 
     312      485314 :       if (Op.isLiteral())
     313             :         EmitAbbreviatedLiteral(Op, Code.getValue());
     314             :       else {
     315             :         assert(Op.getEncoding() != BitCodeAbbrevOp::Array &&
     316             :                Op.getEncoding() != BitCodeAbbrevOp::Blob &&
     317             :                "Expected literal or scalar");
     318          54 :         EmitAbbreviatedField(Op, Code.getValue());
     319             :       }
     320             :     }
     321             : 
     322             :     unsigned RecordIdx = 0;
     323    16096692 :     for (; i != e; ++i) {
     324     7677228 :       const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
     325     7677228 :       if (Op.isLiteral()) {
     326             :         assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
     327     5372566 :         EmitAbbreviatedLiteral(Op, Vals[RecordIdx]);
     328     2686283 :         ++RecordIdx;
     329     4990945 :       } else if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
     330             :         // Array case.
     331             :         assert(i + 2 == e && "array op not second to last?");
     332      302048 :         const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
     333             : 
     334             :         // If this record has blob data, emit it, otherwise we must have record
     335             :         // entries to encode this way.
     336      151024 :         if (BlobData) {
     337             :           assert(RecordIdx == Vals.size() &&
     338             :                  "Blob data and record entries specified for array!");
     339             :           // Emit a vbr6 to indicate the number of elements present.
     340           0 :           EmitVBR(static_cast<uint32_t>(BlobLen), 6);
     341             : 
     342             :           // Emit each field.
     343           0 :           for (unsigned i = 0; i != BlobLen; ++i)
     344           0 :             EmitAbbreviatedField(EltEnc, (unsigned char)BlobData[i]);
     345             : 
     346             :           // Know that blob data is consumed for assertion below.
     347             :           BlobData = nullptr;
     348             :         } else {
     349             :           // Emit a vbr6 to indicate the number of elements present.
     350      151024 :           EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
     351             : 
     352             :           // Emit each field.
     353      936389 :           for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx)
     354     1570730 :             EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
     355             :         }
     356     4839921 :       } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) {
     357             :         // If this record has blob data, emit it, otherwise we must have record
     358             :         // entries to encode this way.
     359             : 
     360       95721 :         if (BlobData) {
     361             :           assert(RecordIdx == Vals.size() &&
     362             :                  "Blob data and record entries specified for blob operand!");
     363             : 
     364             :           assert(Blob.data() == BlobData && "BlobData got moved");
     365             :           assert(Blob.size() == BlobLen && "BlobLen got changed");
     366       94459 :           emitBlob(Blob);
     367       94459 :           BlobData = nullptr;
     368             :         } else {
     369        2524 :           emitBlob(Vals.slice(RecordIdx));
     370             :         }
     371             :       } else {  // Single scalar field.
     372             :         assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
     373     9488400 :         EmitAbbreviatedField(Op, Vals[RecordIdx]);
     374     4744200 :         ++RecordIdx;
     375             :       }
     376             :     }
     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!");
     380      742236 :   }
     381             : 
     382             : public:
     383             :   /// Emit a blob, including flushing before and tail-padding.
     384             :   template <class UIntTy>
     385       95725 :   void emitBlob(ArrayRef<UIntTy> Bytes, bool ShouldEmitSize = true) {
     386             :     // Emit a vbr6 to indicate the number of elements present.
     387       95725 :     if (ShouldEmitSize)
     388       95722 :       EmitVBR(static_cast<uint32_t>(Bytes.size()), 6);
     389             : 
     390             :     // Flush to a 32-bit alignment boundary.
     391       95725 :     FlushToWord();
     392             : 
     393             :     // Emit literal bytes.
     394   136010502 :     for (const auto &B : Bytes) {
     395             :       assert(isUInt<8>(B) && "Value too large to emit as byte");
     396   271638104 :       WriteByte((unsigned char)B);
     397             :     }
     398             : 
     399             :     // Align end to 32-bits.
     400      283818 :     while (GetBufferOffset() & 3)
     401             :       WriteByte(0);
     402       95725 :   }
     403             :   void emitBlob(StringRef Bytes, bool ShouldEmitSize = true) {
     404      188926 :     emitBlob(makeArrayRef((const uint8_t *)Bytes.data(), Bytes.size()),
     405             :              ShouldEmitSize);
     406             :   }
     407             : 
     408             :   /// EmitRecord - Emit the specified record to the stream, using an abbrev if
     409             :   /// we have one to compress the output.
     410             :   template <typename Container>
     411     3430705 :   void EmitRecord(unsigned Code, const Container &Vals, unsigned Abbrev = 0) {
     412     3430705 :     if (!Abbrev) {
     413             :       // If we don't have an abbrev to use, emit this in its fully unabbreviated
     414             :       // form.
     415     2945391 :       auto Count = static_cast<uint32_t>(makeArrayRef(Vals).size());
     416     2945391 :       EmitCode(bitc::UNABBREV_RECORD);
     417     2945391 :       EmitVBR(Code, 6);
     418     2945391 :       EmitVBR(Count, 6);
     419    39509600 :       for (unsigned i = 0, e = Count; i != e; ++i)
     420    73114997 :         EmitVBR64(Vals[i], 6);
     421             :       return;
     422             :     }
     423             : 
     424     1455942 :     EmitRecordWithAbbrevImpl(Abbrev, makeArrayRef(Vals), StringRef(), Code);
     425             :   }
     426             : 
     427             :   /// EmitRecordWithAbbrev - Emit a record with the specified abbreviation.
     428             :   /// Unlike EmitRecord, the code for the record should be included in Vals as
     429             :   /// the first entry.
     430             :   template <typename Container>
     431      157542 :   void EmitRecordWithAbbrev(unsigned Abbrev, const Container &Vals) {
     432      483603 :     EmitRecordWithAbbrevImpl(Abbrev, makeArrayRef(Vals), StringRef(), None);
     433      157542 :   }
     434             : 
     435             :   /// EmitRecordWithBlob - Emit the specified record to the stream, using an
     436             :   /// abbrev that includes a blob at the end.  The blob data to emit is
     437             :   /// specified by the pointer and length specified at the end.  In contrast to
     438             :   /// EmitRecord, this routine expects that the first entry in Vals is the code
     439             :   /// of the record.
     440             :   template <typename Container>
     441             :   void EmitRecordWithBlob(unsigned Abbrev, const Container &Vals,
     442             :                           StringRef Blob) {
     443      271257 :     EmitRecordWithAbbrevImpl(Abbrev, makeArrayRef(Vals), Blob, None);
     444             :   }
     445             :   template <typename Container>
     446             :   void EmitRecordWithBlob(unsigned Abbrev, const Container &Vals,
     447             :                           const char *BlobData, unsigned BlobLen) {
     448             :     return EmitRecordWithAbbrevImpl(Abbrev, makeArrayRef(Vals),
     449       13876 :                                     StringRef(BlobData, BlobLen), None);
     450             :   }
     451             : 
     452             :   /// EmitRecordWithArray - Just like EmitRecordWithBlob, works with records
     453             :   /// that end with an array.
     454             :   template <typename Container>
     455             :   void EmitRecordWithArray(unsigned Abbrev, const Container &Vals,
     456             :                            StringRef Array) {
     457             :     EmitRecordWithAbbrevImpl(Abbrev, makeArrayRef(Vals), Array, None);
     458             :   }
     459             :   template <typename Container>
     460             :   void EmitRecordWithArray(unsigned Abbrev, const Container &Vals,
     461             :                            const char *ArrayData, unsigned ArrayLen) {
     462             :     return EmitRecordWithAbbrevImpl(Abbrev, makeArrayRef(Vals),
     463             :                                     StringRef(ArrayData, ArrayLen), None);
     464             :   }
     465             : 
     466             :   //===--------------------------------------------------------------------===//
     467             :   // Abbrev Emission
     468             :   //===--------------------------------------------------------------------===//
     469             : 
     470             : private:
     471             :   // Emit the abbreviation as a DEFINE_ABBREV record.
     472      216411 :   void EncodeAbbrev(const BitCodeAbbrev &Abbv) {
     473      216411 :     EmitCode(bitc::DEFINE_ABBREV);
     474      216411 :     EmitVBR(Abbv.getNumOperandInfos(), 5);
     475     1758112 :     for (unsigned i = 0, e = static_cast<unsigned>(Abbv.getNumOperandInfos());
     476     1541699 :          i != e; ++i) {
     477     1325288 :       const BitCodeAbbrevOp &Op = Abbv.getOperandInfo(i);
     478     1325288 :       Emit(Op.isLiteral(), 1);
     479     1325288 :       if (Op.isLiteral()) {
     480      477685 :         EmitVBR64(Op.getLiteralValue(), 8);
     481             :       } else {
     482      847603 :         Emit(Op.getEncoding(), 3);
     483      695537 :         if (Op.hasEncodingData())
     484      695537 :           EmitVBR64(Op.getEncodingData(), 5);
     485             :       }
     486             :     }
     487      216411 :   }
     488             : public:
     489             : 
     490             :   /// EmitAbbrev - This emits an abbreviation to the stream.  Note that this
     491             :   /// method takes ownership of the specified abbrev.
     492      158137 :   unsigned EmitAbbrev(std::shared_ptr<BitCodeAbbrev> Abbv) {
     493             :     // Emit the abbreviation as a record.
     494      158137 :     EncodeAbbrev(*Abbv);
     495      316274 :     CurAbbrevs.push_back(std::move(Abbv));
     496      316274 :     return static_cast<unsigned>(CurAbbrevs.size())-1 +
     497      158137 :       bitc::FIRST_APPLICATION_ABBREV;
     498             :   }
     499             : 
     500             :   //===--------------------------------------------------------------------===//
     501             :   // BlockInfo Block Emission
     502             :   //===--------------------------------------------------------------------===//
     503             : 
     504             :   /// EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK.
     505        6314 :   void EnterBlockInfoBlock() {
     506        6314 :     EnterSubblock(bitc::BLOCKINFO_BLOCK_ID, 2);
     507        6314 :     BlockInfoCurBID = ~0U;
     508       12628 :     BlockInfoRecords.clear();
     509        6314 :   }
     510             : private:
     511             :   /// SwitchToBlockID - If we aren't already talking about the specified block
     512             :   /// ID, emit a BLOCKINFO_CODE_SETBID record.
     513       58274 :   void SwitchToBlockID(unsigned BlockID) {
     514      105601 :     if (BlockInfoCurBID == BlockID) return;
     515       21894 :     SmallVector<unsigned, 2> V;
     516       10947 :     V.push_back(BlockID);
     517       10947 :     EmitRecord(bitc::BLOCKINFO_CODE_SETBID, V);
     518       10947 :     BlockInfoCurBID = BlockID;
     519             :   }
     520             : 
     521       58274 :   BlockInfo &getOrCreateBlockInfo(unsigned BlockID) {
     522       58274 :     if (BlockInfo *BI = getBlockInfo(BlockID))
     523             :       return *BI;
     524             : 
     525             :     // Otherwise, add a new record.
     526       10947 :     BlockInfoRecords.emplace_back();
     527       21894 :     BlockInfoRecords.back().BlockID = BlockID;
     528       21894 :     return BlockInfoRecords.back();
     529             :   }
     530             : 
     531             : public:
     532             : 
     533             :   /// EmitBlockInfoAbbrev - Emit a DEFINE_ABBREV record for the specified
     534             :   /// BlockID.
     535       58274 :   unsigned EmitBlockInfoAbbrev(unsigned BlockID, std::shared_ptr<BitCodeAbbrev> Abbv) {
     536       58274 :     SwitchToBlockID(BlockID);
     537       58274 :     EncodeAbbrev(*Abbv);
     538             : 
     539             :     // Add the abbrev to the specified block record.
     540       58274 :     BlockInfo &Info = getOrCreateBlockInfo(BlockID);
     541      116548 :     Info.Abbrevs.push_back(std::move(Abbv));
     542             : 
     543      116548 :     return Info.Abbrevs.size()-1+bitc::FIRST_APPLICATION_ABBREV;
     544             :   }
     545             : };
     546             : 
     547             : 
     548             : } // End llvm namespace
     549             : 
     550             : #endif

Generated by: LCOV version 1.13