diff options
Diffstat (limited to 'include/llvm/Bitcode/NaCl')
-rw-r--r-- | include/llvm/Bitcode/NaCl/NaClBitCodes.h | 189 | ||||
-rw-r--r-- | include/llvm/Bitcode/NaCl/NaClBitstreamReader.h | 28 | ||||
-rw-r--r-- | include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h | 62 | ||||
-rw-r--r-- | include/llvm/Bitcode/NaCl/NaClLLVMBitCodes.h | 6 |
4 files changed, 236 insertions, 49 deletions
diff --git a/include/llvm/Bitcode/NaCl/NaClBitCodes.h b/include/llvm/Bitcode/NaCl/NaClBitCodes.h new file mode 100644 index 0000000000..4c0f754f7b --- /dev/null +++ b/include/llvm/Bitcode/NaCl/NaClBitCodes.h @@ -0,0 +1,189 @@ +//===- NaClBitCodes.h - Enum values for the bitcode format ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header Bitcode enum values. +// +// The enum values defined in this file should be considered permanent. If +// new features are added, they should have values added at the end of the +// respective lists. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BITCODE_NACL_NACLBITCODES_H +#define LLVM_BITCODE_NACL_NACLBITCODES_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorHandling.h" +#include <cassert> + +namespace llvm { +namespace naclbitc { + enum StandardWidths { + BlockIDWidth = 8, // We use VBR-8 for block IDs. + CodeLenWidth = 4, // Codelen are VBR-4. + BlockSizeWidth = 32 // BlockSize up to 2^32 32-bit words = 16GB per block. + }; + + // The standard abbrev namespace always has a way to exit a block, enter a + // nested block, define abbrevs, and define an unabbreviated record. + enum FixedAbbrevIDs { + 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, + + // 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_APPLICATION_ABBREV = 4 + }; + + /// StandardBlockIDs - All bitcode files can optionally include a BLOCKINFO + /// block, which contains metadata about other blocks in the file. + enum StandardBlockIDs { + /// BLOCKINFO_BLOCK is used to define metadata about blocks, for example, + /// standard abbrevs that should be available to all blocks of a specified + /// ID. + BLOCKINFO_BLOCK_ID = 0, + + // Block IDs 1-7 are reserved for future expansion. + FIRST_APPLICATION_BLOCKID = 8 + }; + + /// BlockInfoCodes - The blockinfo block contains metadata about user-defined + /// blocks. + enum BlockInfoCodes { + // DEFINE_ABBREV has magic semantics here, applying to the current SETBID'd + // block, instead of the BlockInfo block. + + BLOCKINFO_CODE_SETBID = 1, // SETBID: [blockid#] + BLOCKINFO_CODE_BLOCKNAME = 2, // BLOCKNAME: [name] + BLOCKINFO_CODE_SETRECORDNAME = 3 // BLOCKINFO_CODE_SETRECORDNAME: + // [id, name] + }; + +} // End naclbitc namespace + +/// NaClBitCodeAbbrevOp - 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 NaClBitCodeAbbrevOp { + 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 { + Fixed = 1, // A fixed width field, Val specifies number of bits. + VBR = 2, // A VBR field where Val specifies the width of each chunk. + Array = 3, // A sequence of fields, next field species elt encoding. + Char6 = 4, // A 6-bit fixed field which maps to [a-zA-Z0-9._]. + Blob = 5 // 32-bit aligned array of 8-bit characters. + }; + + explicit NaClBitCodeAbbrevOp(uint64_t V) : Val(V), IsLiteral(true) {} + explicit NaClBitCodeAbbrevOp(Encoding E, uint64_t Data = 0) + : 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() && hasEncodingData()); + return Val; + } + + bool hasEncodingData() const { return hasEncodingData(getEncoding()); } + static bool hasEncodingData(Encoding E) { + switch (E) { + case Fixed: + case VBR: + return true; + case Array: + case Char6: + case Blob: + return false; + } + llvm_unreachable("Invalid encoding"); + } + + /// isChar6 - Return true if this character is legal in the Char6 encoding. + static bool isChar6(char C) { + if (C >= 'a' && C <= 'z') return true; + if (C >= 'A' && C <= 'Z') return true; + if (C >= '0' && C <= '9') return true; + if (C == '.' || C == '_') return true; + return false; + } + static unsigned EncodeChar6(char C) { + if (C >= 'a' && C <= 'z') return C-'a'; + if (C >= 'A' && C <= 'Z') return C-'A'+26; + if (C >= '0' && C <= '9') return C-'0'+26+26; + if (C == '.') return 62; + if (C == '_') return 63; + llvm_unreachable("Not a value Char6 character!"); + } + + static char DecodeChar6(unsigned V) { + assert((V & ~63) == 0 && "Not a Char6 encoded character!"); + if (V < 26) return V+'a'; + if (V < 26+26) return V-26+'A'; + if (V < 26+26+10) return V-26-26+'0'; + if (V == 62) return '.'; + if (V == 63) return '_'; + llvm_unreachable("Not a value Char6 character!"); + } + +}; + +template <> struct isPodLike<NaClBitCodeAbbrevOp> { + static const bool value=true; +}; + +/// NaClBitCodeAbbrev - This class represents an abbreviation record. An +/// abbreviation allows a complex record that has redundancy to be stored in a +/// specialized format instead of the fully-general, fully-vbr, format. +class NaClBitCodeAbbrev { + SmallVector<NaClBitCodeAbbrevOp, 32> OperandList; + unsigned char RefCount; // Number of things using this. + ~NaClBitCodeAbbrev() {} +public: + NaClBitCodeAbbrev() : RefCount(1) {} + + void addRef() { ++RefCount; } + void dropRef() { if (--RefCount == 0) delete this; } + + unsigned getNumOperandInfos() const { + return static_cast<unsigned>(OperandList.size()); + } + const NaClBitCodeAbbrevOp &getOperandInfo(unsigned N) const { + return OperandList[N]; + } + + void Add(const NaClBitCodeAbbrevOp &OpInfo) { + OperandList.push_back(OpInfo); + } +}; +} // End llvm namespace + +#endif diff --git a/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h b/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h index 238ce5275a..58c0a5d7fa 100644 --- a/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h +++ b/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h @@ -39,7 +39,7 @@ public: /// These describe abbreviations that all blocks of the specified ID inherit. struct BlockInfo { unsigned BlockID; - std::vector<BitCodeAbbrev*> Abbrevs; + std::vector<NaClBitCodeAbbrev*> Abbrevs; std::string Name; std::vector<std::pair<unsigned, std::string> > RecordNames; @@ -189,11 +189,11 @@ class NaClBitstreamCursor { unsigned CurCodeSize; /// CurAbbrevs - Abbrevs installed at in this block. - std::vector<BitCodeAbbrev*> CurAbbrevs; + std::vector<NaClBitCodeAbbrev*> CurAbbrevs; struct Block { unsigned PrevCodeSize; - std::vector<BitCodeAbbrev*> PrevAbbrevs; + std::vector<NaClBitCodeAbbrev*> PrevAbbrevs; explicit Block(unsigned PCS) : PrevCodeSize(PCS) {} }; @@ -286,17 +286,17 @@ public: NaClBitstreamEntry advance(unsigned Flags = 0) { while (1) { unsigned Code = ReadCode(); - if (Code == bitc::END_BLOCK) { + if (Code == naclbitc::END_BLOCK) { // Pop the end of the block unless Flags tells us not to. if (!(Flags & AF_DontPopBlockAtEnd) && ReadBlockEnd()) return NaClBitstreamEntry::getError(); return NaClBitstreamEntry::getEndBlock(); } - if (Code == bitc::ENTER_SUBBLOCK) + if (Code == naclbitc::ENTER_SUBBLOCK) return NaClBitstreamEntry::getSubBlock(ReadSubBlockID()); - if (Code == bitc::DEFINE_ABBREV && + if (Code == naclbitc::DEFINE_ABBREV && !(Flags & AF_DontAutoprocessAbbrevs)) { // We read and accumulate abbrev's, the client can't do anything with // them anyway. @@ -469,7 +469,7 @@ public: /// ReadSubBlockID - Having read the ENTER_SUBBLOCK code, read the BlockID for /// the block. unsigned ReadSubBlockID() { - return ReadVBR(bitc::BlockIDWidth); + return ReadVBR(naclbitc::BlockIDWidth); } /// SkipBlock - Having read the ENTER_SUBBLOCK abbrevid and a BlockID, skip @@ -478,9 +478,9 @@ public: bool SkipBlock() { // Read and ignore the codelen value. Since we are skipping this block, we // don't care what code widths are used inside of it. - ReadVBR(bitc::CodeLenWidth); + ReadVBR(naclbitc::CodeLenWidth); SkipToFourByteBoundary(); - unsigned NumFourBytes = Read(bitc::BlockSizeWidth); + unsigned NumFourBytes = Read(naclbitc::BlockSizeWidth); // Check that the block wasn't partially defined, and that the offset isn't // bogus. @@ -526,17 +526,17 @@ private: //===--------------------------------------------------------------------===// private: - void readAbbreviatedLiteral(const BitCodeAbbrevOp &Op, + void readAbbreviatedLiteral(const NaClBitCodeAbbrevOp &Op, SmallVectorImpl<uint64_t> &Vals); - void readAbbreviatedField(const BitCodeAbbrevOp &Op, + void readAbbreviatedField(const NaClBitCodeAbbrevOp &Op, SmallVectorImpl<uint64_t> &Vals); - void skipAbbreviatedField(const BitCodeAbbrevOp &Op); + void skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op); public: /// getAbbrev - Return the abbreviation for the specified AbbrevId. - const BitCodeAbbrev *getAbbrev(unsigned AbbrevID) { - unsigned AbbrevNo = AbbrevID-bitc::FIRST_APPLICATION_ABBREV; + const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) { + unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV; assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); return CurAbbrevs[AbbrevNo]; } diff --git a/include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h b/include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h index 11443ebd87..26d9cb6b24 100644 --- a/include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h +++ b/include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h @@ -17,7 +17,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Bitcode/BitCodes.h" +#include "llvm/Bitcode/NaCl/NaClBitCodes.h" #include <vector> namespace llvm { @@ -40,12 +40,12 @@ class NaClBitstreamWriter { unsigned BlockInfoCurBID; /// CurAbbrevs - Abbrevs installed at in this block. - std::vector<BitCodeAbbrev*> CurAbbrevs; + std::vector<NaClBitCodeAbbrev*> CurAbbrevs; struct Block { unsigned PrevCodeSize; unsigned StartSizeWord; - std::vector<BitCodeAbbrev*> PrevAbbrevs; + std::vector<NaClBitCodeAbbrev*> PrevAbbrevs; Block(unsigned PCS, unsigned SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {} }; @@ -56,7 +56,7 @@ class NaClBitstreamWriter { /// These describe abbreviations that all blocks of the specified ID inherit. struct BlockInfo { unsigned BlockID; - std::vector<BitCodeAbbrev*> Abbrevs; + std::vector<NaClBitCodeAbbrev*> Abbrevs; }; std::vector<BlockInfo> BlockInfoRecords; @@ -210,16 +210,16 @@ public: void EnterSubblock(unsigned BlockID, unsigned CodeLen) { // Block header: // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] - EmitCode(bitc::ENTER_SUBBLOCK); - EmitVBR(BlockID, bitc::BlockIDWidth); - EmitVBR(CodeLen, bitc::CodeLenWidth); + EmitCode(naclbitc::ENTER_SUBBLOCK); + EmitVBR(BlockID, naclbitc::BlockIDWidth); + EmitVBR(CodeLen, naclbitc::CodeLenWidth); FlushToWord(); unsigned BlockSizeWordIndex = GetWordIndex(); unsigned OldCodeSize = CurCodeSize; // Emit a placeholder, which will be replaced when the block is popped. - Emit(0, bitc::BlockSizeWidth); + Emit(0, naclbitc::BlockSizeWidth); CurCodeSize = CodeLen; @@ -251,7 +251,7 @@ public: // Block tail: // [END_BLOCK, <align4bytes>] - EmitCode(bitc::END_BLOCK); + EmitCode(naclbitc::END_BLOCK); FlushToWord(); // Compute the size of the block, in words, not counting the size field. @@ -275,7 +275,7 @@ private: /// EmitAbbreviatedLiteral - Emit a literal value according to its abbrev /// record. This is a no-op, since the abbrev specifies the literal to use. template<typename uintty> - void EmitAbbreviatedLiteral(const BitCodeAbbrevOp &Op, uintty V) { + void EmitAbbreviatedLiteral(const NaClBitCodeAbbrevOp &Op, uintty V) { assert(Op.isLiteral() && "Not a literal"); // If the abbrev specifies the literal value to use, don't emit // anything. @@ -286,22 +286,22 @@ private: /// EmitAbbreviatedField - Emit a single scalar field value with the specified /// encoding. template<typename uintty> - void EmitAbbreviatedField(const BitCodeAbbrevOp &Op, uintty V) { + void EmitAbbreviatedField(const NaClBitCodeAbbrevOp &Op, uintty V) { assert(!Op.isLiteral() && "Literals should use EmitAbbreviatedLiteral!"); // Encode the value as we are commanded. switch (Op.getEncoding()) { default: llvm_unreachable("Unknown encoding!"); - case BitCodeAbbrevOp::Fixed: + case NaClBitCodeAbbrevOp::Fixed: if (Op.getEncodingData()) Emit((unsigned)V, (unsigned)Op.getEncodingData()); break; - case BitCodeAbbrevOp::VBR: + case NaClBitCodeAbbrevOp::VBR: if (Op.getEncodingData()) EmitVBR64(V, (unsigned)Op.getEncodingData()); break; - case BitCodeAbbrevOp::Char6: - Emit(BitCodeAbbrevOp::EncodeChar6((char)V), 6); + case NaClBitCodeAbbrevOp::Char6: + Emit(NaClBitCodeAbbrevOp::EncodeChar6((char)V), 6); break; } } @@ -315,24 +315,24 @@ private: StringRef Blob) { const char *BlobData = Blob.data(); unsigned BlobLen = (unsigned) Blob.size(); - unsigned AbbrevNo = Abbrev-bitc::FIRST_APPLICATION_ABBREV; + unsigned AbbrevNo = Abbrev-naclbitc::FIRST_APPLICATION_ABBREV; assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); - BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo]; + NaClBitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo]; EmitCode(Abbrev); unsigned RecordIdx = 0; for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos()); i != e; ++i) { - const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); + const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); if (Op.isLiteral()) { assert(RecordIdx < Vals.size() && "Invalid abbrev/record"); EmitAbbreviatedLiteral(Op, Vals[RecordIdx]); ++RecordIdx; - } else if (Op.getEncoding() == BitCodeAbbrevOp::Array) { + } else if (Op.getEncoding() == NaClBitCodeAbbrevOp::Array) { // Array case. assert(i+2 == e && "array op not second to last?"); - const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); + const NaClBitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); // If this record has blob data, emit it, otherwise we must have record // entries to encode this way. @@ -356,7 +356,7 @@ private: for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx) EmitAbbreviatedField(EltEnc, Vals[RecordIdx]); } - } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) { + } else if (Op.getEncoding() == NaClBitCodeAbbrevOp::Blob) { // If this record has blob data, emit it, otherwise we must have record // entries to encode this way. @@ -410,7 +410,7 @@ public: if (!Abbrev) { // If we don't have an abbrev to use, emit this in its fully unabbreviated // form. - EmitCode(bitc::UNABBREV_RECORD); + EmitCode(naclbitc::UNABBREV_RECORD); EmitVBR(Code, 6); EmitVBR(static_cast<uint32_t>(Vals.size()), 6); for (unsigned i = 0, e = static_cast<unsigned>(Vals.size()); i != e; ++i) @@ -468,12 +468,12 @@ public: private: // Emit the abbreviation as a DEFINE_ABBREV record. - void EncodeAbbrev(BitCodeAbbrev *Abbv) { - EmitCode(bitc::DEFINE_ABBREV); + void EncodeAbbrev(NaClBitCodeAbbrev *Abbv) { + EmitCode(naclbitc::DEFINE_ABBREV); EmitVBR(Abbv->getNumOperandInfos(), 5); for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos()); i != e; ++i) { - const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); + const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); Emit(Op.isLiteral(), 1); if (Op.isLiteral()) { EmitVBR64(Op.getLiteralValue(), 8); @@ -488,12 +488,12 @@ public: /// EmitAbbrev - This emits an abbreviation to the stream. Note that this /// method takes ownership of the specified abbrev. - unsigned EmitAbbrev(BitCodeAbbrev *Abbv) { + unsigned EmitAbbrev(NaClBitCodeAbbrev *Abbv) { // Emit the abbreviation as a record. EncodeAbbrev(Abbv); CurAbbrevs.push_back(Abbv); return static_cast<unsigned>(CurAbbrevs.size())-1 + - bitc::FIRST_APPLICATION_ABBREV; + naclbitc::FIRST_APPLICATION_ABBREV; } //===--------------------------------------------------------------------===// @@ -502,7 +502,7 @@ public: /// EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK. void EnterBlockInfoBlock(unsigned CodeWidth) { - EnterSubblock(bitc::BLOCKINFO_BLOCK_ID, CodeWidth); + EnterSubblock(naclbitc::BLOCKINFO_BLOCK_ID, CodeWidth); BlockInfoCurBID = ~0U; } private: @@ -512,7 +512,7 @@ private: if (BlockInfoCurBID == BlockID) return; SmallVector<unsigned, 2> V; V.push_back(BlockID); - EmitRecord(bitc::BLOCKINFO_CODE_SETBID, V); + EmitRecord(naclbitc::BLOCKINFO_CODE_SETBID, V); BlockInfoCurBID = BlockID; } @@ -530,7 +530,7 @@ public: /// EmitBlockInfoAbbrev - Emit a DEFINE_ABBREV record for the specified /// BlockID. - unsigned EmitBlockInfoAbbrev(unsigned BlockID, BitCodeAbbrev *Abbv) { + unsigned EmitBlockInfoAbbrev(unsigned BlockID, NaClBitCodeAbbrev *Abbv) { SwitchToBlockID(BlockID); EncodeAbbrev(Abbv); @@ -538,7 +538,7 @@ public: BlockInfo &Info = getOrCreateBlockInfo(BlockID); Info.Abbrevs.push_back(Abbv); - return Info.Abbrevs.size()-1+bitc::FIRST_APPLICATION_ABBREV; + return Info.Abbrevs.size()-1+naclbitc::FIRST_APPLICATION_ABBREV; } }; diff --git a/include/llvm/Bitcode/NaCl/NaClLLVMBitCodes.h b/include/llvm/Bitcode/NaCl/NaClLLVMBitCodes.h index a8ebe8b8f6..bf31c5bea3 100644 --- a/include/llvm/Bitcode/NaCl/NaClLLVMBitCodes.h +++ b/include/llvm/Bitcode/NaCl/NaClLLVMBitCodes.h @@ -19,16 +19,14 @@ #ifndef LLVM_BITCODE_NACL_NACLLLVMBITCODES_H #define LLVM_BITCODE_NACL_NACLLLVMBITCODES_H -// TODO(kschimpf) Make a NaCl version of BitCodes.h, so that block id's -// and abbreviations can be modified. -#include "llvm/Bitcode/BitCodes.h" +#include "llvm/Bitcode/NaCl/NaClBitCodes.h" namespace llvm { namespace naclbitc { // The only top-level block type defined is for a module. enum NaClBlockIDs { // Blocks - MODULE_BLOCK_ID = bitc::FIRST_APPLICATION_BLOCKID, + MODULE_BLOCK_ID = FIRST_APPLICATION_BLOCKID, // Module sub-block id's. PARAMATTR_BLOCK_ID, |