Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h

Issue 1146203003: Fix abbreviation handling in munged bitcode writer. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Fix nits. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeWriter.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
(...skipping 26 matching lines...) Expand all
37 NaClBitcodeSelectorAbbrev CurCodeSize; 37 NaClBitcodeSelectorAbbrev CurCodeSize;
38 38
39 /// BlockInfoCurBID - When emitting a BLOCKINFO_BLOCK, this is the currently 39 /// BlockInfoCurBID - When emitting a BLOCKINFO_BLOCK, this is the currently
40 /// selected BLOCK ID. 40 /// selected BLOCK ID.
41 unsigned BlockInfoCurBID; 41 unsigned BlockInfoCurBID;
42 42
43 /// CurAbbrevs - Abbrevs installed at in this block. 43 /// CurAbbrevs - Abbrevs installed at in this block.
44 std::vector<NaClBitCodeAbbrev*> CurAbbrevs; 44 std::vector<NaClBitCodeAbbrev*> CurAbbrevs;
45 45
46 struct Block { 46 struct Block {
47 NaClBitcodeSelectorAbbrev PrevCodeSize; 47 const NaClBitcodeSelectorAbbrev PrevCodeSize;
48 unsigned StartSizeWord; 48 const unsigned StartSizeWord;
49 std::vector<NaClBitCodeAbbrev*> PrevAbbrevs; 49 std::vector<NaClBitCodeAbbrev*> PrevAbbrevs;
50 Block(const NaClBitcodeSelectorAbbrev& PCS, unsigned SSW) 50 const unsigned AbbreviationIndexLimit;
51 : PrevCodeSize(PCS), StartSizeWord(SSW) {} 51 Block(const NaClBitcodeSelectorAbbrev& PCS, unsigned SSW,
52 unsigned AbbreviationIndexLimit)
53 : PrevCodeSize(PCS), StartSizeWord(SSW),
54 AbbreviationIndexLimit(AbbreviationIndexLimit) {}
52 }; 55 };
53 56
54 /// BlockScope - This tracks the current blocks that we have entered. 57 /// BlockScope - This tracks the current blocks that we have entered.
55 std::vector<Block> BlockScope; 58 std::vector<Block> BlockScope;
56 59
57 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. 60 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks.
58 /// These describe abbreviations that all blocks of the specified ID inherit. 61 /// These describe abbreviations that all blocks of the specified ID inherit.
59 struct BlockInfo { 62 struct BlockInfo {
60 unsigned BlockID; 63 unsigned BlockID;
61 std::vector<NaClBitCodeAbbrev*> Abbrevs; 64 std::vector<NaClBitCodeAbbrev*> Abbrevs;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 /// \brief Returns the maximum abbreviation index allowed for the 154 /// \brief Returns the maximum abbreviation index allowed for the
152 /// current block. 155 /// current block.
153 size_t getMaxCurAbbrevIndex() const { 156 size_t getMaxCurAbbrevIndex() const {
154 return CurAbbrevs.size() + naclbitc::DEFAULT_MAX_ABBREV; 157 return CurAbbrevs.size() + naclbitc::DEFAULT_MAX_ABBREV;
155 } 158 }
156 159
157 //===--------------------------------------------------------------------===// 160 //===--------------------------------------------------------------------===//
158 // Basic Primitives for emitting bits to the stream. 161 // Basic Primitives for emitting bits to the stream.
159 //===--------------------------------------------------------------------===// 162 //===--------------------------------------------------------------------===//
160 163
164 // Max Number of bits that can be written using Emit.
165 static const unsigned MaxEmitNumBits = 32;
166
161 void Emit(uint32_t Val, unsigned NumBits) { 167 void Emit(uint32_t Val, unsigned NumBits) {
162 assert(NumBits && NumBits <= 32 && "Invalid value size!"); 168 assert(NumBits && NumBits <= MaxEmitNumBits && "Invalid value size!");
163 assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!"); 169 assert((Val &
170 ~(~0U >> (MaxEmitNumBits-NumBits))) == 0 && "High bits set!");
164 CurValue |= Val << CurBit; 171 CurValue |= Val << CurBit;
165 if (CurBit + NumBits < 32) { 172 if (CurBit + NumBits < MaxEmitNumBits) {
166 CurBit += NumBits; 173 CurBit += NumBits;
167 return; 174 return;
168 } 175 }
169 176
170 // Add the current word. 177 // Add the current word.
171 WriteWord(CurValue); 178 WriteWord(CurValue);
172 179
173 if (CurBit) 180 if (CurBit)
174 CurValue = Val >> (32-CurBit); 181 CurValue = Val >> (MaxEmitNumBits-CurBit);
175 else 182 else
176 CurValue = 0; 183 CurValue = 0;
177 CurBit = (CurBit+NumBits) & 31; 184 CurBit = (CurBit+NumBits) & (MaxEmitNumBits-1);
178 } 185 }
179 186
180 void Emit64(uint64_t Val, unsigned NumBits) { 187 void Emit64(uint64_t Val, unsigned NumBits) {
181 if (NumBits <= 32) 188 while (NumBits > MaxEmitNumBits) {
182 Emit((uint32_t)Val, NumBits); 189 Emit((uint32_t)Val, MaxEmitNumBits);
183 else { 190 Val >>= MaxEmitNumBits;
184 Emit((uint32_t)Val, 32); 191 NumBits -= MaxEmitNumBits;
185 Emit((uint32_t)(Val >> 32), NumBits-32);
186 } 192 }
193 Emit((uint32_t)Val, NumBits);
187 } 194 }
188 195
189 void flushToByte() { 196 void flushToByte() {
190 unsigned BitsToFlush = (32 - CurBit) % CHAR_BIT; 197 unsigned BitsToFlush = (32 - CurBit) % CHAR_BIT;
191 if (BitsToFlush) 198 if (BitsToFlush)
192 Emit(0, BitsToFlush); 199 Emit(0, BitsToFlush);
193 } 200 }
194 201
195 void flushToByteIfAligned() { 202 void flushToByteIfAligned() {
196 if (AlignBitcodeRecords) 203 if (AlignBitcodeRecords)
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 unsigned BlockSizeWordIndex = GetWordIndex(); 287 unsigned BlockSizeWordIndex = GetWordIndex();
281 NaClBitcodeSelectorAbbrev OldCodeSize(CurCodeSize); 288 NaClBitcodeSelectorAbbrev OldCodeSize(CurCodeSize);
282 289
283 // Emit a placeholder, which will be replaced when the block is popped. 290 // Emit a placeholder, which will be replaced when the block is popped.
284 Emit(0, naclbitc::BlockSizeWidth); 291 Emit(0, naclbitc::BlockSizeWidth);
285 292
286 CurCodeSize = CodeLen; 293 CurCodeSize = CodeLen;
287 294
288 // Push the outer block's abbrev set onto the stack, start out with an 295 // Push the outer block's abbrev set onto the stack, start out with an
289 // empty abbrev set. 296 // empty abbrev set.
290 BlockScope.push_back(Block(OldCodeSize, BlockSizeWordIndex)); 297 BlockScope.push_back(Block(OldCodeSize, BlockSizeWordIndex,
298 1 << CodeLen.NumBits));
291 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); 299 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
292 300
293 // If there is a blockinfo for this BlockID, add all the predefined abbrevs 301 // If there is a blockinfo for this BlockID, add all the predefined abbrevs
294 // to the abbrev list. 302 // to the abbrev list.
295 if (Info) { 303 if (Info) {
296 for (unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size()); 304 for (unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size());
297 i != e; ++i) { 305 i != e; ++i) {
298 CurAbbrevs.push_back(Info->Abbrevs[i]); 306 CurAbbrevs.push_back(Info->Abbrevs[i]);
299 Info->Abbrevs[i]->addRef(); 307 Info->Abbrevs[i]->addRef();
300 } 308 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 Emit(NaClBitCodeAbbrevOp::EncodeChar6((char)V), 6); 390 Emit(NaClBitCodeAbbrevOp::EncodeChar6((char)V), 6);
383 break; 391 break;
384 } 392 }
385 } 393 }
386 394
387 /// EmitRecordWithAbbrevImpl - This is the core implementation of the record 395 /// EmitRecordWithAbbrevImpl - This is the core implementation of the record
388 /// emission code. 396 /// emission code.
389 template<typename uintty> 397 template<typename uintty>
390 void EmitRecordWithAbbrevImpl(unsigned Abbrev, 398 void EmitRecordWithAbbrevImpl(unsigned Abbrev,
391 const AbbrevValues<uintty> &Vals) { 399 const AbbrevValues<uintty> &Vals) {
392 unsigned AbbrevNo = Abbrev-naclbitc::FIRST_APPLICATION_ABBREV; 400 const NaClBitCodeAbbrev *Abbv = getAbbreviation(Abbrev);
393 assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); 401 assert(Abbv && "Abbreviation index is invalid");
394 NaClBitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo];
395 402
396 EmitCode(Abbrev); 403 EmitCode(Abbrev);
397 404
398 unsigned RecordIdx = 0; 405 unsigned RecordIdx = 0;
399 for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos()); 406 for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos());
400 i != e; ++i) { 407 i != e; ++i) {
401 const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); 408 const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
402 if (Op.getEncoding() == NaClBitCodeAbbrevOp::Array) { 409 if (Op.getEncoding() == NaClBitCodeAbbrevOp::Array) {
403 // Array case. 410 // Array case.
404 assert(i+2 == e && "array op not second to last?"); 411 assert(i+2 == e && "array op not second to last?");
405 const NaClBitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); 412 const NaClBitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
406 413
407 // Emit a vbr6 to indicate the number of elements present. 414 // Emit a vbr6 to indicate the number of elements present.
408 EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6); 415 EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
409 416
410 // Emit each field. 417 // Emit each field.
411 for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx) 418 for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx)
412 EmitAbbreviatedField(EltEnc, Vals[RecordIdx]); 419 EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
413 } else { 420 } else {
414 assert(RecordIdx < Vals.size() && "Invalid abbrev/record"); 421 assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
415 EmitAbbreviatedField(Op, Vals[RecordIdx]); 422 EmitAbbreviatedField(Op, Vals[RecordIdx]);
416 ++RecordIdx; 423 ++RecordIdx;
417 } 424 }
418 } 425 }
419 assert(RecordIdx == Vals.size() && "Not all record operands emitted!"); 426 assert(RecordIdx == Vals.size() && "Not all record operands emitted!");
420 } 427 }
421 428
422 public: 429 public:
423 430
424 /// Returns true if the given abbreviation index corresponds to a user-defined 431 /// Returns a pointer to the abbreviation currently associated with
425 /// abbreviation. 432 /// the abbreviation index. Returns nullptr if no such abbreviation.
426 bool isUserRecordAbbreviation(unsigned Abbrev) const { 433 const NaClBitCodeAbbrev *getAbbreviation(unsigned Index) const {
427 return Abbrev >= naclbitc::FIRST_APPLICATION_ABBREV 434 if (Index < naclbitc::FIRST_APPLICATION_ABBREV)
428 && Abbrev < (CurAbbrevs.size() + naclbitc::FIRST_APPLICATION_ABBREV); 435 return nullptr;
436 if (Index >= BlockScope.back().AbbreviationIndexLimit)
437 return nullptr;
438 unsigned AbbrevNo = Index - naclbitc::FIRST_APPLICATION_ABBREV;
439 if (AbbrevNo >= CurAbbrevs.size())
440 return nullptr;
441 return CurAbbrevs[AbbrevNo];
429 } 442 }
430 443
431 /// EmitRecord - Emit the specified record to the stream, using an abbrev if 444 /// EmitRecord - Emit the specified record to the stream, using an abbrev if
432 /// we have one to compress the output. 445 /// we have one to compress the output.
433 template<typename uintty> 446 template<typename uintty>
434 void EmitRecord(unsigned Code, const SmallVectorImpl<uintty> &Vals, 447 void EmitRecord(unsigned Code, const SmallVectorImpl<uintty> &Vals,
435 unsigned Abbrev = 0) { 448 unsigned Abbrev = 0) {
436 if (!Abbrev) { 449 if (!Abbrev) {
437 // If we don't have an abbrev to use, emit this in its fully unabbreviated 450 // If we don't have an abbrev to use, emit this in its fully unabbreviated
438 // form. 451 // form.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 Info.Abbrevs.push_back(Abbv); 544 Info.Abbrevs.push_back(Abbv);
532 545
533 return Info.Abbrevs.size()-1+naclbitc::FIRST_APPLICATION_ABBREV; 546 return Info.Abbrevs.size()-1+naclbitc::FIRST_APPLICATION_ABBREV;
534 } 547 }
535 }; 548 };
536 549
537 550
538 } // End llvm namespace 551 } // End llvm namespace
539 552
540 #endif 553 #endif
OLDNEW
« no previous file with comments | « no previous file | lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeWriter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698