diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index 2067f222110..f4b620ed19a 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -496,8 +496,22 @@ void BytecodeParser::ParseCompactionTable(const unsigned char *&Buf, const unsigned char *End) { while (Buf != End) { - unsigned NumEntries = read_vbr_uint(Buf, End); - unsigned Ty = read_vbr_uint(Buf, End); + unsigned NumEntries; + unsigned Ty; + + NumEntries = read_vbr_uint(Buf, End); + switch (NumEntries & 3) { + case 0: + case 1: + case 2: + Ty = NumEntries >> 2; + NumEntries &= 3; + break; + case 3: + NumEntries >>= 2; + Ty = read_vbr_uint(Buf, End); + break; + } if (Ty >= CompactionTable.size()) CompactionTable.resize(Ty+1); @@ -513,11 +527,10 @@ void BytecodeParser::ParseCompactionTable(const unsigned char *&Buf, CompactionTable.resize(NumEntries+Type::FirstDerivedTyID); } else { - assert(NumEntries != 0 && "Cannot read zero entries!"); const Type *Typ = getType(Ty); // Push the implicit zero CompactionTable[Ty].push_back(Constant::getNullValue(Typ)); - for (unsigned i = 1; i != NumEntries; ++i) { + for (unsigned i = 0; i != NumEntries; ++i) { Value *V = getGlobalTableValue(Typ, read_vbr_uint(Buf, End)); CompactionTable[Ty].push_back(V); } diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index d0b04d2dabf..a55508e6e0a 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -293,12 +293,24 @@ void BytecodeWriter::outputCompactionTablePlane(unsigned PlaneNo, assert(StartNo < End && "Cannot emit negative range!"); assert(StartNo < Plane.size() && End <= Plane.size()); - output_vbr(unsigned(End-StartNo), Out); // Output the number of things. - output_vbr(PlaneNo, Out); // Emit the type plane this is - // Do not emit the null initializer! if (PlaneNo != Type::TypeTyID) ++StartNo; + // Figure out which encoding to use. By far the most common case we have is + // to emit 0-2 entries in a compaction table plane. + switch (End-StartNo) { + case 0: // Avoid emitting two vbr's if possible. + case 1: + case 2: + output_vbr((PlaneNo << 2) | End-StartNo, Out); + break; + default: + // Output the number of things. + output_vbr((unsigned(End-StartNo) << 2) | 3, Out); + output_vbr(PlaneNo, Out); // Emit the type plane this is + break; + } + for (unsigned i = StartNo; i != End; ++i) output_vbr(Table.getGlobalSlot(Plane[i]), Out); }