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 |