| OLD | NEW |
| 1 //===- NaClBitstreamWriter.h - NaCl bitstream writer ------------*- C++ -*-===// | 1 //===- NaClBitstreamWriter.h - NaCl bitstream writer ------------*- C++ -*-===// |
| 2 // | 2 // |
| 3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This header defines the BitstreamWriter class. This class can be used to | 10 // This header defines the BitstreamWriter class. This class can be used to |
| 11 // write an arbitrary bitstream, regardless of its contents. | 11 // write an arbitrary bitstream, regardless of its contents. |
| 12 // | 12 // |
| 13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
| 14 | 14 |
| 15 #ifndef LLVM_BITCODE_NACL_NACLBITSTREAMWRITER_H | 15 #ifndef LLVM_BITCODE_NACL_NACLBITSTREAMWRITER_H |
| 16 #define LLVM_BITCODE_NACL_NACLBITSTREAMWRITER_H | 16 #define LLVM_BITCODE_NACL_NACLBITSTREAMWRITER_H |
| 17 | 17 |
| 18 #include "llvm/ADT/SmallVector.h" | 18 #include "llvm/ADT/SmallVector.h" |
| 19 #include "llvm/ADT/StringRef.h" | 19 #include "llvm/ADT/StringRef.h" |
| 20 #include "llvm/Bitcode/NaCl/NaClBitCodes.h" | 20 #include "llvm/Bitcode/NaCl/NaClBitCodes.h" |
| 21 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" |
| 21 #include <vector> | 22 #include <vector> |
| 22 | 23 |
| 23 namespace llvm { | 24 namespace llvm { |
| 24 | 25 |
| 25 class NaClBitstreamWriter { | 26 class NaClBitstreamWriter { |
| 26 SmallVectorImpl<char> &Out; | 27 SmallVectorImpl<char> &Out; |
| 27 | 28 |
| 28 /// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use. | 29 /// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use. |
| 29 unsigned CurBit; | 30 unsigned CurBit; |
| 30 | 31 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 54 std::vector<Block> BlockScope; | 55 std::vector<Block> BlockScope; |
| 55 | 56 |
| 56 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. | 57 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. |
| 57 /// These describe abbreviations that all blocks of the specified ID inherit. | 58 /// These describe abbreviations that all blocks of the specified ID inherit. |
| 58 struct BlockInfo { | 59 struct BlockInfo { |
| 59 unsigned BlockID; | 60 unsigned BlockID; |
| 60 std::vector<NaClBitCodeAbbrev*> Abbrevs; | 61 std::vector<NaClBitCodeAbbrev*> Abbrevs; |
| 61 }; | 62 }; |
| 62 std::vector<BlockInfo> BlockInfoRecords; | 63 std::vector<BlockInfo> BlockInfoRecords; |
| 63 | 64 |
| 65 // True if filler should be added to byte align records. |
| 66 bool AlignBitcodeRecords = false; |
| 67 |
| 64 /// AbbrevValues - Wrapper class that allows the bitstream writer to | 68 /// AbbrevValues - Wrapper class that allows the bitstream writer to |
| 65 /// prefix a code to the set of values, associated with a record to | 69 /// prefix a code to the set of values, associated with a record to |
| 66 /// emit, without having to destructively change the contents of | 70 /// emit, without having to destructively change the contents of |
| 67 /// values. | 71 /// values. |
| 68 template<typename uintty> | 72 template<typename uintty> |
| 69 struct AbbrevValues { | 73 struct AbbrevValues { |
| 70 AbbrevValues(uintty Code, const SmallVectorImpl<uintty> &Values) | 74 AbbrevValues(uintty Code, const SmallVectorImpl<uintty> &Values) |
| 71 : Code(Code), Values(Values) {} | 75 : Code(Code), Values(Values) {} |
| 72 | 76 |
| 73 size_t size() const { | 77 size_t size() const { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 while (!BlockInfoRecords.empty()) { | 134 while (!BlockInfoRecords.empty()) { |
| 131 BlockInfo &Info = BlockInfoRecords.back(); | 135 BlockInfo &Info = BlockInfoRecords.back(); |
| 132 // Free blockinfo abbrev info. | 136 // Free blockinfo abbrev info. |
| 133 for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size()); | 137 for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size()); |
| 134 i != e; ++i) | 138 i != e; ++i) |
| 135 Info.Abbrevs[i]->dropRef(); | 139 Info.Abbrevs[i]->dropRef(); |
| 136 BlockInfoRecords.pop_back(); | 140 BlockInfoRecords.pop_back(); |
| 137 } | 141 } |
| 138 } | 142 } |
| 139 | 143 |
| 144 void initFromHeader(const NaClBitcodeHeader &Header) { |
| 145 AlignBitcodeRecords = Header.getAlignBitcodeRecords(); |
| 146 } |
| 147 |
| 140 /// \brief Retrieve the current position in the stream, in bits. | 148 /// \brief Retrieve the current position in the stream, in bits. |
| 141 uint64_t GetCurrentBitNo() const { return GetBufferOffset() * 8 + CurBit; } | 149 uint64_t GetCurrentBitNo() const { return GetBufferOffset() * 8 + CurBit; } |
| 142 | 150 |
| 143 //===--------------------------------------------------------------------===// | 151 //===--------------------------------------------------------------------===// |
| 144 // Basic Primitives for emitting bits to the stream. | 152 // Basic Primitives for emitting bits to the stream. |
| 145 //===--------------------------------------------------------------------===// | 153 //===--------------------------------------------------------------------===// |
| 146 | 154 |
| 147 void Emit(uint32_t Val, unsigned NumBits) { | 155 void Emit(uint32_t Val, unsigned NumBits) { |
| 148 assert(NumBits && NumBits <= 32 && "Invalid value size!"); | 156 assert(NumBits && NumBits <= 32 && "Invalid value size!"); |
| 149 assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!"); | 157 assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!"); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 165 | 173 |
| 166 void Emit64(uint64_t Val, unsigned NumBits) { | 174 void Emit64(uint64_t Val, unsigned NumBits) { |
| 167 if (NumBits <= 32) | 175 if (NumBits <= 32) |
| 168 Emit((uint32_t)Val, NumBits); | 176 Emit((uint32_t)Val, NumBits); |
| 169 else { | 177 else { |
| 170 Emit((uint32_t)Val, 32); | 178 Emit((uint32_t)Val, 32); |
| 171 Emit((uint32_t)(Val >> 32), NumBits-32); | 179 Emit((uint32_t)(Val >> 32), NumBits-32); |
| 172 } | 180 } |
| 173 } | 181 } |
| 174 | 182 |
| 183 void flushToByte() { |
| 184 unsigned BitsToFlush = (32 - CurBit) % CHAR_BIT; |
| 185 if (BitsToFlush) |
| 186 Emit(0, BitsToFlush); |
| 187 } |
| 188 |
| 189 void flushToByteIfAligned() { |
| 190 if (AlignBitcodeRecords) |
| 191 flushToByte(); |
| 192 } |
| 193 |
| 175 void FlushToWord() { | 194 void FlushToWord() { |
| 176 if (CurBit) { | 195 if (CurBit) { |
| 177 WriteWord(CurValue); | 196 WriteWord(CurValue); |
| 178 CurBit = 0; | 197 CurBit = 0; |
| 179 CurValue = 0; | 198 CurValue = 0; |
| 180 } | 199 } |
| 181 } | 200 } |
| 182 | 201 |
| 183 void EmitVBR(uint32_t Val, unsigned NumBits) { | 202 void EmitVBR(uint32_t Val, unsigned NumBits) { |
| 184 assert(NumBits <= 32 && "Too many bits to emit!"); | 203 assert(NumBits <= 32 && "Too many bits to emit!"); |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 void EmitRecord(unsigned Code, const SmallVectorImpl<uintty> &Vals, | 428 void EmitRecord(unsigned Code, const SmallVectorImpl<uintty> &Vals, |
| 410 unsigned Abbrev = 0) { | 429 unsigned Abbrev = 0) { |
| 411 if (!Abbrev) { | 430 if (!Abbrev) { |
| 412 // If we don't have an abbrev to use, emit this in its fully unabbreviated | 431 // If we don't have an abbrev to use, emit this in its fully unabbreviated |
| 413 // form. | 432 // form. |
| 414 EmitCode(naclbitc::UNABBREV_RECORD); | 433 EmitCode(naclbitc::UNABBREV_RECORD); |
| 415 EmitVBR(Code, 6); | 434 EmitVBR(Code, 6); |
| 416 EmitVBR(static_cast<uint32_t>(Vals.size()), 6); | 435 EmitVBR(static_cast<uint32_t>(Vals.size()), 6); |
| 417 for (unsigned i = 0, e = static_cast<unsigned>(Vals.size()); i != e; ++i) | 436 for (unsigned i = 0, e = static_cast<unsigned>(Vals.size()); i != e; ++i) |
| 418 EmitVBR64(Vals[i], 6); | 437 EmitVBR64(Vals[i], 6); |
| 438 flushToByteIfAligned(); |
| 419 return; | 439 return; |
| 420 } | 440 } |
| 421 | 441 |
| 422 // combine code and values, and then emit. | 442 // combine code and values, and then emit. |
| 423 AbbrevValues<uintty> AbbrevVals(Code, Vals); | 443 AbbrevValues<uintty> AbbrevVals(Code, Vals); |
| 424 EmitRecordWithAbbrevImpl(Abbrev, AbbrevVals); | 444 EmitRecordWithAbbrevImpl(Abbrev, AbbrevVals); |
| 445 flushToByteIfAligned(); |
| 425 } | 446 } |
| 426 | 447 |
| 427 //===--------------------------------------------------------------------===// | 448 //===--------------------------------------------------------------------===// |
| 428 // Abbrev Emission | 449 // Abbrev Emission |
| 429 //===--------------------------------------------------------------------===// | 450 //===--------------------------------------------------------------------===// |
| 430 | 451 |
| 431 private: | 452 private: |
| 432 // Emit the abbreviation as a DEFINE_ABBREV record. | 453 // Emit the abbreviation as a DEFINE_ABBREV record. |
| 433 void EncodeAbbrev(NaClBitCodeAbbrev *Abbv) { | 454 void EncodeAbbrev(NaClBitCodeAbbrev *Abbv) { |
| 434 EmitCode(naclbitc::DEFINE_ABBREV); | 455 EmitCode(naclbitc::DEFINE_ABBREV); |
| 435 EmitVBR(Abbv->getNumOperandInfos(), 5); | 456 EmitVBR(Abbv->getNumOperandInfos(), 5); |
| 436 for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos()); | 457 for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos()); |
| 437 i != e; ++i) { | 458 i != e; ++i) { |
| 438 const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); | 459 const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); |
| 439 bool IsLiteral = Op.isLiteral(); | 460 bool IsLiteral = Op.isLiteral(); |
| 440 Emit(IsLiteral, 1); | 461 Emit(IsLiteral, 1); |
| 441 if (IsLiteral) { | 462 if (IsLiteral) { |
| 442 EmitVBR64(Op.getValue(), 8); | 463 EmitVBR64(Op.getValue(), 8); |
| 443 } else { | 464 } else { |
| 444 Emit(Op.getEncoding(), 3); | 465 Emit(Op.getEncoding(), 3); |
| 445 if (Op.hasValue()) | 466 if (Op.hasValue()) |
| 446 EmitVBR64(Op.getValue(), 5); | 467 EmitVBR64(Op.getValue(), 5); |
| 447 } | 468 } |
| 448 } | 469 } |
| 470 flushToByteIfAligned(); |
| 449 } | 471 } |
| 450 public: | 472 public: |
| 451 | 473 |
| 452 /// EmitAbbrev - This emits an abbreviation to the stream. Note that this | 474 /// EmitAbbrev - This emits an abbreviation to the stream. Note that this |
| 453 /// method takes ownership of the specified abbrev. | 475 /// method takes ownership of the specified abbrev. |
| 454 unsigned EmitAbbrev(NaClBitCodeAbbrev *Abbv) { | 476 unsigned EmitAbbrev(NaClBitCodeAbbrev *Abbv) { |
| 455 assert(Abbv->isValid() && "Can't emit invalid abbreviation!"); | 477 assert(Abbv->isValid() && "Can't emit invalid abbreviation!"); |
| 456 // Emit the abbreviation as a record. | 478 // Emit the abbreviation as a record. |
| 457 EncodeAbbrev(Abbv); | 479 EncodeAbbrev(Abbv); |
| 458 CurAbbrevs.push_back(Abbv); | 480 CurAbbrevs.push_back(Abbv); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 Info.Abbrevs.push_back(Abbv); | 525 Info.Abbrevs.push_back(Abbv); |
| 504 | 526 |
| 505 return Info.Abbrevs.size()-1+naclbitc::FIRST_APPLICATION_ABBREV; | 527 return Info.Abbrevs.size()-1+naclbitc::FIRST_APPLICATION_ABBREV; |
| 506 } | 528 } |
| 507 }; | 529 }; |
| 508 | 530 |
| 509 | 531 |
| 510 } // End llvm namespace | 532 } // End llvm namespace |
| 511 | 533 |
| 512 #endif | 534 #endif |
| OLD | NEW |