| Index: include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h
|
| diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h
|
| similarity index 55%
|
| copy from include/llvm/Bitcode/BitstreamWriter.h
|
| copy to include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h
|
| index 9e2c2fa4a15635820ce673457b98223369d55f3b..b0054f5be376c7077e91546b7fa19196aac8bb1f 100644
|
| --- a/include/llvm/Bitcode/BitstreamWriter.h
|
| +++ b/include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h
|
| @@ -1,4 +1,4 @@
|
| -//===- BitstreamWriter.h - Low-level bitstream writer interface -*- C++ -*-===//
|
| +//===- NaClBitstreamWriter.h - NaCl bitstream writer ------------*- C++ -*-===//
|
| //
|
| // The LLVM Compiler Infrastructure
|
| //
|
| @@ -12,17 +12,17 @@
|
| //
|
| //===----------------------------------------------------------------------===//
|
|
|
| -#ifndef LLVM_BITCODE_BITSTREAMWRITER_H
|
| -#define LLVM_BITCODE_BITSTREAMWRITER_H
|
| +#ifndef LLVM_BITCODE_NACL_NACLBITSTREAMWRITER_H
|
| +#define LLVM_BITCODE_NACL_NACLBITSTREAMWRITER_H
|
|
|
| #include "llvm/ADT/SmallVector.h"
|
| #include "llvm/ADT/StringRef.h"
|
| -#include "llvm/Bitcode/BitCodes.h"
|
| +#include "llvm/Bitcode/NaCl/NaClBitCodes.h"
|
| #include <vector>
|
|
|
| namespace llvm {
|
|
|
| -class BitstreamWriter {
|
| +class NaClBitstreamWriter {
|
| SmallVectorImpl<char> &Out;
|
|
|
| /// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use.
|
| @@ -33,20 +33,21 @@ class BitstreamWriter {
|
|
|
| /// CurCodeSize - This is the declared size of code values used for the
|
| /// current block, in bits.
|
| - unsigned CurCodeSize;
|
| + NaClBitcodeSelectorAbbrev CurCodeSize;
|
|
|
| /// BlockInfoCurBID - When emitting a BLOCKINFO_BLOCK, this is the currently
|
| /// selected BLOCK ID.
|
| unsigned BlockInfoCurBID;
|
|
|
| /// CurAbbrevs - Abbrevs installed at in this block.
|
| - std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> CurAbbrevs;
|
| + std::vector<NaClBitCodeAbbrev*> CurAbbrevs;
|
|
|
| struct Block {
|
| - unsigned PrevCodeSize;
|
| + NaClBitcodeSelectorAbbrev PrevCodeSize;
|
| unsigned StartSizeWord;
|
| - std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> PrevAbbrevs;
|
| - Block(unsigned PCS, unsigned SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {}
|
| + std::vector<NaClBitCodeAbbrev*> PrevAbbrevs;
|
| + Block(const NaClBitcodeSelectorAbbrev& PCS, unsigned SSW)
|
| + : PrevCodeSize(PCS), StartSizeWord(SSW) {}
|
| };
|
|
|
| /// BlockScope - This tracks the current blocks that we have entered.
|
| @@ -56,10 +57,34 @@ class BitstreamWriter {
|
| /// These describe abbreviations that all blocks of the specified ID inherit.
|
| struct BlockInfo {
|
| unsigned BlockID;
|
| - std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> Abbrevs;
|
| + std::vector<NaClBitCodeAbbrev*> Abbrevs;
|
| };
|
| std::vector<BlockInfo> BlockInfoRecords;
|
|
|
| + /// AbbrevValues - Wrapper class that allows the bitstream writer to
|
| + /// prefix a code to the set of values, associated with a record to
|
| + /// emit, without having to destructively change the contents of
|
| + /// values.
|
| + template<typename uintty>
|
| + struct AbbrevValues {
|
| + AbbrevValues(uintty Code, const SmallVectorImpl<uintty> &Values)
|
| + : Code(Code), Values(Values) {}
|
| +
|
| + size_t size() const {
|
| + return Values.size() + 1;
|
| + }
|
| +
|
| + uintty operator[](size_t Index) const {
|
| + return Index == 0 ? Code : Values[Index-1];
|
| + }
|
| +
|
| + private:
|
| + // The code to use (if not DONT_USE_CODE).
|
| + uintty Code;
|
| + const SmallVectorImpl<uintty> &Values;
|
| + };
|
| +
|
| +public:
|
| // BackpatchWord - Backpatch a 32-bit word in the output with the specified
|
| // value.
|
| void BackpatchWord(unsigned ByteNo, unsigned NewWord) {
|
| @@ -69,6 +94,7 @@ class BitstreamWriter {
|
| Out[ByteNo ] = (unsigned char)(NewWord >> 24);
|
| }
|
|
|
| +private:
|
| void WriteByte(unsigned char Value) {
|
| Out.push_back(Value);
|
| }
|
| @@ -93,12 +119,22 @@ class BitstreamWriter {
|
| }
|
|
|
| public:
|
| - explicit BitstreamWriter(SmallVectorImpl<char> &O)
|
| - : Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {}
|
| + explicit NaClBitstreamWriter(SmallVectorImpl<char> &O)
|
| + : Out(O), CurBit(0), CurValue(0), CurCodeSize() {}
|
|
|
| - ~BitstreamWriter() {
|
| - assert(CurBit == 0 && "Unflushed data remaining");
|
| + ~NaClBitstreamWriter() {
|
| + assert(CurBit == 0 && "Unflused data remaining");
|
| assert(BlockScope.empty() && CurAbbrevs.empty() && "Block imbalance");
|
| +
|
| + // Free the BlockInfoRecords.
|
| + while (!BlockInfoRecords.empty()) {
|
| + BlockInfo &Info = BlockInfoRecords.back();
|
| + // Free blockinfo abbrev info.
|
| + for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size());
|
| + i != e; ++i)
|
| + Info.Abbrevs[i]->dropRef();
|
| + BlockInfoRecords.pop_back();
|
| + }
|
| }
|
|
|
| /// \brief Retrieve the current position in the stream, in bits.
|
| @@ -146,6 +182,7 @@ public:
|
|
|
| void EmitVBR(uint32_t Val, unsigned NumBits) {
|
| assert(NumBits <= 32 && "Too many bits to emit!");
|
| + assert(NumBits > 1 && "Too few bits to emit!");
|
| uint32_t Threshold = 1U << (NumBits-1);
|
|
|
| // Emit the bits with VBR encoding, NumBits-1 bits at a time.
|
| @@ -159,6 +196,7 @@ public:
|
|
|
| void EmitVBR64(uint64_t Val, unsigned NumBits) {
|
| assert(NumBits <= 32 && "Too many bits to emit!");
|
| + assert(NumBits > 1 && "Too few bits to emit!");
|
| if ((uint32_t)Val == Val)
|
| return EmitVBR((uint32_t)Val, NumBits);
|
|
|
| @@ -176,7 +214,10 @@ public:
|
|
|
| /// EmitCode - Emit the specified code.
|
| void EmitCode(unsigned Val) {
|
| - Emit(Val, CurCodeSize);
|
| + if (CurCodeSize.IsFixed)
|
| + Emit(Val, CurCodeSize.NumBits);
|
| + else
|
| + EmitVBR(Val, CurCodeSize.NumBits);
|
| }
|
|
|
| //===--------------------------------------------------------------------===//
|
| @@ -194,22 +235,28 @@ public:
|
| i != e; ++i)
|
| if (BlockInfoRecords[i].BlockID == BlockID)
|
| return &BlockInfoRecords[i];
|
| - return nullptr;
|
| + return 0;
|
| }
|
|
|
| - void EnterSubblock(unsigned BlockID, unsigned CodeLen) {
|
| +private:
|
| + // Enter block using CodeLen bits to read the size of the code
|
| + // selector associated with the block.
|
| + void EnterSubblock(unsigned BlockID,
|
| + const NaClBitcodeSelectorAbbrev& CodeLen,
|
| + BlockInfo *Info) {
|
| // Block header:
|
| // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen]
|
| - EmitCode(bitc::ENTER_SUBBLOCK);
|
| - EmitVBR(BlockID, bitc::BlockIDWidth);
|
| - EmitVBR(CodeLen, bitc::CodeLenWidth);
|
| + EmitCode(naclbitc::ENTER_SUBBLOCK);
|
| + EmitVBR(BlockID, naclbitc::BlockIDWidth);
|
| + assert(CodeLen.IsFixed && "Block codelens must be fixed");
|
| + EmitVBR(CodeLen.NumBits, naclbitc::CodeLenWidth);
|
| FlushToWord();
|
|
|
| unsigned BlockSizeWordIndex = GetWordIndex();
|
| - unsigned OldCodeSize = CurCodeSize;
|
| + NaClBitcodeSelectorAbbrev OldCodeSize(CurCodeSize);
|
|
|
| // Emit a placeholder, which will be replaced when the block is popped.
|
| - Emit(0, bitc::BlockSizeWidth);
|
| + Emit(0, naclbitc::BlockSizeWidth);
|
|
|
| CurCodeSize = CodeLen;
|
|
|
| @@ -220,19 +267,53 @@ public:
|
|
|
| // If there is a blockinfo for this BlockID, add all the predefined abbrevs
|
| // to the abbrev list.
|
| - if (BlockInfo *Info = getBlockInfo(BlockID)) {
|
| - CurAbbrevs.insert(CurAbbrevs.end(), Info->Abbrevs.begin(),
|
| - Info->Abbrevs.end());
|
| + if (Info) {
|
| + for (unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size());
|
| + i != e; ++i) {
|
| + CurAbbrevs.push_back(Info->Abbrevs[i]);
|
| + Info->Abbrevs[i]->addRef();
|
| + }
|
| }
|
| }
|
|
|
| +public:
|
| + /// \brief Enter block using CodeLen bits to read the size of the code
|
| + /// selector associated with the block.
|
| + void EnterSubblock(unsigned BlockID,
|
| + const NaClBitcodeSelectorAbbrev& CodeLen) {
|
| + EnterSubblock(BlockID, CodeLen, getBlockInfo(BlockID));
|
| + }
|
| +
|
| + /// \brief Enter block, using a code length based on the number of
|
| + /// (global) BlockInfo entries defined for the block. Note: This
|
| + /// should be used only if the block doesn't define any local abbreviations.
|
| + void EnterSubblock(unsigned BlockID) {
|
| + BlockInfo *Info = getBlockInfo(BlockID);
|
| + size_t NumAbbrevs = Info ? Info->Abbrevs.size() : 0;
|
| + NaClBitcodeSelectorAbbrev DefaultCodeLen(
|
| + naclbitc::DEFAULT_MAX_ABBREV+NumAbbrevs);
|
| + EnterSubblock(BlockID, DefaultCodeLen, Info);
|
| + }
|
| +
|
| + /// \brief Enter block with the given number of abbreviations.
|
| + void EnterSubblock(unsigned BlockID, unsigned NumAbbrev) {
|
| + NaClBitcodeSelectorAbbrev CodeLenAbbrev(NumAbbrev);
|
| + EnterSubblock(BlockID, CodeLenAbbrev);
|
| + }
|
| +
|
| void ExitBlock() {
|
| assert(!BlockScope.empty() && "Block scope imbalance!");
|
| +
|
| + // Delete all abbrevs.
|
| + for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size());
|
| + i != e; ++i)
|
| + CurAbbrevs[i]->dropRef();
|
| +
|
| const Block &B = BlockScope.back();
|
|
|
| // Block tail:
|
| // [END_BLOCK, <align4bytes>]
|
| - EmitCode(bitc::END_BLOCK);
|
| + EmitCode(naclbitc::END_BLOCK);
|
| FlushToWord();
|
|
|
| // Compute the size of the block, in words, not counting the size field.
|
| @@ -244,7 +325,7 @@ public:
|
|
|
| // Restore the inner block's code size and abbrev table.
|
| CurCodeSize = B.PrevCodeSize;
|
| - CurAbbrevs = std::move(B.PrevAbbrevs);
|
| + BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
|
| BlockScope.pop_back();
|
| }
|
|
|
| @@ -253,146 +334,84 @@ public:
|
| //===--------------------------------------------------------------------===//
|
|
|
| private:
|
| - /// EmitAbbreviatedLiteral - Emit a literal value according to its abbrev
|
| - /// record. This is a no-op, since the abbrev specifies the literal to use.
|
| - template<typename uintty>
|
| - void EmitAbbreviatedLiteral(const BitCodeAbbrevOp &Op, uintty V) {
|
| - assert(Op.isLiteral() && "Not a literal");
|
| - // If the abbrev specifies the literal value to use, don't emit
|
| - // anything.
|
| - assert(V == Op.getLiteralValue() &&
|
| - "Invalid abbrev for record!");
|
| - }
|
| -
|
| /// EmitAbbreviatedField - Emit a single scalar field value with the specified
|
| /// encoding.
|
| template<typename uintty>
|
| - void EmitAbbreviatedField(const BitCodeAbbrevOp &Op, uintty V) {
|
| - assert(!Op.isLiteral() && "Literals should use EmitAbbreviatedLiteral!");
|
| -
|
| - // Encode the value as we are commanded.
|
| + void EmitAbbreviatedField(const NaClBitCodeAbbrevOp &Op, uintty V) {
|
| switch (Op.getEncoding()) {
|
| - default: llvm_unreachable("Unknown encoding!");
|
| - case BitCodeAbbrevOp::Fixed:
|
| - if (Op.getEncodingData())
|
| - Emit((unsigned)V, (unsigned)Op.getEncodingData());
|
| + case NaClBitCodeAbbrevOp::Literal:
|
| + // This is a no-op, since the abbrev specifies the literal to use.
|
| + assert(V == Op.getValue() && "Invalid abbrev for record!");
|
| break;
|
| - case BitCodeAbbrevOp::VBR:
|
| - if (Op.getEncodingData())
|
| - EmitVBR64(V, (unsigned)Op.getEncodingData());
|
| + case NaClBitCodeAbbrevOp::Fixed:
|
| + if (Op.getValue())
|
| + Emit((unsigned)V, (unsigned)Op.getValue());
|
| break;
|
| - case BitCodeAbbrevOp::Char6:
|
| - Emit(BitCodeAbbrevOp::EncodeChar6((char)V), 6);
|
| + case NaClBitCodeAbbrevOp::VBR:
|
| + if (Op.getValue())
|
| + EmitVBR64(V, (unsigned)Op.getValue());
|
| + break;
|
| + case NaClBitCodeAbbrevOp::Array:
|
| + report_fatal_error("Not to be used with array abbreviation op!");
|
| + case NaClBitCodeAbbrevOp::Char6:
|
| + Emit(NaClBitCodeAbbrevOp::EncodeChar6((char)V), 6);
|
| break;
|
| }
|
| }
|
|
|
| /// EmitRecordWithAbbrevImpl - This is the core implementation of the record
|
| - /// emission code. If BlobData is non-null, then it specifies an array of
|
| - /// data that should be emitted as part of the Blob or Array operand that is
|
| - /// known to exist at the end of the record.
|
| + /// emission code.
|
| template<typename uintty>
|
| - void EmitRecordWithAbbrevImpl(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
|
| - StringRef Blob) {
|
| - const char *BlobData = Blob.data();
|
| - unsigned BlobLen = (unsigned) Blob.size();
|
| - unsigned AbbrevNo = Abbrev-bitc::FIRST_APPLICATION_ABBREV;
|
| + void EmitRecordWithAbbrevImpl(unsigned Abbrev,
|
| + const AbbrevValues<uintty> &Vals) {
|
| + unsigned AbbrevNo = Abbrev-naclbitc::FIRST_APPLICATION_ABBREV;
|
| assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
|
| - const BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo].get();
|
| + NaClBitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo];
|
|
|
| EmitCode(Abbrev);
|
|
|
| unsigned RecordIdx = 0;
|
| for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos());
|
| i != e; ++i) {
|
| - const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
|
| - if (Op.isLiteral()) {
|
| - assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
|
| - EmitAbbreviatedLiteral(Op, Vals[RecordIdx]);
|
| - ++RecordIdx;
|
| - } else if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
|
| + const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
|
| + if (Op.getEncoding() == NaClBitCodeAbbrevOp::Array) {
|
| // Array case.
|
| assert(i+2 == e && "array op not second to last?");
|
| - const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
|
| -
|
| - // If this record has blob data, emit it, otherwise we must have record
|
| - // entries to encode this way.
|
| - if (BlobData) {
|
| - assert(RecordIdx == Vals.size() &&
|
| - "Blob data and record entries specified for array!");
|
| - // Emit a vbr6 to indicate the number of elements present.
|
| - EmitVBR(static_cast<uint32_t>(BlobLen), 6);
|
| -
|
| - // Emit each field.
|
| - for (unsigned i = 0; i != BlobLen; ++i)
|
| - EmitAbbreviatedField(EltEnc, (unsigned char)BlobData[i]);
|
| -
|
| - // Know that blob data is consumed for assertion below.
|
| - BlobData = nullptr;
|
| - } else {
|
| - // Emit a vbr6 to indicate the number of elements present.
|
| - EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
|
| -
|
| - // Emit each field.
|
| - for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx)
|
| - EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
|
| - }
|
| - } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) {
|
| - // If this record has blob data, emit it, otherwise we must have record
|
| - // entries to encode this way.
|
| + const NaClBitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
|
|
|
| // Emit a vbr6 to indicate the number of elements present.
|
| - if (BlobData) {
|
| - EmitVBR(static_cast<uint32_t>(BlobLen), 6);
|
| - assert(RecordIdx == Vals.size() &&
|
| - "Blob data and record entries specified for blob operand!");
|
| - } else {
|
| - EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
|
| - }
|
| -
|
| - // Flush to a 32-bit alignment boundary.
|
| - FlushToWord();
|
| -
|
| - // Emit each field as a literal byte.
|
| - if (BlobData) {
|
| - for (unsigned i = 0; i != BlobLen; ++i)
|
| - WriteByte((unsigned char)BlobData[i]);
|
| -
|
| - // Know that blob data is consumed for assertion below.
|
| - BlobData = nullptr;
|
| - } else {
|
| - for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx) {
|
| - assert(isUInt<8>(Vals[RecordIdx]) &&
|
| - "Value too large to emit as blob");
|
| - WriteByte((unsigned char)Vals[RecordIdx]);
|
| - }
|
| - }
|
| -
|
| - // Align end to 32-bits.
|
| - while (GetBufferOffset() & 3)
|
| - WriteByte(0);
|
| - } else { // Single scalar field.
|
| + EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
|
| +
|
| + // Emit each field.
|
| + for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx)
|
| + EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
|
| + } else {
|
| assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
|
| EmitAbbreviatedField(Op, Vals[RecordIdx]);
|
| ++RecordIdx;
|
| }
|
| }
|
| assert(RecordIdx == Vals.size() && "Not all record operands emitted!");
|
| - assert(BlobData == nullptr &&
|
| - "Blob data specified for record that doesn't use it!");
|
| }
|
|
|
| public:
|
|
|
| + /// Returns true if the given abbreviation index corresponds to a user-defined
|
| + /// abbreviation.
|
| + bool isUserRecordAbbreviation(unsigned Abbrev) const {
|
| + return Abbrev >= naclbitc::FIRST_APPLICATION_ABBREV
|
| + && Abbrev < CurAbbrevs.size();
|
| + }
|
| +
|
| /// EmitRecord - Emit the specified record to the stream, using an abbrev if
|
| /// we have one to compress the output.
|
| template<typename uintty>
|
| - void EmitRecord(unsigned Code, SmallVectorImpl<uintty> &Vals,
|
| + void EmitRecord(unsigned Code, const SmallVectorImpl<uintty> &Vals,
|
| unsigned Abbrev = 0) {
|
| if (!Abbrev) {
|
| // If we don't have an abbrev to use, emit this in its fully unabbreviated
|
| // form.
|
| - EmitCode(bitc::UNABBREV_RECORD);
|
| + EmitCode(naclbitc::UNABBREV_RECORD);
|
| EmitVBR(Code, 6);
|
| EmitVBR(static_cast<uint32_t>(Vals.size()), 6);
|
| for (unsigned i = 0, e = static_cast<unsigned>(Vals.size()); i != e; ++i)
|
| @@ -400,48 +419,9 @@ public:
|
| return;
|
| }
|
|
|
| - // Insert the code into Vals to treat it uniformly.
|
| - Vals.insert(Vals.begin(), Code);
|
| -
|
| - EmitRecordWithAbbrev(Abbrev, Vals);
|
| - }
|
| -
|
| - /// EmitRecordWithAbbrev - Emit a record with the specified abbreviation.
|
| - /// Unlike EmitRecord, the code for the record should be included in Vals as
|
| - /// the first entry.
|
| - template<typename uintty>
|
| - void EmitRecordWithAbbrev(unsigned Abbrev, SmallVectorImpl<uintty> &Vals) {
|
| - EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef());
|
| - }
|
| -
|
| - /// EmitRecordWithBlob - Emit the specified record to the stream, using an
|
| - /// abbrev that includes a blob at the end. The blob data to emit is
|
| - /// specified by the pointer and length specified at the end. In contrast to
|
| - /// EmitRecord, this routine expects that the first entry in Vals is the code
|
| - /// of the record.
|
| - template<typename uintty>
|
| - void EmitRecordWithBlob(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
|
| - StringRef Blob) {
|
| - EmitRecordWithAbbrevImpl(Abbrev, Vals, Blob);
|
| - }
|
| - template<typename uintty>
|
| - void EmitRecordWithBlob(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
|
| - const char *BlobData, unsigned BlobLen) {
|
| - return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(BlobData, BlobLen));
|
| - }
|
| -
|
| - /// EmitRecordWithArray - Just like EmitRecordWithBlob, works with records
|
| - /// that end with an array.
|
| - template<typename uintty>
|
| - void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
|
| - StringRef Array) {
|
| - EmitRecordWithAbbrevImpl(Abbrev, Vals, Array);
|
| - }
|
| - template<typename uintty>
|
| - void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
|
| - const char *ArrayData, unsigned ArrayLen) {
|
| - return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(ArrayData,
|
| - ArrayLen));
|
| + // combine code and values, and then emit.
|
| + AbbrevValues<uintty> AbbrevVals(Code, Vals);
|
| + EmitRecordWithAbbrevImpl(Abbrev, AbbrevVals);
|
| }
|
|
|
| //===--------------------------------------------------------------------===//
|
| @@ -450,19 +430,20 @@ public:
|
|
|
| private:
|
| // Emit the abbreviation as a DEFINE_ABBREV record.
|
| - void EncodeAbbrev(BitCodeAbbrev *Abbv) {
|
| - EmitCode(bitc::DEFINE_ABBREV);
|
| + void EncodeAbbrev(NaClBitCodeAbbrev *Abbv) {
|
| + EmitCode(naclbitc::DEFINE_ABBREV);
|
| EmitVBR(Abbv->getNumOperandInfos(), 5);
|
| for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos());
|
| i != e; ++i) {
|
| - const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
|
| - Emit(Op.isLiteral(), 1);
|
| - if (Op.isLiteral()) {
|
| - EmitVBR64(Op.getLiteralValue(), 8);
|
| + const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
|
| + bool IsLiteral = Op.isLiteral();
|
| + Emit(IsLiteral, 1);
|
| + if (IsLiteral) {
|
| + EmitVBR64(Op.getValue(), 8);
|
| } else {
|
| Emit(Op.getEncoding(), 3);
|
| - if (Op.hasEncodingData())
|
| - EmitVBR64(Op.getEncodingData(), 5);
|
| + if (Op.hasValue())
|
| + EmitVBR64(Op.getValue(), 5);
|
| }
|
| }
|
| }
|
| @@ -470,12 +451,13 @@ public:
|
|
|
| /// EmitAbbrev - This emits an abbreviation to the stream. Note that this
|
| /// method takes ownership of the specified abbrev.
|
| - unsigned EmitAbbrev(BitCodeAbbrev *Abbv) {
|
| + unsigned EmitAbbrev(NaClBitCodeAbbrev *Abbv) {
|
| + assert(Abbv->isValid() && "Can't emit invalid abbreviation!");
|
| // Emit the abbreviation as a record.
|
| EncodeAbbrev(Abbv);
|
| CurAbbrevs.push_back(Abbv);
|
| return static_cast<unsigned>(CurAbbrevs.size())-1 +
|
| - bitc::FIRST_APPLICATION_ABBREV;
|
| + naclbitc::FIRST_APPLICATION_ABBREV;
|
| }
|
|
|
| //===--------------------------------------------------------------------===//
|
| @@ -483,8 +465,8 @@ public:
|
| //===--------------------------------------------------------------------===//
|
|
|
| /// EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK.
|
| - void EnterBlockInfoBlock(unsigned CodeWidth) {
|
| - EnterSubblock(bitc::BLOCKINFO_BLOCK_ID, CodeWidth);
|
| + void EnterBlockInfoBlock() {
|
| + EnterSubblock(naclbitc::BLOCKINFO_BLOCK_ID);
|
| BlockInfoCurBID = ~0U;
|
| }
|
| private:
|
| @@ -494,7 +476,7 @@ private:
|
| if (BlockInfoCurBID == BlockID) return;
|
| SmallVector<unsigned, 2> V;
|
| V.push_back(BlockID);
|
| - EmitRecord(bitc::BLOCKINFO_CODE_SETBID, V);
|
| + EmitRecord(naclbitc::BLOCKINFO_CODE_SETBID, V);
|
| BlockInfoCurBID = BlockID;
|
| }
|
|
|
| @@ -512,7 +494,7 @@ public:
|
|
|
| /// EmitBlockInfoAbbrev - Emit a DEFINE_ABBREV record for the specified
|
| /// BlockID.
|
| - unsigned EmitBlockInfoAbbrev(unsigned BlockID, BitCodeAbbrev *Abbv) {
|
| + unsigned EmitBlockInfoAbbrev(unsigned BlockID, NaClBitCodeAbbrev *Abbv) {
|
| SwitchToBlockID(BlockID);
|
| EncodeAbbrev(Abbv);
|
|
|
| @@ -520,7 +502,7 @@ public:
|
| BlockInfo &Info = getOrCreateBlockInfo(BlockID);
|
| Info.Abbrevs.push_back(Abbv);
|
|
|
| - return Info.Abbrevs.size()-1+bitc::FIRST_APPLICATION_ABBREV;
|
| + return Info.Abbrevs.size()-1+naclbitc::FIRST_APPLICATION_ABBREV;
|
| }
|
| };
|
|
|
|
|