From: Duncan P. N. Exon Smith Date: Sun, 27 Mar 2016 23:04:04 +0000 (+0000) Subject: BitcodeWriter: Simplify and test writing blobs, NFC X-Git-Tag: llvmorg-3.9.0-rc1~10789 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=376fa2606069cdd5840fd035312bad027d8b2428;p=platform%2Fupstream%2Fllvm.git BitcodeWriter: Simplify and test writing blobs, NFC Split helper out of EmitRecordWithAbbrevImpl called emitBlob to reduce code duplication, and add a few tests for it. No functionality change intended. llvm-svn: 264550 --- diff --git a/llvm/include/llvm/Bitcode/BitstreamWriter.h b/llvm/include/llvm/Bitcode/BitstreamWriter.h index 438f4a6..d613f5e1 100644 --- a/llvm/include/llvm/Bitcode/BitstreamWriter.h +++ b/llvm/include/llvm/Bitcode/BitstreamWriter.h @@ -361,36 +361,17 @@ private: // 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); assert(RecordIdx == Vals.size() && "Blob data and record entries specified for blob operand!"); - } else { - EmitVBR(static_cast(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. + assert(Blob.data() == BlobData && "BlobData got moved"); + assert(Blob.size() == BlobLen && "BlobLen got changed"); + emitBlob(Blob); 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]); - } + emitBlob(Vals.slice(RecordIdx)); } - - // Align end to 32-bits. - while (GetBufferOffset() & 3) - WriteByte(0); } else { // Single scalar field. assert(RecordIdx < Vals.size() && "Invalid abbrev/record"); EmitAbbreviatedField(Op, Vals[RecordIdx]); @@ -403,6 +384,30 @@ private: } public: + /// Emit a blob, including flushing before and tail-padding. + template + void emitBlob(ArrayRef Bytes, bool ShouldEmitSize = true) { + // Emit a vbr6 to indicate the number of elements present. + if (ShouldEmitSize) + EmitVBR(static_cast(Bytes.size()), 6); + + // Flush to a 32-bit alignment boundary. + FlushToWord(); + + // Emit literal bytes. + for (const auto &B : Bytes) { + assert(isUInt<8>(B) && "Value too large to emit as byte"); + WriteByte((unsigned char)B); + } + + // Align end to 32-bits. + while (GetBufferOffset() & 3) + WriteByte(0); + } + void emitBlob(StringRef Bytes, bool ShouldEmitSize = true) { + emitBlob(makeArrayRef((const uint8_t *)Bytes.data(), Bytes.size()), + ShouldEmitSize); + } /// EmitRecord - Emit the specified record to the stream, using an abbrev if /// we have one to compress the output. diff --git a/llvm/unittests/Bitcode/BitstreamWriterTest.cpp b/llvm/unittests/Bitcode/BitstreamWriterTest.cpp new file mode 100644 index 0000000..f17cc15 --- /dev/null +++ b/llvm/unittests/Bitcode/BitstreamWriterTest.cpp @@ -0,0 +1,59 @@ +//===- BitstreamWriterTest.cpp - Tests for BitstreamWriter ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Bitcode/BitstreamWriter.h" +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +TEST(BitstreamWriterTest, emitBlob) { + SmallString<64> Buffer; + BitstreamWriter W(Buffer); + W.emitBlob("str", /* ShouldEmitSize */ false); + EXPECT_EQ(StringRef("str\0", 4), Buffer); +} + +TEST(BitstreamWriterTest, emitBlobWithSize) { + SmallString<64> Buffer; + { + BitstreamWriter W(Buffer); + W.emitBlob("str"); + } + SmallString<64> Expected; + { + BitstreamWriter W(Expected); + W.EmitVBR(3, 6); + W.FlushToWord(); + W.Emit('s', 8); + W.Emit('t', 8); + W.Emit('r', 8); + W.Emit(0, 8); + } + EXPECT_EQ(StringRef(Expected), Buffer); +} + +TEST(BitstreamWriterTest, emitBlobEmpty) { + SmallString<64> Buffer; + BitstreamWriter W(Buffer); + W.emitBlob("", /* ShouldEmitSize */ false); + EXPECT_EQ(StringRef(""), Buffer); +} + +TEST(BitstreamWriterTest, emitBlob4ByteAligned) { + SmallString<64> Buffer; + BitstreamWriter W(Buffer); + W.emitBlob("str0", /* ShouldEmitSize */ false); + EXPECT_EQ(StringRef("str0"), Buffer); +} + +} // end namespace diff --git a/llvm/unittests/Bitcode/CMakeLists.txt b/llvm/unittests/Bitcode/CMakeLists.txt index 09cbcdc..4d06f80 100644 --- a/llvm/unittests/Bitcode/CMakeLists.txt +++ b/llvm/unittests/Bitcode/CMakeLists.txt @@ -9,4 +9,5 @@ set(LLVM_LINK_COMPONENTS add_llvm_unittest(BitcodeTests BitReaderTest.cpp BitstreamReaderTest.cpp + BitstreamWriterTest.cpp )