Changes in directory llvm/include/llvm/Bitcode:
BitCodes.h updated: 1.1 -> 1.2 BitstreamReader.h updated: 1.3 -> 1.4 BitstreamWriter.h updated: 1.2 -> 1.3 --- Log message: first part of implementation of abbrevs. The writer isn't fully there yet and the reader doesn't handle them at all yet. --- Diffs of the changes: (+109 -13) BitCodes.h | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++--- BitstreamReader.h | 3 -- BitstreamWriter.h | 54 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 109 insertions(+), 13 deletions(-) Index: llvm/include/llvm/Bitcode/BitCodes.h diff -u llvm/include/llvm/Bitcode/BitCodes.h:1.1 llvm/include/llvm/Bitcode/BitCodes.h:1.2 --- llvm/include/llvm/Bitcode/BitCodes.h:1.1 Sun Apr 22 01:22:05 2007 +++ llvm/include/llvm/Bitcode/BitCodes.h Mon Apr 23 11:04:05 2007 @@ -18,6 +18,10 @@ #ifndef LLVM_BITCODE_BITCODES_H #define LLVM_BITCODE_BITCODES_H +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/DataTypes.h" +#include <cassert> + namespace llvm { namespace bitc { enum StandardWidths { @@ -31,16 +35,71 @@ enum FixedCodes { END_BLOCK = 0, // Must be zero to guarantee termination for broken bitcode. ENTER_SUBBLOCK = 1, + + /// DEFINE_ABBREV - Defines an abbrev for the current block. It consists + /// of a vbr5 for # operand infos. Each operand info is emitted with a + /// single bit to indicate if it is a literal encoding. If so, the value is + /// emitted with a vbr8. If not, the encoding is emitted as 3 bits followed + /// by the info value as a vbr5 if needed. + DEFINE_ABBREV = 2, - // Two codes are reserved for defining abbrevs and for emitting an - // unabbreviated record. - DEFINE_ABBREVS = 2, + // UNABBREV_RECORDs are emitted with a vbr6 for the record code, followed by + // a vbr6 for the # operands, followed by vbr6's for each operand. UNABBREV_RECORD = 3, // This is not a code, this is a marker for the first abbrev assignment. FIRST_ABBREV = 4 }; } // End bitc namespace + +/// BitCodeAbbrevOp - This describes one or more operands in an abbreviation. +/// This is actually a union of two different things: +/// 1. It could be a literal integer value ("the operand is always 17"). +/// 2. It could be an encoding specification ("this operand encoded like so"). +/// +class BitCodeAbbrevOp { + uint64_t Val; // A literal value or data for an encoding. + bool IsLiteral : 1; // Indicate whether this is a literal value or not. + unsigned Enc : 3; // The encoding to use. +public: + enum Encoding { + FixedWidth = 1, // A fixed with field, Val specifies number of bits. + VBR = 2 // A VBR field where Val specifies the width of each chunk. + }; + + BitCodeAbbrevOp(uint64_t V) : Val(V), IsLiteral(true) {} + BitCodeAbbrevOp(Encoding E, uint64_t Data) + : Val(Data), IsLiteral(false), Enc(E) {} + + bool isLiteral() const { return IsLiteral; } + bool isEncoding() const { return !IsLiteral; } + + // Accessors for literals. + uint64_t getLiteralValue() const { assert(isLiteral()); return Val; } + + // Accessors for encoding info. + Encoding getEncoding() const { assert(isEncoding()); return (Encoding)Enc; } + uint64_t getEncodingData() const { assert(isEncoding()); return Val; } + + bool hasEncodingData() const { return hasEncodingData(getEncoding()); } + static bool hasEncodingData(Encoding E) { + return true; + } +}; + +class BitCodeAbbrev { + SmallVector<BitCodeAbbrevOp, 8> OperandList; +public: + + unsigned getNumOperandInfos() const { return OperandList.size(); } + const BitCodeAbbrevOp &getOperandInfo(unsigned N) const { + return OperandList[N]; + } + + void Add(const BitCodeAbbrevOp &OpInfo) { + OperandList.push_back(OpInfo); + } +}; } // End llvm namespace #endif Index: llvm/include/llvm/Bitcode/BitstreamReader.h diff -u llvm/include/llvm/Bitcode/BitstreamReader.h:1.3 llvm/include/llvm/Bitcode/BitstreamReader.h:1.4 --- llvm/include/llvm/Bitcode/BitstreamReader.h:1.3 Sun Apr 22 11:31:22 2007 +++ llvm/include/llvm/Bitcode/BitstreamReader.h Mon Apr 23 11:04:05 2007 @@ -16,9 +16,6 @@ #define BITSTREAM_READER_H #include "llvm/Bitcode/BitCodes.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/DataTypes.h" -#include <cassert> namespace llvm { Index: llvm/include/llvm/Bitcode/BitstreamWriter.h diff -u llvm/include/llvm/Bitcode/BitstreamWriter.h:1.2 llvm/include/llvm/Bitcode/BitstreamWriter.h:1.3 --- llvm/include/llvm/Bitcode/BitstreamWriter.h:1.2 Sun Apr 22 10:00:52 2007 +++ llvm/include/llvm/Bitcode/BitstreamWriter.h Mon Apr 23 11:04:05 2007 @@ -16,9 +16,6 @@ #define BITSTREAM_WRITER_H #include "llvm/Bitcode/BitCodes.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/DataTypes.h" -#include <cassert> #include <vector> namespace llvm { @@ -39,11 +36,14 @@ struct Block { unsigned PrevCodeSize; unsigned StartSizeWord; + std::vector<BitCodeAbbrev*> PrevAbbrevs; Block(unsigned PCS, unsigned SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {} }; /// BlockScope - This tracks the current blocks that we have entered. std::vector<Block> BlockScope; + + std::vector<BitCodeAbbrev*> CurAbbrevs; public: BitstreamWriter(std::vector<unsigned char> &O) : Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {} @@ -145,6 +145,12 @@ EmitVBR(CodeLen, bitc::CodeLenWidth); FlushToWord(); BlockScope.push_back(Block(CurCodeSize, Out.size()/4)); + + // Delete all abbrevs. + for (unsigned i = 0, e = CurAbbrevs.size(); i != e; ++i) + delete CurAbbrevs[i]; + + BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); // Emit a placeholder, which will be replaced when the block is popped. Emit(0, bitc::BlockSizeWidth); @@ -153,8 +159,7 @@ void ExitBlock() { assert(!BlockScope.empty() && "Block scope imbalance!"); - Block B = BlockScope.back(); - BlockScope.pop_back(); + const Block &B = BlockScope.back(); // Block tail: // [END_BLOCK, <align4bytes>] @@ -171,8 +176,10 @@ Out[ByteNo++] = (unsigned char)(SizeInWords >> 16); Out[ByteNo++] = (unsigned char)(SizeInWords >> 24); - // Restore the outer block's code size. + // Restore the inner block's code size and abbrev table. CurCodeSize = B.PrevCodeSize; + BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); + BlockScope.pop_back(); } //===--------------------------------------------------------------------===// @@ -184,7 +191,14 @@ void EmitRecord(unsigned Code, SmallVectorImpl<uint64_t> &Vals, unsigned Abbrev = 0) { if (Abbrev) { - assert(0 && "abbrevs not implemented yet!"); + unsigned AbbrevNo = Abbrev-bitc::FIRST_ABBREV; + assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); + BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo]; + assert(0 && "TODO"); + for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) { + } + + } else { // If we don't have an abbrev to use, emit this in its fully unabbreviated // form. @@ -212,6 +226,32 @@ EmitVBR(Vals[i], 6); } } + + //===--------------------------------------------------------------------===// + // Abbrev Emission + //===--------------------------------------------------------------------===// + + /// EmitAbbrev - This emits an abbreviation to the stream. Note that this + /// method takes ownership of the specified abbrev. + unsigned EmitAbbrev(BitCodeAbbrev *Abbv) { + // Emit the abbreviation as a record. + EmitCode(bitc::DEFINE_ABBREV); + EmitVBR(Abbv->getNumOperandInfos(), 5); + for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) { + const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); + Emit(Op.isLiteral(), 1); + if (Op.isLiteral()) { + EmitVBR64(Op.getLiteralValue(), 8); + } else { + Emit(Op.getEncoding(), 3); + if (Op.hasEncodingData()) + EmitVBR64(Op.getEncodingData(), 5); + } + } + + CurAbbrevs.push_back(Abbv); + return CurAbbrevs.size()-1+bitc::FIRST_ABBREV; + } }; _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits