| 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 |