OLD | NEW |
1 //===- BitstreamWriter.h - Low-level bitstream writer interface -*- 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_BITSTREAMWRITER_H | 15 #ifndef LLVM_BITCODE_NACL_NACLBITSTREAMWRITER_H |
16 #define LLVM_BITCODE_BITSTREAMWRITER_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/BitCodes.h" | 20 #include "llvm/Bitcode/NaCl/NaClBitCodes.h" |
21 #include <vector> | 21 #include <vector> |
22 | 22 |
23 namespace llvm { | 23 namespace llvm { |
24 | 24 |
25 class BitstreamWriter { | 25 class NaClBitstreamWriter { |
26 SmallVectorImpl<char> &Out; | 26 SmallVectorImpl<char> &Out; |
27 | 27 |
28 /// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use. | 28 /// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use. |
29 unsigned CurBit; | 29 unsigned CurBit; |
30 | 30 |
31 /// CurValue - The current value. Only bits < CurBit are valid. | 31 /// CurValue - The current value. Only bits < CurBit are valid. |
32 uint32_t CurValue; | 32 uint32_t CurValue; |
33 | 33 |
34 /// CurCodeSize - This is the declared size of code values used for the | 34 /// CurCodeSize - This is the declared size of code values used for the |
35 /// current block, in bits. | 35 /// current block, in bits. |
36 unsigned CurCodeSize; | 36 NaClBitcodeSelectorAbbrev CurCodeSize; |
37 | 37 |
38 /// BlockInfoCurBID - When emitting a BLOCKINFO_BLOCK, this is the currently | 38 /// BlockInfoCurBID - When emitting a BLOCKINFO_BLOCK, this is the currently |
39 /// selected BLOCK ID. | 39 /// selected BLOCK ID. |
40 unsigned BlockInfoCurBID; | 40 unsigned BlockInfoCurBID; |
41 | 41 |
42 /// CurAbbrevs - Abbrevs installed at in this block. | 42 /// CurAbbrevs - Abbrevs installed at in this block. |
43 std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> CurAbbrevs; | 43 std::vector<NaClBitCodeAbbrev*> CurAbbrevs; |
44 | 44 |
45 struct Block { | 45 struct Block { |
46 unsigned PrevCodeSize; | 46 NaClBitcodeSelectorAbbrev PrevCodeSize; |
47 unsigned StartSizeWord; | 47 unsigned StartSizeWord; |
48 std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> PrevAbbrevs; | 48 std::vector<NaClBitCodeAbbrev*> PrevAbbrevs; |
49 Block(unsigned PCS, unsigned SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {} | 49 Block(const NaClBitcodeSelectorAbbrev& PCS, unsigned SSW) |
| 50 : PrevCodeSize(PCS), StartSizeWord(SSW) {} |
50 }; | 51 }; |
51 | 52 |
52 /// BlockScope - This tracks the current blocks that we have entered. | 53 /// BlockScope - This tracks the current blocks that we have entered. |
53 std::vector<Block> BlockScope; | 54 std::vector<Block> BlockScope; |
54 | 55 |
55 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. | 56 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. |
56 /// These describe abbreviations that all blocks of the specified ID inherit. | 57 /// These describe abbreviations that all blocks of the specified ID inherit. |
57 struct BlockInfo { | 58 struct BlockInfo { |
58 unsigned BlockID; | 59 unsigned BlockID; |
59 std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> Abbrevs; | 60 std::vector<NaClBitCodeAbbrev*> Abbrevs; |
60 }; | 61 }; |
61 std::vector<BlockInfo> BlockInfoRecords; | 62 std::vector<BlockInfo> BlockInfoRecords; |
62 | 63 |
| 64 /// AbbrevValues - Wrapper class that allows the bitstream writer to |
| 65 /// prefix a code to the set of values, associated with a record to |
| 66 /// emit, without having to destructively change the contents of |
| 67 /// values. |
| 68 template<typename uintty> |
| 69 struct AbbrevValues { |
| 70 AbbrevValues(uintty Code, const SmallVectorImpl<uintty> &Values) |
| 71 : Code(Code), Values(Values) {} |
| 72 |
| 73 size_t size() const { |
| 74 return Values.size() + 1; |
| 75 } |
| 76 |
| 77 uintty operator[](size_t Index) const { |
| 78 return Index == 0 ? Code : Values[Index-1]; |
| 79 } |
| 80 |
| 81 private: |
| 82 // The code to use (if not DONT_USE_CODE). |
| 83 uintty Code; |
| 84 const SmallVectorImpl<uintty> &Values; |
| 85 }; |
| 86 |
| 87 public: |
63 // BackpatchWord - Backpatch a 32-bit word in the output with the specified | 88 // BackpatchWord - Backpatch a 32-bit word in the output with the specified |
64 // value. | 89 // value. |
65 void BackpatchWord(unsigned ByteNo, unsigned NewWord) { | 90 void BackpatchWord(unsigned ByteNo, unsigned NewWord) { |
66 Out[ByteNo++] = (unsigned char)(NewWord >> 0); | 91 Out[ByteNo++] = (unsigned char)(NewWord >> 0); |
67 Out[ByteNo++] = (unsigned char)(NewWord >> 8); | 92 Out[ByteNo++] = (unsigned char)(NewWord >> 8); |
68 Out[ByteNo++] = (unsigned char)(NewWord >> 16); | 93 Out[ByteNo++] = (unsigned char)(NewWord >> 16); |
69 Out[ByteNo ] = (unsigned char)(NewWord >> 24); | 94 Out[ByteNo ] = (unsigned char)(NewWord >> 24); |
70 } | 95 } |
71 | 96 |
| 97 private: |
72 void WriteByte(unsigned char Value) { | 98 void WriteByte(unsigned char Value) { |
73 Out.push_back(Value); | 99 Out.push_back(Value); |
74 } | 100 } |
75 | 101 |
76 void WriteWord(unsigned Value) { | 102 void WriteWord(unsigned Value) { |
77 unsigned char Bytes[4] = { | 103 unsigned char Bytes[4] = { |
78 (unsigned char)(Value >> 0), | 104 (unsigned char)(Value >> 0), |
79 (unsigned char)(Value >> 8), | 105 (unsigned char)(Value >> 8), |
80 (unsigned char)(Value >> 16), | 106 (unsigned char)(Value >> 16), |
81 (unsigned char)(Value >> 24) }; | 107 (unsigned char)(Value >> 24) }; |
82 Out.append(&Bytes[0], &Bytes[4]); | 108 Out.append(&Bytes[0], &Bytes[4]); |
83 } | 109 } |
84 | 110 |
85 unsigned GetBufferOffset() const { | 111 unsigned GetBufferOffset() const { |
86 return Out.size(); | 112 return Out.size(); |
87 } | 113 } |
88 | 114 |
89 unsigned GetWordIndex() const { | 115 unsigned GetWordIndex() const { |
90 unsigned Offset = GetBufferOffset(); | 116 unsigned Offset = GetBufferOffset(); |
91 assert((Offset & 3) == 0 && "Not 32-bit aligned"); | 117 assert((Offset & 3) == 0 && "Not 32-bit aligned"); |
92 return Offset / 4; | 118 return Offset / 4; |
93 } | 119 } |
94 | 120 |
95 public: | 121 public: |
96 explicit BitstreamWriter(SmallVectorImpl<char> &O) | 122 explicit NaClBitstreamWriter(SmallVectorImpl<char> &O) |
97 : Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {} | 123 : Out(O), CurBit(0), CurValue(0), CurCodeSize() {} |
98 | 124 |
99 ~BitstreamWriter() { | 125 ~NaClBitstreamWriter() { |
100 assert(CurBit == 0 && "Unflushed data remaining"); | 126 assert(CurBit == 0 && "Unflused data remaining"); |
101 assert(BlockScope.empty() && CurAbbrevs.empty() && "Block imbalance"); | 127 assert(BlockScope.empty() && CurAbbrevs.empty() && "Block imbalance"); |
| 128 |
| 129 // Free the BlockInfoRecords. |
| 130 while (!BlockInfoRecords.empty()) { |
| 131 BlockInfo &Info = BlockInfoRecords.back(); |
| 132 // Free blockinfo abbrev info. |
| 133 for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size()); |
| 134 i != e; ++i) |
| 135 Info.Abbrevs[i]->dropRef(); |
| 136 BlockInfoRecords.pop_back(); |
| 137 } |
102 } | 138 } |
103 | 139 |
104 /// \brief Retrieve the current position in the stream, in bits. | 140 /// \brief Retrieve the current position in the stream, in bits. |
105 uint64_t GetCurrentBitNo() const { return GetBufferOffset() * 8 + CurBit; } | 141 uint64_t GetCurrentBitNo() const { return GetBufferOffset() * 8 + CurBit; } |
106 | 142 |
107 //===--------------------------------------------------------------------===// | 143 //===--------------------------------------------------------------------===// |
108 // Basic Primitives for emitting bits to the stream. | 144 // Basic Primitives for emitting bits to the stream. |
109 //===--------------------------------------------------------------------===// | 145 //===--------------------------------------------------------------------===// |
110 | 146 |
111 void Emit(uint32_t Val, unsigned NumBits) { | 147 void Emit(uint32_t Val, unsigned NumBits) { |
(...skipping 27 matching lines...) Expand all Loading... |
139 void FlushToWord() { | 175 void FlushToWord() { |
140 if (CurBit) { | 176 if (CurBit) { |
141 WriteWord(CurValue); | 177 WriteWord(CurValue); |
142 CurBit = 0; | 178 CurBit = 0; |
143 CurValue = 0; | 179 CurValue = 0; |
144 } | 180 } |
145 } | 181 } |
146 | 182 |
147 void EmitVBR(uint32_t Val, unsigned NumBits) { | 183 void EmitVBR(uint32_t Val, unsigned NumBits) { |
148 assert(NumBits <= 32 && "Too many bits to emit!"); | 184 assert(NumBits <= 32 && "Too many bits to emit!"); |
| 185 assert(NumBits > 1 && "Too few bits to emit!"); |
149 uint32_t Threshold = 1U << (NumBits-1); | 186 uint32_t Threshold = 1U << (NumBits-1); |
150 | 187 |
151 // Emit the bits with VBR encoding, NumBits-1 bits at a time. | 188 // Emit the bits with VBR encoding, NumBits-1 bits at a time. |
152 while (Val >= Threshold) { | 189 while (Val >= Threshold) { |
153 Emit((Val & ((1 << (NumBits-1))-1)) | (1 << (NumBits-1)), NumBits); | 190 Emit((Val & ((1 << (NumBits-1))-1)) | (1 << (NumBits-1)), NumBits); |
154 Val >>= NumBits-1; | 191 Val >>= NumBits-1; |
155 } | 192 } |
156 | 193 |
157 Emit(Val, NumBits); | 194 Emit(Val, NumBits); |
158 } | 195 } |
159 | 196 |
160 void EmitVBR64(uint64_t Val, unsigned NumBits) { | 197 void EmitVBR64(uint64_t Val, unsigned NumBits) { |
161 assert(NumBits <= 32 && "Too many bits to emit!"); | 198 assert(NumBits <= 32 && "Too many bits to emit!"); |
| 199 assert(NumBits > 1 && "Too few bits to emit!"); |
162 if ((uint32_t)Val == Val) | 200 if ((uint32_t)Val == Val) |
163 return EmitVBR((uint32_t)Val, NumBits); | 201 return EmitVBR((uint32_t)Val, NumBits); |
164 | 202 |
165 uint32_t Threshold = 1U << (NumBits-1); | 203 uint32_t Threshold = 1U << (NumBits-1); |
166 | 204 |
167 // Emit the bits with VBR encoding, NumBits-1 bits at a time. | 205 // Emit the bits with VBR encoding, NumBits-1 bits at a time. |
168 while (Val >= Threshold) { | 206 while (Val >= Threshold) { |
169 Emit(((uint32_t)Val & ((1 << (NumBits-1))-1)) | | 207 Emit(((uint32_t)Val & ((1 << (NumBits-1))-1)) | |
170 (1 << (NumBits-1)), NumBits); | 208 (1 << (NumBits-1)), NumBits); |
171 Val >>= NumBits-1; | 209 Val >>= NumBits-1; |
172 } | 210 } |
173 | 211 |
174 Emit((uint32_t)Val, NumBits); | 212 Emit((uint32_t)Val, NumBits); |
175 } | 213 } |
176 | 214 |
177 /// EmitCode - Emit the specified code. | 215 /// EmitCode - Emit the specified code. |
178 void EmitCode(unsigned Val) { | 216 void EmitCode(unsigned Val) { |
179 Emit(Val, CurCodeSize); | 217 if (CurCodeSize.IsFixed) |
| 218 Emit(Val, CurCodeSize.NumBits); |
| 219 else |
| 220 EmitVBR(Val, CurCodeSize.NumBits); |
180 } | 221 } |
181 | 222 |
182 //===--------------------------------------------------------------------===// | 223 //===--------------------------------------------------------------------===// |
183 // Block Manipulation | 224 // Block Manipulation |
184 //===--------------------------------------------------------------------===// | 225 //===--------------------------------------------------------------------===// |
185 | 226 |
186 /// getBlockInfo - If there is block info for the specified ID, return it, | 227 /// getBlockInfo - If there is block info for the specified ID, return it, |
187 /// otherwise return null. | 228 /// otherwise return null. |
188 BlockInfo *getBlockInfo(unsigned BlockID) { | 229 BlockInfo *getBlockInfo(unsigned BlockID) { |
189 // Common case, the most recent entry matches BlockID. | 230 // Common case, the most recent entry matches BlockID. |
190 if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID) | 231 if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID) |
191 return &BlockInfoRecords.back(); | 232 return &BlockInfoRecords.back(); |
192 | 233 |
193 for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size()); | 234 for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size()); |
194 i != e; ++i) | 235 i != e; ++i) |
195 if (BlockInfoRecords[i].BlockID == BlockID) | 236 if (BlockInfoRecords[i].BlockID == BlockID) |
196 return &BlockInfoRecords[i]; | 237 return &BlockInfoRecords[i]; |
197 return nullptr; | 238 return 0; |
198 } | 239 } |
199 | 240 |
200 void EnterSubblock(unsigned BlockID, unsigned CodeLen) { | 241 private: |
| 242 // Enter block using CodeLen bits to read the size of the code |
| 243 // selector associated with the block. |
| 244 void EnterSubblock(unsigned BlockID, |
| 245 const NaClBitcodeSelectorAbbrev& CodeLen, |
| 246 BlockInfo *Info) { |
201 // Block header: | 247 // Block header: |
202 // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] | 248 // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] |
203 EmitCode(bitc::ENTER_SUBBLOCK); | 249 EmitCode(naclbitc::ENTER_SUBBLOCK); |
204 EmitVBR(BlockID, bitc::BlockIDWidth); | 250 EmitVBR(BlockID, naclbitc::BlockIDWidth); |
205 EmitVBR(CodeLen, bitc::CodeLenWidth); | 251 assert(CodeLen.IsFixed && "Block codelens must be fixed"); |
| 252 EmitVBR(CodeLen.NumBits, naclbitc::CodeLenWidth); |
206 FlushToWord(); | 253 FlushToWord(); |
207 | 254 |
208 unsigned BlockSizeWordIndex = GetWordIndex(); | 255 unsigned BlockSizeWordIndex = GetWordIndex(); |
209 unsigned OldCodeSize = CurCodeSize; | 256 NaClBitcodeSelectorAbbrev OldCodeSize(CurCodeSize); |
210 | 257 |
211 // Emit a placeholder, which will be replaced when the block is popped. | 258 // Emit a placeholder, which will be replaced when the block is popped. |
212 Emit(0, bitc::BlockSizeWidth); | 259 Emit(0, naclbitc::BlockSizeWidth); |
213 | 260 |
214 CurCodeSize = CodeLen; | 261 CurCodeSize = CodeLen; |
215 | 262 |
216 // Push the outer block's abbrev set onto the stack, start out with an | 263 // Push the outer block's abbrev set onto the stack, start out with an |
217 // empty abbrev set. | 264 // empty abbrev set. |
218 BlockScope.push_back(Block(OldCodeSize, BlockSizeWordIndex)); | 265 BlockScope.push_back(Block(OldCodeSize, BlockSizeWordIndex)); |
219 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); | 266 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); |
220 | 267 |
221 // If there is a blockinfo for this BlockID, add all the predefined abbrevs | 268 // If there is a blockinfo for this BlockID, add all the predefined abbrevs |
222 // to the abbrev list. | 269 // to the abbrev list. |
223 if (BlockInfo *Info = getBlockInfo(BlockID)) { | 270 if (Info) { |
224 CurAbbrevs.insert(CurAbbrevs.end(), Info->Abbrevs.begin(), | 271 for (unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size()); |
225 Info->Abbrevs.end()); | 272 i != e; ++i) { |
| 273 CurAbbrevs.push_back(Info->Abbrevs[i]); |
| 274 Info->Abbrevs[i]->addRef(); |
| 275 } |
226 } | 276 } |
227 } | 277 } |
228 | 278 |
| 279 public: |
| 280 /// \brief Enter block using CodeLen bits to read the size of the code |
| 281 /// selector associated with the block. |
| 282 void EnterSubblock(unsigned BlockID, |
| 283 const NaClBitcodeSelectorAbbrev& CodeLen) { |
| 284 EnterSubblock(BlockID, CodeLen, getBlockInfo(BlockID)); |
| 285 } |
| 286 |
| 287 /// \brief Enter block, using a code length based on the number of |
| 288 /// (global) BlockInfo entries defined for the block. Note: This |
| 289 /// should be used only if the block doesn't define any local abbreviations. |
| 290 void EnterSubblock(unsigned BlockID) { |
| 291 BlockInfo *Info = getBlockInfo(BlockID); |
| 292 size_t NumAbbrevs = Info ? Info->Abbrevs.size() : 0; |
| 293 NaClBitcodeSelectorAbbrev DefaultCodeLen( |
| 294 naclbitc::DEFAULT_MAX_ABBREV+NumAbbrevs); |
| 295 EnterSubblock(BlockID, DefaultCodeLen, Info); |
| 296 } |
| 297 |
| 298 /// \brief Enter block with the given number of abbreviations. |
| 299 void EnterSubblock(unsigned BlockID, unsigned NumAbbrev) { |
| 300 NaClBitcodeSelectorAbbrev CodeLenAbbrev(NumAbbrev); |
| 301 EnterSubblock(BlockID, CodeLenAbbrev); |
| 302 } |
| 303 |
229 void ExitBlock() { | 304 void ExitBlock() { |
230 assert(!BlockScope.empty() && "Block scope imbalance!"); | 305 assert(!BlockScope.empty() && "Block scope imbalance!"); |
| 306 |
| 307 // Delete all abbrevs. |
| 308 for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size()); |
| 309 i != e; ++i) |
| 310 CurAbbrevs[i]->dropRef(); |
| 311 |
231 const Block &B = BlockScope.back(); | 312 const Block &B = BlockScope.back(); |
232 | 313 |
233 // Block tail: | 314 // Block tail: |
234 // [END_BLOCK, <align4bytes>] | 315 // [END_BLOCK, <align4bytes>] |
235 EmitCode(bitc::END_BLOCK); | 316 EmitCode(naclbitc::END_BLOCK); |
236 FlushToWord(); | 317 FlushToWord(); |
237 | 318 |
238 // Compute the size of the block, in words, not counting the size field. | 319 // Compute the size of the block, in words, not counting the size field. |
239 unsigned SizeInWords = GetWordIndex() - B.StartSizeWord - 1; | 320 unsigned SizeInWords = GetWordIndex() - B.StartSizeWord - 1; |
240 unsigned ByteNo = B.StartSizeWord*4; | 321 unsigned ByteNo = B.StartSizeWord*4; |
241 | 322 |
242 // Update the block size field in the header of this sub-block. | 323 // Update the block size field in the header of this sub-block. |
243 BackpatchWord(ByteNo, SizeInWords); | 324 BackpatchWord(ByteNo, SizeInWords); |
244 | 325 |
245 // Restore the inner block's code size and abbrev table. | 326 // Restore the inner block's code size and abbrev table. |
246 CurCodeSize = B.PrevCodeSize; | 327 CurCodeSize = B.PrevCodeSize; |
247 CurAbbrevs = std::move(B.PrevAbbrevs); | 328 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); |
248 BlockScope.pop_back(); | 329 BlockScope.pop_back(); |
249 } | 330 } |
250 | 331 |
251 //===--------------------------------------------------------------------===// | 332 //===--------------------------------------------------------------------===// |
252 // Record Emission | 333 // Record Emission |
253 //===--------------------------------------------------------------------===// | 334 //===--------------------------------------------------------------------===// |
254 | 335 |
255 private: | 336 private: |
256 /// EmitAbbreviatedLiteral - Emit a literal value according to its abbrev | |
257 /// record. This is a no-op, since the abbrev specifies the literal to use. | |
258 template<typename uintty> | |
259 void EmitAbbreviatedLiteral(const BitCodeAbbrevOp &Op, uintty V) { | |
260 assert(Op.isLiteral() && "Not a literal"); | |
261 // If the abbrev specifies the literal value to use, don't emit | |
262 // anything. | |
263 assert(V == Op.getLiteralValue() && | |
264 "Invalid abbrev for record!"); | |
265 } | |
266 | |
267 /// EmitAbbreviatedField - Emit a single scalar field value with the specified | 337 /// EmitAbbreviatedField - Emit a single scalar field value with the specified |
268 /// encoding. | 338 /// encoding. |
269 template<typename uintty> | 339 template<typename uintty> |
270 void EmitAbbreviatedField(const BitCodeAbbrevOp &Op, uintty V) { | 340 void EmitAbbreviatedField(const NaClBitCodeAbbrevOp &Op, uintty V) { |
271 assert(!Op.isLiteral() && "Literals should use EmitAbbreviatedLiteral!"); | |
272 | |
273 // Encode the value as we are commanded. | |
274 switch (Op.getEncoding()) { | 341 switch (Op.getEncoding()) { |
275 default: llvm_unreachable("Unknown encoding!"); | 342 case NaClBitCodeAbbrevOp::Literal: |
276 case BitCodeAbbrevOp::Fixed: | 343 // This is a no-op, since the abbrev specifies the literal to use. |
277 if (Op.getEncodingData()) | 344 assert(V == Op.getValue() && "Invalid abbrev for record!"); |
278 Emit((unsigned)V, (unsigned)Op.getEncodingData()); | |
279 break; | 345 break; |
280 case BitCodeAbbrevOp::VBR: | 346 case NaClBitCodeAbbrevOp::Fixed: |
281 if (Op.getEncodingData()) | 347 if (Op.getValue()) |
282 EmitVBR64(V, (unsigned)Op.getEncodingData()); | 348 Emit((unsigned)V, (unsigned)Op.getValue()); |
283 break; | 349 break; |
284 case BitCodeAbbrevOp::Char6: | 350 case NaClBitCodeAbbrevOp::VBR: |
285 Emit(BitCodeAbbrevOp::EncodeChar6((char)V), 6); | 351 if (Op.getValue()) |
| 352 EmitVBR64(V, (unsigned)Op.getValue()); |
| 353 break; |
| 354 case NaClBitCodeAbbrevOp::Array: |
| 355 report_fatal_error("Not to be used with array abbreviation op!"); |
| 356 case NaClBitCodeAbbrevOp::Char6: |
| 357 Emit(NaClBitCodeAbbrevOp::EncodeChar6((char)V), 6); |
286 break; | 358 break; |
287 } | 359 } |
288 } | 360 } |
289 | 361 |
290 /// EmitRecordWithAbbrevImpl - This is the core implementation of the record | 362 /// EmitRecordWithAbbrevImpl - This is the core implementation of the record |
291 /// emission code. If BlobData is non-null, then it specifies an array of | 363 /// emission code. |
292 /// data that should be emitted as part of the Blob or Array operand that is | |
293 /// known to exist at the end of the record. | |
294 template<typename uintty> | 364 template<typename uintty> |
295 void EmitRecordWithAbbrevImpl(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, | 365 void EmitRecordWithAbbrevImpl(unsigned Abbrev, |
296 StringRef Blob) { | 366 const AbbrevValues<uintty> &Vals) { |
297 const char *BlobData = Blob.data(); | 367 unsigned AbbrevNo = Abbrev-naclbitc::FIRST_APPLICATION_ABBREV; |
298 unsigned BlobLen = (unsigned) Blob.size(); | |
299 unsigned AbbrevNo = Abbrev-bitc::FIRST_APPLICATION_ABBREV; | |
300 assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); | 368 assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); |
301 const BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo].get(); | 369 NaClBitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo]; |
302 | 370 |
303 EmitCode(Abbrev); | 371 EmitCode(Abbrev); |
304 | 372 |
305 unsigned RecordIdx = 0; | 373 unsigned RecordIdx = 0; |
306 for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos()); | 374 for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos()); |
307 i != e; ++i) { | 375 i != e; ++i) { |
308 const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); | 376 const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); |
309 if (Op.isLiteral()) { | 377 if (Op.getEncoding() == NaClBitCodeAbbrevOp::Array) { |
310 assert(RecordIdx < Vals.size() && "Invalid abbrev/record"); | |
311 EmitAbbreviatedLiteral(Op, Vals[RecordIdx]); | |
312 ++RecordIdx; | |
313 } else if (Op.getEncoding() == BitCodeAbbrevOp::Array) { | |
314 // Array case. | 378 // Array case. |
315 assert(i+2 == e && "array op not second to last?"); | 379 assert(i+2 == e && "array op not second to last?"); |
316 const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); | 380 const NaClBitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); |
317 | |
318 // If this record has blob data, emit it, otherwise we must have record | |
319 // entries to encode this way. | |
320 if (BlobData) { | |
321 assert(RecordIdx == Vals.size() && | |
322 "Blob data and record entries specified for array!"); | |
323 // Emit a vbr6 to indicate the number of elements present. | |
324 EmitVBR(static_cast<uint32_t>(BlobLen), 6); | |
325 | |
326 // Emit each field. | |
327 for (unsigned i = 0; i != BlobLen; ++i) | |
328 EmitAbbreviatedField(EltEnc, (unsigned char)BlobData[i]); | |
329 | |
330 // Know that blob data is consumed for assertion below. | |
331 BlobData = nullptr; | |
332 } else { | |
333 // Emit a vbr6 to indicate the number of elements present. | |
334 EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6); | |
335 | |
336 // Emit each field. | |
337 for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx) | |
338 EmitAbbreviatedField(EltEnc, Vals[RecordIdx]); | |
339 } | |
340 } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) { | |
341 // If this record has blob data, emit it, otherwise we must have record | |
342 // entries to encode this way. | |
343 | 381 |
344 // Emit a vbr6 to indicate the number of elements present. | 382 // Emit a vbr6 to indicate the number of elements present. |
345 if (BlobData) { | 383 EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6); |
346 EmitVBR(static_cast<uint32_t>(BlobLen), 6); | |
347 assert(RecordIdx == Vals.size() && | |
348 "Blob data and record entries specified for blob operand!"); | |
349 } else { | |
350 EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6); | |
351 } | |
352 | 384 |
353 // Flush to a 32-bit alignment boundary. | 385 // Emit each field. |
354 FlushToWord(); | 386 for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx) |
355 | 387 EmitAbbreviatedField(EltEnc, Vals[RecordIdx]); |
356 // Emit each field as a literal byte. | 388 } else { |
357 if (BlobData) { | |
358 for (unsigned i = 0; i != BlobLen; ++i) | |
359 WriteByte((unsigned char)BlobData[i]); | |
360 | |
361 // Know that blob data is consumed for assertion below. | |
362 BlobData = nullptr; | |
363 } else { | |
364 for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx) { | |
365 assert(isUInt<8>(Vals[RecordIdx]) && | |
366 "Value too large to emit as blob"); | |
367 WriteByte((unsigned char)Vals[RecordIdx]); | |
368 } | |
369 } | |
370 | |
371 // Align end to 32-bits. | |
372 while (GetBufferOffset() & 3) | |
373 WriteByte(0); | |
374 } else { // Single scalar field. | |
375 assert(RecordIdx < Vals.size() && "Invalid abbrev/record"); | 389 assert(RecordIdx < Vals.size() && "Invalid abbrev/record"); |
376 EmitAbbreviatedField(Op, Vals[RecordIdx]); | 390 EmitAbbreviatedField(Op, Vals[RecordIdx]); |
377 ++RecordIdx; | 391 ++RecordIdx; |
378 } | 392 } |
379 } | 393 } |
380 assert(RecordIdx == Vals.size() && "Not all record operands emitted!"); | 394 assert(RecordIdx == Vals.size() && "Not all record operands emitted!"); |
381 assert(BlobData == nullptr && | |
382 "Blob data specified for record that doesn't use it!"); | |
383 } | 395 } |
384 | 396 |
385 public: | 397 public: |
386 | 398 |
| 399 /// Returns true if the given abbreviation index corresponds to a user-defined |
| 400 /// abbreviation. |
| 401 bool isUserRecordAbbreviation(unsigned Abbrev) const { |
| 402 return Abbrev >= naclbitc::FIRST_APPLICATION_ABBREV |
| 403 && Abbrev < CurAbbrevs.size(); |
| 404 } |
| 405 |
387 /// EmitRecord - Emit the specified record to the stream, using an abbrev if | 406 /// EmitRecord - Emit the specified record to the stream, using an abbrev if |
388 /// we have one to compress the output. | 407 /// we have one to compress the output. |
389 template<typename uintty> | 408 template<typename uintty> |
390 void EmitRecord(unsigned Code, SmallVectorImpl<uintty> &Vals, | 409 void EmitRecord(unsigned Code, const SmallVectorImpl<uintty> &Vals, |
391 unsigned Abbrev = 0) { | 410 unsigned Abbrev = 0) { |
392 if (!Abbrev) { | 411 if (!Abbrev) { |
393 // If we don't have an abbrev to use, emit this in its fully unabbreviated | 412 // If we don't have an abbrev to use, emit this in its fully unabbreviated |
394 // form. | 413 // form. |
395 EmitCode(bitc::UNABBREV_RECORD); | 414 EmitCode(naclbitc::UNABBREV_RECORD); |
396 EmitVBR(Code, 6); | 415 EmitVBR(Code, 6); |
397 EmitVBR(static_cast<uint32_t>(Vals.size()), 6); | 416 EmitVBR(static_cast<uint32_t>(Vals.size()), 6); |
398 for (unsigned i = 0, e = static_cast<unsigned>(Vals.size()); i != e; ++i) | 417 for (unsigned i = 0, e = static_cast<unsigned>(Vals.size()); i != e; ++i) |
399 EmitVBR64(Vals[i], 6); | 418 EmitVBR64(Vals[i], 6); |
400 return; | 419 return; |
401 } | 420 } |
402 | 421 |
403 // Insert the code into Vals to treat it uniformly. | 422 // combine code and values, and then emit. |
404 Vals.insert(Vals.begin(), Code); | 423 AbbrevValues<uintty> AbbrevVals(Code, Vals); |
405 | 424 EmitRecordWithAbbrevImpl(Abbrev, AbbrevVals); |
406 EmitRecordWithAbbrev(Abbrev, Vals); | |
407 } | |
408 | |
409 /// EmitRecordWithAbbrev - Emit a record with the specified abbreviation. | |
410 /// Unlike EmitRecord, the code for the record should be included in Vals as | |
411 /// the first entry. | |
412 template<typename uintty> | |
413 void EmitRecordWithAbbrev(unsigned Abbrev, SmallVectorImpl<uintty> &Vals) { | |
414 EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef()); | |
415 } | |
416 | |
417 /// EmitRecordWithBlob - Emit the specified record to the stream, using an | |
418 /// abbrev that includes a blob at the end. The blob data to emit is | |
419 /// specified by the pointer and length specified at the end. In contrast to | |
420 /// EmitRecord, this routine expects that the first entry in Vals is the code | |
421 /// of the record. | |
422 template<typename uintty> | |
423 void EmitRecordWithBlob(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, | |
424 StringRef Blob) { | |
425 EmitRecordWithAbbrevImpl(Abbrev, Vals, Blob); | |
426 } | |
427 template<typename uintty> | |
428 void EmitRecordWithBlob(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, | |
429 const char *BlobData, unsigned BlobLen) { | |
430 return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(BlobData, BlobLen)); | |
431 } | |
432 | |
433 /// EmitRecordWithArray - Just like EmitRecordWithBlob, works with records | |
434 /// that end with an array. | |
435 template<typename uintty> | |
436 void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, | |
437 StringRef Array) { | |
438 EmitRecordWithAbbrevImpl(Abbrev, Vals, Array); | |
439 } | |
440 template<typename uintty> | |
441 void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, | |
442 const char *ArrayData, unsigned ArrayLen) { | |
443 return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(ArrayData, | |
444 ArrayLen)); | |
445 } | 425 } |
446 | 426 |
447 //===--------------------------------------------------------------------===// | 427 //===--------------------------------------------------------------------===// |
448 // Abbrev Emission | 428 // Abbrev Emission |
449 //===--------------------------------------------------------------------===// | 429 //===--------------------------------------------------------------------===// |
450 | 430 |
451 private: | 431 private: |
452 // Emit the abbreviation as a DEFINE_ABBREV record. | 432 // Emit the abbreviation as a DEFINE_ABBREV record. |
453 void EncodeAbbrev(BitCodeAbbrev *Abbv) { | 433 void EncodeAbbrev(NaClBitCodeAbbrev *Abbv) { |
454 EmitCode(bitc::DEFINE_ABBREV); | 434 EmitCode(naclbitc::DEFINE_ABBREV); |
455 EmitVBR(Abbv->getNumOperandInfos(), 5); | 435 EmitVBR(Abbv->getNumOperandInfos(), 5); |
456 for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos()); | 436 for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos()); |
457 i != e; ++i) { | 437 i != e; ++i) { |
458 const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); | 438 const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); |
459 Emit(Op.isLiteral(), 1); | 439 bool IsLiteral = Op.isLiteral(); |
460 if (Op.isLiteral()) { | 440 Emit(IsLiteral, 1); |
461 EmitVBR64(Op.getLiteralValue(), 8); | 441 if (IsLiteral) { |
| 442 EmitVBR64(Op.getValue(), 8); |
462 } else { | 443 } else { |
463 Emit(Op.getEncoding(), 3); | 444 Emit(Op.getEncoding(), 3); |
464 if (Op.hasEncodingData()) | 445 if (Op.hasValue()) |
465 EmitVBR64(Op.getEncodingData(), 5); | 446 EmitVBR64(Op.getValue(), 5); |
466 } | 447 } |
467 } | 448 } |
468 } | 449 } |
469 public: | 450 public: |
470 | 451 |
471 /// EmitAbbrev - This emits an abbreviation to the stream. Note that this | 452 /// EmitAbbrev - This emits an abbreviation to the stream. Note that this |
472 /// method takes ownership of the specified abbrev. | 453 /// method takes ownership of the specified abbrev. |
473 unsigned EmitAbbrev(BitCodeAbbrev *Abbv) { | 454 unsigned EmitAbbrev(NaClBitCodeAbbrev *Abbv) { |
| 455 assert(Abbv->isValid() && "Can't emit invalid abbreviation!"); |
474 // Emit the abbreviation as a record. | 456 // Emit the abbreviation as a record. |
475 EncodeAbbrev(Abbv); | 457 EncodeAbbrev(Abbv); |
476 CurAbbrevs.push_back(Abbv); | 458 CurAbbrevs.push_back(Abbv); |
477 return static_cast<unsigned>(CurAbbrevs.size())-1 + | 459 return static_cast<unsigned>(CurAbbrevs.size())-1 + |
478 bitc::FIRST_APPLICATION_ABBREV; | 460 naclbitc::FIRST_APPLICATION_ABBREV; |
479 } | 461 } |
480 | 462 |
481 //===--------------------------------------------------------------------===// | 463 //===--------------------------------------------------------------------===// |
482 // BlockInfo Block Emission | 464 // BlockInfo Block Emission |
483 //===--------------------------------------------------------------------===// | 465 //===--------------------------------------------------------------------===// |
484 | 466 |
485 /// EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK. | 467 /// EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK. |
486 void EnterBlockInfoBlock(unsigned CodeWidth) { | 468 void EnterBlockInfoBlock() { |
487 EnterSubblock(bitc::BLOCKINFO_BLOCK_ID, CodeWidth); | 469 EnterSubblock(naclbitc::BLOCKINFO_BLOCK_ID); |
488 BlockInfoCurBID = ~0U; | 470 BlockInfoCurBID = ~0U; |
489 } | 471 } |
490 private: | 472 private: |
491 /// SwitchToBlockID - If we aren't already talking about the specified block | 473 /// SwitchToBlockID - If we aren't already talking about the specified block |
492 /// ID, emit a BLOCKINFO_CODE_SETBID record. | 474 /// ID, emit a BLOCKINFO_CODE_SETBID record. |
493 void SwitchToBlockID(unsigned BlockID) { | 475 void SwitchToBlockID(unsigned BlockID) { |
494 if (BlockInfoCurBID == BlockID) return; | 476 if (BlockInfoCurBID == BlockID) return; |
495 SmallVector<unsigned, 2> V; | 477 SmallVector<unsigned, 2> V; |
496 V.push_back(BlockID); | 478 V.push_back(BlockID); |
497 EmitRecord(bitc::BLOCKINFO_CODE_SETBID, V); | 479 EmitRecord(naclbitc::BLOCKINFO_CODE_SETBID, V); |
498 BlockInfoCurBID = BlockID; | 480 BlockInfoCurBID = BlockID; |
499 } | 481 } |
500 | 482 |
501 BlockInfo &getOrCreateBlockInfo(unsigned BlockID) { | 483 BlockInfo &getOrCreateBlockInfo(unsigned BlockID) { |
502 if (BlockInfo *BI = getBlockInfo(BlockID)) | 484 if (BlockInfo *BI = getBlockInfo(BlockID)) |
503 return *BI; | 485 return *BI; |
504 | 486 |
505 // Otherwise, add a new record. | 487 // Otherwise, add a new record. |
506 BlockInfoRecords.push_back(BlockInfo()); | 488 BlockInfoRecords.push_back(BlockInfo()); |
507 BlockInfoRecords.back().BlockID = BlockID; | 489 BlockInfoRecords.back().BlockID = BlockID; |
508 return BlockInfoRecords.back(); | 490 return BlockInfoRecords.back(); |
509 } | 491 } |
510 | 492 |
511 public: | 493 public: |
512 | 494 |
513 /// EmitBlockInfoAbbrev - Emit a DEFINE_ABBREV record for the specified | 495 /// EmitBlockInfoAbbrev - Emit a DEFINE_ABBREV record for the specified |
514 /// BlockID. | 496 /// BlockID. |
515 unsigned EmitBlockInfoAbbrev(unsigned BlockID, BitCodeAbbrev *Abbv) { | 497 unsigned EmitBlockInfoAbbrev(unsigned BlockID, NaClBitCodeAbbrev *Abbv) { |
516 SwitchToBlockID(BlockID); | 498 SwitchToBlockID(BlockID); |
517 EncodeAbbrev(Abbv); | 499 EncodeAbbrev(Abbv); |
518 | 500 |
519 // Add the abbrev to the specified block record. | 501 // Add the abbrev to the specified block record. |
520 BlockInfo &Info = getOrCreateBlockInfo(BlockID); | 502 BlockInfo &Info = getOrCreateBlockInfo(BlockID); |
521 Info.Abbrevs.push_back(Abbv); | 503 Info.Abbrevs.push_back(Abbv); |
522 | 504 |
523 return Info.Abbrevs.size()-1+bitc::FIRST_APPLICATION_ABBREV; | 505 return Info.Abbrevs.size()-1+naclbitc::FIRST_APPLICATION_ABBREV; |
524 } | 506 } |
525 }; | 507 }; |
526 | 508 |
527 | 509 |
528 } // End llvm namespace | 510 } // End llvm namespace |
529 | 511 |
530 #endif | 512 #endif |
OLD | NEW |