X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FBitcode%2FBitstreamWriter.h;h=eef6076d6a45b37208e6c5d8c7ca0dcfe6e9a024;hb=cf0db29df20d9c665da7e82bb261bdd7cf7f1b2b;hp=42c68aac7d7b84e8e0c17505f54fd782fbb53236;hpb=88e48e7d58eeb138e30ce21592eb903c7f193c42;p=oota-llvm.git diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h index 42c68aac7d7..eef6076d6a4 100644 --- a/include/llvm/Bitcode/BitstreamWriter.h +++ b/include/llvm/Bitcode/BitstreamWriter.h @@ -12,12 +12,13 @@ // //===----------------------------------------------------------------------===// -#ifndef BITSTREAM_WRITER_H -#define BITSTREAM_WRITER_H +#ifndef LLVM_BITCODE_BITSTREAMWRITER_H +#define LLVM_BITCODE_BITSTREAMWRITER_H -#include "llvm/ADT/StringRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Bitcode/BitCodes.h" +#include "llvm/Support/Endian.h" #include namespace llvm { @@ -40,12 +41,12 @@ class BitstreamWriter { unsigned BlockInfoCurBID; /// CurAbbrevs - Abbrevs installed at in this block. - std::vector CurAbbrevs; + std::vector> CurAbbrevs; struct Block { unsigned PrevCodeSize; unsigned StartSizeWord; - std::vector PrevAbbrevs; + std::vector> PrevAbbrevs; Block(unsigned PCS, unsigned SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {} }; @@ -56,17 +57,14 @@ class BitstreamWriter { /// These describe abbreviations that all blocks of the specified ID inherit. struct BlockInfo { unsigned BlockID; - std::vector Abbrevs; + std::vector> Abbrevs; }; std::vector BlockInfoRecords; // BackpatchWord - Backpatch a 32-bit word in the output with the specified // value. void BackpatchWord(unsigned ByteNo, unsigned NewWord) { - Out[ByteNo++] = (unsigned char)(NewWord >> 0); - Out[ByteNo++] = (unsigned char)(NewWord >> 8); - Out[ByteNo++] = (unsigned char)(NewWord >> 16); - Out[ByteNo ] = (unsigned char)(NewWord >> 24); + support::endian::write32le(&Out[ByteNo], NewWord); } void WriteByte(unsigned char Value) { @@ -74,12 +72,9 @@ class BitstreamWriter { } void WriteWord(unsigned Value) { - unsigned char Bytes[4] = { - (unsigned char)(Value >> 0), - (unsigned char)(Value >> 8), - (unsigned char)(Value >> 16), - (unsigned char)(Value >> 24) }; - Out.append(&Bytes[0], &Bytes[4]); + Value = support::endian::byte_swap(Value); + Out.append(reinterpret_cast(&Value), + reinterpret_cast(&Value + 1)); } unsigned GetBufferOffset() const { @@ -97,18 +92,8 @@ public: : Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {} ~BitstreamWriter() { - assert(CurBit == 0 && "Unflused data remaining"); + assert(CurBit == 0 && "Unflushed 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(Info.Abbrevs.size()); - i != e; ++i) - Info.Abbrevs[i]->dropRef(); - BlockInfoRecords.pop_back(); - } } /// \brief Retrieve the current position in the stream, in bits. @@ -155,6 +140,7 @@ public: } void EmitVBR(uint32_t Val, unsigned NumBits) { + assert(NumBits <= 32 && "Too many bits to emit!"); uint32_t Threshold = 1U << (NumBits-1); // Emit the bits with VBR encoding, NumBits-1 bits at a time. @@ -167,10 +153,11 @@ public: } void EmitVBR64(uint64_t Val, unsigned NumBits) { + assert(NumBits <= 32 && "Too many bits to emit!"); if ((uint32_t)Val == Val) return EmitVBR((uint32_t)Val, NumBits); - uint64_t Threshold = 1U << (NumBits-1); + uint32_t Threshold = 1U << (NumBits-1); // Emit the bits with VBR encoding, NumBits-1 bits at a time. while (Val >= Threshold) { @@ -202,7 +189,7 @@ public: i != e; ++i) if (BlockInfoRecords[i].BlockID == BlockID) return &BlockInfoRecords[i]; - return 0; + return nullptr; } void EnterSubblock(unsigned BlockID, unsigned CodeLen) { @@ -223,28 +210,19 @@ public: // Push the outer block's abbrev set onto the stack, start out with an // empty abbrev set. - BlockScope.push_back(Block(OldCodeSize, BlockSizeWordIndex)); + BlockScope.emplace_back(OldCodeSize, BlockSizeWordIndex); BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); // If there is a blockinfo for this BlockID, add all the predefined abbrevs // to the abbrev list. if (BlockInfo *Info = getBlockInfo(BlockID)) { - for (unsigned i = 0, e = static_cast(Info->Abbrevs.size()); - i != e; ++i) { - CurAbbrevs.push_back(Info->Abbrevs[i]); - Info->Abbrevs[i]->addRef(); - } + CurAbbrevs.insert(CurAbbrevs.end(), Info->Abbrevs.begin(), + Info->Abbrevs.end()); } } void ExitBlock() { assert(!BlockScope.empty() && "Block scope imbalance!"); - - // Delete all abbrevs. - for (unsigned i = 0, e = static_cast(CurAbbrevs.size()); - i != e; ++i) - CurAbbrevs[i]->dropRef(); - const Block &B = BlockScope.back(); // Block tail: @@ -261,7 +239,7 @@ public: // Restore the inner block's code size and abbrev table. CurCodeSize = B.PrevCodeSize; - BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); + CurAbbrevs = std::move(B.PrevAbbrevs); BlockScope.pop_back(); } @@ -271,7 +249,7 @@ 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. + /// record. This is a no-op, since the abbrev specifies the literal to use. template void EmitAbbreviatedLiteral(const BitCodeAbbrevOp &Op, uintty V) { assert(Op.isLiteral() && "Not a literal"); @@ -280,13 +258,13 @@ private: assert(V == Op.getLiteralValue() && "Invalid abbrev for record!"); } - + /// EmitAbbreviatedField - Emit a single scalar field value with the specified /// encoding. template void EmitAbbreviatedField(const BitCodeAbbrevOp &Op, uintty V) { assert(!Op.isLiteral() && "Literals should use EmitAbbreviatedLiteral!"); - + // Encode the value as we are commanded. switch (Op.getEncoding()) { default: llvm_unreachable("Unknown encoding!"); @@ -303,7 +281,7 @@ private: 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 @@ -315,7 +293,7 @@ private: unsigned BlobLen = (unsigned) Blob.size(); unsigned AbbrevNo = Abbrev-bitc::FIRST_APPLICATION_ABBREV; assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); - BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo]; + const BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo].get(); EmitCode(Abbrev); @@ -339,13 +317,13 @@ private: "Blob data and record entries specified for array!"); // Emit a vbr6 to indicate the number of elements present. EmitVBR(static_cast(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 = 0; + BlobData = nullptr; } else { // Emit a vbr6 to indicate the number of elements present. EmitVBR(static_cast(Vals.size()-RecordIdx), 6); @@ -357,7 +335,7 @@ private: } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) { // If this record has blob data, emit it, otherwise we must have record // entries to encode this way. - + // Emit a vbr6 to indicate the number of elements present. if (BlobData) { EmitVBR(static_cast(BlobLen), 6); @@ -366,7 +344,7 @@ private: } else { EmitVBR(static_cast(Vals.size()-RecordIdx), 6); } - + // Flush to a 32-bit alignment boundary. FlushToWord(); @@ -374,12 +352,13 @@ private: if (BlobData) { for (unsigned i = 0; i != BlobLen; ++i) WriteByte((unsigned char)BlobData[i]); - + // Know that blob data is consumed for assertion below. - BlobData = 0; + BlobData = nullptr; } else { for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx) { - assert(Vals[RecordIdx] < 256 && "Value too large to emit as blob"); + assert(isUInt<8>(Vals[RecordIdx]) && + "Value too large to emit as blob"); WriteByte((unsigned char)Vals[RecordIdx]); } } @@ -394,10 +373,10 @@ private: } } assert(RecordIdx == Vals.size() && "Not all record operands emitted!"); - assert(BlobData == 0 && + assert(BlobData == nullptr && "Blob data specified for record that doesn't use it!"); } - + public: /// EmitRecord - Emit the specified record to the stream, using an abbrev if @@ -418,10 +397,10 @@ public: // 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. @@ -429,7 +408,7 @@ public: void EmitRecordWithAbbrev(unsigned Abbrev, SmallVectorImpl &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 @@ -456,10 +435,10 @@ public: template void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl &Vals, const char *ArrayData, unsigned ArrayLen) { - return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(ArrayData, + return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(ArrayData, ArrayLen)); } - + //===--------------------------------------------------------------------===// // Abbrev Emission //===--------------------------------------------------------------------===// @@ -501,7 +480,7 @@ public: /// EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK. void EnterBlockInfoBlock(unsigned CodeWidth) { EnterSubblock(bitc::BLOCKINFO_BLOCK_ID, CodeWidth); - BlockInfoCurBID = -1U; + BlockInfoCurBID = ~0U; } private: /// SwitchToBlockID - If we aren't already talking about the specified block @@ -519,7 +498,7 @@ private: return *BI; // Otherwise, add a new record. - BlockInfoRecords.push_back(BlockInfo()); + BlockInfoRecords.emplace_back(); BlockInfoRecords.back().BlockID = BlockID; return BlockInfoRecords.back(); } @@ -541,6 +520,6 @@ public: }; -} // End llvm namespace +} // namespace llvm #endif