diff options
Diffstat (limited to 'include/llvm/Bitcode')
-rw-r--r-- | include/llvm/Bitcode/BitCodes.h | 8 | ||||
-rw-r--r-- | include/llvm/Bitcode/BitcodeWriterPass.h | 24 | ||||
-rw-r--r-- | include/llvm/Bitcode/BitstreamReader.h | 349 | ||||
-rw-r--r-- | include/llvm/Bitcode/BitstreamWriter.h | 51 | ||||
-rw-r--r-- | include/llvm/Bitcode/LLVMBitCodes.h | 891 | ||||
-rw-r--r-- | include/llvm/Bitcode/ReaderWriter.h | 81 |
6 files changed, 763 insertions, 641 deletions
diff --git a/include/llvm/Bitcode/BitCodes.h b/include/llvm/Bitcode/BitCodes.h index 96c420151858b..66400b697c5c6 100644 --- a/include/llvm/Bitcode/BitCodes.h +++ b/include/llvm/Bitcode/BitCodes.h @@ -147,12 +147,8 @@ public: 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!"); + return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._" + [V]; } }; diff --git a/include/llvm/Bitcode/BitcodeWriterPass.h b/include/llvm/Bitcode/BitcodeWriterPass.h index a1272cf156e50..946255b878a6d 100644 --- a/include/llvm/Bitcode/BitcodeWriterPass.h +++ b/include/llvm/Bitcode/BitcodeWriterPass.h @@ -16,12 +16,12 @@ #define LLVM_BITCODE_BITCODEWRITERPASS_H #include "llvm/ADT/StringRef.h" +#include "llvm/IR/PassManager.h" namespace llvm { class Module; class ModulePass; class raw_ostream; -class PreservedAnalyses; /// \brief Create and return a pass that writes the module to the specified /// ostream. Note that this pass is designed for use with the legacy pass @@ -30,11 +30,15 @@ class PreservedAnalyses; /// If \c ShouldPreserveUseListOrder, encode use-list order so it can be /// reproduced when deserialized. /// -/// If \c EmitFunctionSummary, emit the function summary index (currently -/// for use in ThinLTO optimization). +/// If \c EmitSummaryIndex, emit the summary index (currently for use in ThinLTO +/// optimization). +/// +/// If \c EmitModuleHash, compute and emit the module hash in the bitcode +/// (currently for use in ThinLTO incremental build). ModulePass *createBitcodeWriterPass(raw_ostream &Str, bool ShouldPreserveUseListOrder = false, - bool EmitFunctionSummary = false); + bool EmitSummaryIndex = false, + bool EmitModuleHash = false); /// \brief Pass for writing a module of IR out to a bitcode file. /// @@ -43,7 +47,8 @@ ModulePass *createBitcodeWriterPass(raw_ostream &Str, class BitcodeWriterPass { raw_ostream &OS; bool ShouldPreserveUseListOrder; - bool EmitFunctionSummary; + bool EmitSummaryIndex; + bool EmitModuleHash; public: /// \brief Construct a bitcode writer pass around a particular output stream. @@ -51,17 +56,18 @@ public: /// If \c ShouldPreserveUseListOrder, encode use-list order so it can be /// reproduced when deserialized. /// - /// If \c EmitFunctionSummary, emit the function summary index (currently + /// If \c EmitSummaryIndex, emit the summary index (currently /// for use in ThinLTO optimization). explicit BitcodeWriterPass(raw_ostream &OS, bool ShouldPreserveUseListOrder = false, - bool EmitFunctionSummary = false) + bool EmitSummaryIndex = false, + bool EmitModuleHash = false) : OS(OS), ShouldPreserveUseListOrder(ShouldPreserveUseListOrder), - EmitFunctionSummary(EmitFunctionSummary) {} + EmitSummaryIndex(EmitSummaryIndex), EmitModuleHash(EmitModuleHash) {} /// \brief Run the bitcode writer pass, and output the module to the selected /// output stream. - PreservedAnalyses run(Module &M); + PreservedAnalyses run(Module &M, ModuleAnalysisManager &); static StringRef name() { return "BitcodeWriterPass"; } }; diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h index c0cf6cde887f1..b331ceea051c3 100644 --- a/include/llvm/Bitcode/BitstreamReader.h +++ b/include/llvm/Bitcode/BitstreamReader.h @@ -17,6 +17,7 @@ #include "llvm/Bitcode/BitCodes.h" #include "llvm/Support/Endian.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/StreamingMemoryObject.h" #include <climits> #include <string> @@ -128,175 +129,64 @@ public: } }; -/// When advancing through a bitstream cursor, each advance can discover a few -/// different kinds of entries: -struct BitstreamEntry { - enum { - Error, // Malformed bitcode was found. - EndBlock, // We've reached the end of the current block, (or the end of the - // file, which is treated like a series of EndBlock records. - SubBlock, // This is the start of a new subblock of a specific ID. - Record // This is a record with a specific AbbrevID. - } Kind; - - unsigned ID; - - static BitstreamEntry getError() { - BitstreamEntry E; E.Kind = Error; return E; - } - static BitstreamEntry getEndBlock() { - BitstreamEntry E; E.Kind = EndBlock; return E; - } - static BitstreamEntry getSubBlock(unsigned ID) { - BitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E; - } - static BitstreamEntry getRecord(unsigned AbbrevID) { - BitstreamEntry E; E.Kind = Record; E.ID = AbbrevID; return E; - } -}; - -/// This represents a position within a bitcode file. There may be multiple -/// independent cursors reading within one bitstream, each maintaining their own -/// local state. -/// -/// Unlike iterators, BitstreamCursors are heavy-weight objects that should not -/// be passed by value. -class BitstreamCursor { - BitstreamReader *BitStream; - size_t NextChar; +/// This represents a position within a bitstream. There may be multiple +/// independent cursors reading within one bitstream, each maintaining their +/// own local state. +class SimpleBitstreamCursor { + BitstreamReader *R = nullptr; + size_t NextChar = 0; // The size of the bicode. 0 if we don't know it yet. - size_t Size; + size_t Size = 0; /// This is the current data we have pulled from the stream but have not /// returned to the client. This is specifically and intentionally defined to /// follow the word size of the host machine for efficiency. We use word_t in /// places that are aware of this to make it perfectly explicit what is going /// on. +public: typedef size_t word_t; - word_t CurWord; + +private: + word_t CurWord = 0; /// This is the number of bits in CurWord that are valid. This is always from /// [0...bits_of(size_t)-1] inclusive. - unsigned BitsInCurWord; - - // This is the declared size of code values used for the current block, in - // bits. - unsigned CurCodeSize; - - /// Abbrevs installed at in this block. - std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> CurAbbrevs; - - struct Block { - unsigned PrevCodeSize; - std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> PrevAbbrevs; - explicit Block(unsigned PCS) : PrevCodeSize(PCS) {} - }; - - /// This tracks the codesize of parent blocks. - SmallVector<Block, 8> BlockScope; - + unsigned BitsInCurWord = 0; public: static const size_t MaxChunkSize = sizeof(word_t) * 8; - BitstreamCursor() { init(nullptr); } - - explicit BitstreamCursor(BitstreamReader &R) { init(&R); } + SimpleBitstreamCursor() = default; - void init(BitstreamReader *R) { - freeState(); - - BitStream = R; - NextChar = 0; - Size = 0; - BitsInCurWord = 0; - CurCodeSize = 2; - } - - void freeState(); + explicit SimpleBitstreamCursor(BitstreamReader &R) : R(&R) {} + explicit SimpleBitstreamCursor(BitstreamReader *R) : R(R) {} bool canSkipToPos(size_t pos) const { // pos can be skipped to if it is a valid address or one byte past the end. - return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( - static_cast<uint64_t>(pos - 1)); + return pos == 0 || + R->getBitcodeBytes().isValidAddress(static_cast<uint64_t>(pos - 1)); } bool AtEndOfStream() { if (BitsInCurWord != 0) return false; if (Size != 0) - return Size == NextChar; + return Size <= NextChar; fillCurWord(); return BitsInCurWord == 0; } - /// Return the number of bits used to encode an abbrev #. - unsigned getAbbrevIDWidth() const { return CurCodeSize; } - /// Return the bit # of the bit we are reading. uint64_t GetCurrentBitNo() const { return NextChar*CHAR_BIT - BitsInCurWord; } - BitstreamReader *getBitStreamReader() { - return BitStream; - } - const BitstreamReader *getBitStreamReader() const { - return BitStream; - } - - /// Flags that modify the behavior of advance(). - enum { - /// If this flag is used, the advance() method does not automatically pop - /// the block scope when the end of a block is reached. - AF_DontPopBlockAtEnd = 1, - - /// If this flag is used, abbrev entries are returned just like normal - /// records. - AF_DontAutoprocessAbbrevs = 2 - }; - - /// Advance the current bitstream, returning the next entry in the stream. - BitstreamEntry advance(unsigned Flags = 0) { - while (1) { - unsigned Code = ReadCode(); - if (Code == bitc::END_BLOCK) { - // Pop the end of the block unless Flags tells us not to. - if (!(Flags & AF_DontPopBlockAtEnd) && ReadBlockEnd()) - return BitstreamEntry::getError(); - return BitstreamEntry::getEndBlock(); - } - - if (Code == bitc::ENTER_SUBBLOCK) - return BitstreamEntry::getSubBlock(ReadSubBlockID()); - - if (Code == bitc::DEFINE_ABBREV && - !(Flags & AF_DontAutoprocessAbbrevs)) { - // We read and accumulate abbrev's, the client can't do anything with - // them anyway. - ReadAbbrevRecord(); - continue; - } - - return BitstreamEntry::getRecord(Code); - } - } + // Return the byte # of the current bit. + uint64_t getCurrentByteNo() const { return GetCurrentBitNo() / 8; } - /// This is a convenience function for clients that don't expect any - /// subblocks. This just skips over them automatically. - BitstreamEntry advanceSkippingSubblocks(unsigned Flags = 0) { - while (1) { - // If we found a normal entry, return it. - BitstreamEntry Entry = advance(Flags); - if (Entry.Kind != BitstreamEntry::SubBlock) - return Entry; - - // If we found a sub-block, just skip over it and check the next entry. - if (SkipBlock()) - return BitstreamEntry::getError(); - } - } + BitstreamReader *getBitStreamReader() { return R; } + const BitstreamReader *getBitStreamReader() const { return R; } /// Reset the stream to the specified bit number. void JumpToBit(uint64_t BitNo) { @@ -313,6 +203,37 @@ public: Read(WordBitNo); } + /// Reset the stream to the bit pointed at by the specified pointer. + /// + /// The pointer must be a dereferenceable pointer into the bytes in the + /// underlying memory object. + void jumpToPointer(const uint8_t *Pointer) { + auto *Pointer0 = getPointerToByte(0, 1); + assert((intptr_t)Pointer0 <= (intptr_t)Pointer && + "Expected pointer into bitstream"); + + JumpToBit(8 * (Pointer - Pointer0)); + assert((intptr_t)getPointerToByte(getCurrentByteNo(), 1) == + (intptr_t)Pointer && + "Expected to reach pointer"); + } + void jumpToPointer(const char *Pointer) { + jumpToPointer((const uint8_t *)Pointer); + } + + /// Get a pointer into the bitstream at the specified byte offset. + const uint8_t *getPointerToByte(uint64_t ByteNo, uint64_t NumBytes) { + return R->getBitcodeBytes().getPointer(ByteNo, NumBytes); + } + + /// Get a pointer into the bitstream at the specified bit offset. + /// + /// The bit offset must be on a byte boundary. + const uint8_t *getPointerToBit(uint64_t BitNo, uint64_t NumBytes) { + assert(!(BitNo % 8) && "Expected bit on byte boundary"); + return getPointerToByte(BitNo / 8, NumBytes); + } + void fillCurWord() { if (Size != 0 && NextChar >= Size) report_fatal_error("Unexpected end of file"); @@ -321,7 +242,7 @@ public: uint8_t Array[sizeof(word_t)] = {0}; uint64_t BytesRead = - BitStream->getBitcodeBytes().readBytes(Array, sizeof(Array), NextChar); + R->getBitcodeBytes().readBytes(Array, sizeof(Array), NextChar); // If we run out of data, stop at the end of the stream. if (BytesRead == 0) { @@ -416,7 +337,6 @@ public: } } -private: void SkipToFourByteBoundary() { // If word_t is 64-bits and if we've read less than 32 bits, just dump // the bits we have up to the next 32-bit boundary. @@ -429,7 +349,166 @@ private: BitsInCurWord = 0; } + + /// Skip to the end of the file. + void skipToEnd() { NextChar = R->getBitcodeBytes().getExtent(); } + + /// Prevent the cursor from reading past a byte boundary. + /// + /// Prevent the cursor from requesting byte reads past \c Limit. This is + /// useful when working with a cursor on a StreamingMemoryObject, when it's + /// desirable to avoid invalidating the result of getPointerToByte(). + /// + /// If \c Limit is on a word boundary, AtEndOfStream() will return true if + /// the cursor position reaches or exceeds \c Limit, regardless of the true + /// number of available bytes. Otherwise, AtEndOfStream() returns true when + /// it reaches or exceeds the next word boundary. + void setArtificialByteLimit(uint64_t Limit) { + assert(getCurrentByteNo() < Limit && "Move cursor before lowering limit"); + + // Round to word boundary. + Limit = alignTo(Limit, sizeof(word_t)); + + // Only change size if the new one is lower. + if (!Size || Size > Limit) + Size = Limit; + } + + /// Return the Size, if known. + uint64_t getSizeIfKnown() const { return Size; } +}; + +/// When advancing through a bitstream cursor, each advance can discover a few +/// different kinds of entries: +struct BitstreamEntry { + enum { + Error, // Malformed bitcode was found. + EndBlock, // We've reached the end of the current block, (or the end of the + // file, which is treated like a series of EndBlock records. + SubBlock, // This is the start of a new subblock of a specific ID. + Record // This is a record with a specific AbbrevID. + } Kind; + + unsigned ID; + + static BitstreamEntry getError() { + BitstreamEntry E; E.Kind = Error; return E; + } + static BitstreamEntry getEndBlock() { + BitstreamEntry E; E.Kind = EndBlock; return E; + } + static BitstreamEntry getSubBlock(unsigned ID) { + BitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E; + } + static BitstreamEntry getRecord(unsigned AbbrevID) { + BitstreamEntry E; E.Kind = Record; E.ID = AbbrevID; return E; + } +}; + +/// This represents a position within a bitcode file, implemented on top of a +/// SimpleBitstreamCursor. +/// +/// Unlike iterators, BitstreamCursors are heavy-weight objects that should not +/// be passed by value. +class BitstreamCursor : SimpleBitstreamCursor { + // This is the declared size of code values used for the current block, in + // bits. + unsigned CurCodeSize = 2; + + /// Abbrevs installed at in this block. + std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> CurAbbrevs; + + struct Block { + unsigned PrevCodeSize; + std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> PrevAbbrevs; + explicit Block(unsigned PCS) : PrevCodeSize(PCS) {} + }; + + /// This tracks the codesize of parent blocks. + SmallVector<Block, 8> BlockScope; + + public: + static const size_t MaxChunkSize = sizeof(word_t) * 8; + + BitstreamCursor() = default; + + explicit BitstreamCursor(BitstreamReader &R) { init(&R); } + + void init(BitstreamReader *R) { + freeState(); + SimpleBitstreamCursor::operator=(SimpleBitstreamCursor(R)); + CurCodeSize = 2; + } + + void freeState(); + + using SimpleBitstreamCursor::canSkipToPos; + using SimpleBitstreamCursor::AtEndOfStream; + using SimpleBitstreamCursor::GetCurrentBitNo; + using SimpleBitstreamCursor::getCurrentByteNo; + using SimpleBitstreamCursor::getPointerToByte; + using SimpleBitstreamCursor::getBitStreamReader; + using SimpleBitstreamCursor::JumpToBit; + using SimpleBitstreamCursor::fillCurWord; + using SimpleBitstreamCursor::Read; + using SimpleBitstreamCursor::ReadVBR; + using SimpleBitstreamCursor::ReadVBR64; + + /// Return the number of bits used to encode an abbrev #. + unsigned getAbbrevIDWidth() const { return CurCodeSize; } + + /// Flags that modify the behavior of advance(). + enum { + /// If this flag is used, the advance() method does not automatically pop + /// the block scope when the end of a block is reached. + AF_DontPopBlockAtEnd = 1, + + /// If this flag is used, abbrev entries are returned just like normal + /// records. + AF_DontAutoprocessAbbrevs = 2 + }; + + /// Advance the current bitstream, returning the next entry in the stream. + BitstreamEntry advance(unsigned Flags = 0) { + while (1) { + unsigned Code = ReadCode(); + if (Code == bitc::END_BLOCK) { + // Pop the end of the block unless Flags tells us not to. + if (!(Flags & AF_DontPopBlockAtEnd) && ReadBlockEnd()) + return BitstreamEntry::getError(); + return BitstreamEntry::getEndBlock(); + } + + if (Code == bitc::ENTER_SUBBLOCK) + return BitstreamEntry::getSubBlock(ReadSubBlockID()); + + if (Code == bitc::DEFINE_ABBREV && + !(Flags & AF_DontAutoprocessAbbrevs)) { + // We read and accumulate abbrev's, the client can't do anything with + // them anyway. + ReadAbbrevRecord(); + continue; + } + + return BitstreamEntry::getRecord(Code); + } + } + + /// This is a convenience function for clients that don't expect any + /// subblocks. This just skips over them automatically. + BitstreamEntry advanceSkippingSubblocks(unsigned Flags = 0) { + while (1) { + // If we found a normal entry, return it. + BitstreamEntry Entry = advance(Flags); + if (Entry.Kind != BitstreamEntry::SubBlock) + return Entry; + + // If we found a sub-block, just skip over it and check the next entry. + if (SkipBlock()) + return BitstreamEntry::getError(); + } + } unsigned ReadCode() { return Read(CurCodeSize); diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h index 438f4a6fb69b8..d613f5e189546 100644 --- a/include/llvm/Bitcode/BitstreamWriter.h +++ b/include/llvm/Bitcode/BitstreamWriter.h @@ -361,36 +361,17 @@ private: // If this record has blob data, emit it, otherwise we must have record // entries to encode this way. - // Emit a vbr6 to indicate the number of elements present. if (BlobData) { - EmitVBR(static_cast<uint32_t>(BlobLen), 6); assert(RecordIdx == Vals.size() && "Blob data and record entries specified for blob operand!"); - } else { - EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6); - } - - // Flush to a 32-bit alignment boundary. - FlushToWord(); - - // Emit each field as a literal byte. - if (BlobData) { - for (unsigned i = 0; i != BlobLen; ++i) - WriteByte((unsigned char)BlobData[i]); - // Know that blob data is consumed for assertion below. + assert(Blob.data() == BlobData && "BlobData got moved"); + assert(Blob.size() == BlobLen && "BlobLen got changed"); + emitBlob(Blob); BlobData = nullptr; } else { - for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx) { - assert(isUInt<8>(Vals[RecordIdx]) && - "Value too large to emit as blob"); - WriteByte((unsigned char)Vals[RecordIdx]); - } + emitBlob(Vals.slice(RecordIdx)); } - - // Align end to 32-bits. - while (GetBufferOffset() & 3) - WriteByte(0); } else { // Single scalar field. assert(RecordIdx < Vals.size() && "Invalid abbrev/record"); EmitAbbreviatedField(Op, Vals[RecordIdx]); @@ -403,6 +384,30 @@ private: } public: + /// Emit a blob, including flushing before and tail-padding. + template <class UIntTy> + void emitBlob(ArrayRef<UIntTy> Bytes, bool ShouldEmitSize = true) { + // Emit a vbr6 to indicate the number of elements present. + if (ShouldEmitSize) + EmitVBR(static_cast<uint32_t>(Bytes.size()), 6); + + // Flush to a 32-bit alignment boundary. + FlushToWord(); + + // Emit literal bytes. + for (const auto &B : Bytes) { + assert(isUInt<8>(B) && "Value too large to emit as byte"); + WriteByte((unsigned char)B); + } + + // Align end to 32-bits. + while (GetBufferOffset() & 3) + WriteByte(0); + } + void emitBlob(StringRef Bytes, bool ShouldEmitSize = true) { + emitBlob(makeArrayRef((const uint8_t *)Bytes.data(), Bytes.size()), + ShouldEmitSize); + } /// EmitRecord - Emit the specified record to the stream, using an abbrev if /// we have one to compress the output. diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index bcc84bedbed04..52d4f01b79852 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -22,7 +22,7 @@ namespace llvm { namespace bitc { - // The only top-level block type defined is for a module. +// The only top-level block type defined is for a module. enum BlockIDs { // Blocks MODULE_BLOCK_ID = FIRST_APPLICATION_BLOCKID, @@ -48,7 +48,7 @@ enum BlockIDs { USELIST_BLOCK_ID, MODULE_STRTAB_BLOCK_ID, - FUNCTION_SUMMARY_BLOCK_ID, + GLOBALVAL_SUMMARY_BLOCK_ID, OPERAND_BUNDLE_TAGS_BLOCK_ID, @@ -70,431 +70,468 @@ enum IdentificationCodes { /// also accepts N-1. enum { BITCODE_CURRENT_EPOCH = 0 }; - /// MODULE blocks have a number of optional fields and subblocks. - enum ModuleCodes { - MODULE_CODE_VERSION = 1, // VERSION: [version#] - MODULE_CODE_TRIPLE = 2, // TRIPLE: [strchr x N] - MODULE_CODE_DATALAYOUT = 3, // DATALAYOUT: [strchr x N] - MODULE_CODE_ASM = 4, // ASM: [strchr x N] - MODULE_CODE_SECTIONNAME = 5, // SECTIONNAME: [strchr x N] - - // FIXME: Remove DEPLIB in 4.0. - MODULE_CODE_DEPLIB = 6, // DEPLIB: [strchr x N] - - // GLOBALVAR: [pointer type, isconst, initid, - // linkage, alignment, section, visibility, threadlocal] - MODULE_CODE_GLOBALVAR = 7, - - // FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment, - // section, visibility, gc, unnamed_addr] - MODULE_CODE_FUNCTION = 8, - - // ALIAS: [alias type, aliasee val#, linkage, visibility] - MODULE_CODE_ALIAS_OLD = 9, - - // MODULE_CODE_PURGEVALS: [numvals] - MODULE_CODE_PURGEVALS = 10, - - MODULE_CODE_GCNAME = 11, // GCNAME: [strchr x N] - MODULE_CODE_COMDAT = 12, // COMDAT: [selection_kind, name] - - MODULE_CODE_VSTOFFSET = 13, // VSTOFFSET: [offset] - - // ALIAS: [alias value type, addrspace, aliasee val#, linkage, visibility] - MODULE_CODE_ALIAS = 14, - - // METADATA_VALUES: [numvals] - MODULE_CODE_METADATA_VALUES = 15, - }; - - /// PARAMATTR blocks have code for defining a parameter attribute set. - enum AttributeCodes { - // FIXME: Remove `PARAMATTR_CODE_ENTRY_OLD' in 4.0 - PARAMATTR_CODE_ENTRY_OLD = 1, // ENTRY: [paramidx0, attr0, - // paramidx1, attr1...] - PARAMATTR_CODE_ENTRY = 2, // ENTRY: [paramidx0, attrgrp0, - // paramidx1, attrgrp1, ...] - PARAMATTR_GRP_CODE_ENTRY = 3 // ENTRY: [id, attr0, att1, ...] - }; - - /// TYPE blocks have codes for each type primitive they use. - enum TypeCodes { - TYPE_CODE_NUMENTRY = 1, // NUMENTRY: [numentries] - - // Type Codes - TYPE_CODE_VOID = 2, // VOID - TYPE_CODE_FLOAT = 3, // FLOAT - TYPE_CODE_DOUBLE = 4, // DOUBLE - TYPE_CODE_LABEL = 5, // LABEL - TYPE_CODE_OPAQUE = 6, // OPAQUE - TYPE_CODE_INTEGER = 7, // INTEGER: [width] - TYPE_CODE_POINTER = 8, // POINTER: [pointee type] - - TYPE_CODE_FUNCTION_OLD = 9, // FUNCTION: [vararg, attrid, retty, - // paramty x N] - - TYPE_CODE_HALF = 10, // HALF - - TYPE_CODE_ARRAY = 11, // ARRAY: [numelts, eltty] - TYPE_CODE_VECTOR = 12, // VECTOR: [numelts, eltty] - - // These are not with the other floating point types because they're - // a late addition, and putting them in the right place breaks - // binary compatibility. - TYPE_CODE_X86_FP80 = 13, // X86 LONG DOUBLE - TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa) - TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles) - - TYPE_CODE_METADATA = 16, // METADATA - - TYPE_CODE_X86_MMX = 17, // X86 MMX - - TYPE_CODE_STRUCT_ANON = 18, // STRUCT_ANON: [ispacked, eltty x N] - TYPE_CODE_STRUCT_NAME = 19, // STRUCT_NAME: [strchr x N] - TYPE_CODE_STRUCT_NAMED = 20,// STRUCT_NAMED: [ispacked, eltty x N] - - TYPE_CODE_FUNCTION = 21, // FUNCTION: [vararg, retty, paramty x N] - - TYPE_CODE_TOKEN = 22 // TOKEN - }; - - enum OperandBundleTagCode { - OPERAND_BUNDLE_TAG = 1, // TAG: [strchr x N] - }; - - // The type symbol table only has one code (TST_ENTRY_CODE). - enum TypeSymtabCodes { - TST_CODE_ENTRY = 1 // TST_ENTRY: [typeid, namechar x N] - }; - - // Value symbol table codes. - enum ValueSymtabCodes { - VST_CODE_ENTRY = 1, // VST_ENTRY: [valueid, namechar x N] - VST_CODE_BBENTRY = 2, // VST_BBENTRY: [bbid, namechar x N] - VST_CODE_FNENTRY = 3, // VST_FNENTRY: [valueid, offset, namechar x N] - // VST_COMBINED_FNENTRY: [offset, namechar x N] - VST_CODE_COMBINED_FNENTRY = 4 - }; - - // The module path symbol table only has one code (MST_CODE_ENTRY). - enum ModulePathSymtabCodes { - MST_CODE_ENTRY = 1, // MST_ENTRY: [modid, namechar x N] - }; - - // The function summary section uses different codes in the per-module - // and combined index cases. - enum FunctionSummarySymtabCodes { - FS_CODE_PERMODULE_ENTRY = 1, // FS_ENTRY: [valueid, islocal, instcount] - FS_CODE_COMBINED_ENTRY = 2, // FS_ENTRY: [modid, instcount] - }; - - enum MetadataCodes { - METADATA_STRING = 1, // MDSTRING: [values] - METADATA_VALUE = 2, // VALUE: [type num, value num] - METADATA_NODE = 3, // NODE: [n x md num] - METADATA_NAME = 4, // STRING: [values] - METADATA_DISTINCT_NODE = 5, // DISTINCT_NODE: [n x md num] - METADATA_KIND = 6, // [n x [id, name]] - METADATA_LOCATION = 7, // [distinct, line, col, scope, inlined-at?] - METADATA_OLD_NODE = 8, // OLD_NODE: [n x (type num, value num)] - METADATA_OLD_FN_NODE = 9, // OLD_FN_NODE: [n x (type num, value num)] - METADATA_NAMED_NODE = 10, // NAMED_NODE: [n x mdnodes] - METADATA_ATTACHMENT = 11, // [m x [value, [n x [id, mdnode]]] - METADATA_GENERIC_DEBUG = 12, // [distinct, tag, vers, header, n x md num] - METADATA_SUBRANGE = 13, // [distinct, count, lo] - METADATA_ENUMERATOR = 14, // [distinct, value, name] - METADATA_BASIC_TYPE = 15, // [distinct, tag, name, size, align, enc] - METADATA_FILE = 16, // [distinct, filename, directory] - METADATA_DERIVED_TYPE = 17, // [distinct, ...] - METADATA_COMPOSITE_TYPE= 18, // [distinct, ...] - METADATA_SUBROUTINE_TYPE=19, // [distinct, flags, types] - METADATA_COMPILE_UNIT = 20, // [distinct, ...] - METADATA_SUBPROGRAM = 21, // [distinct, ...] - METADATA_LEXICAL_BLOCK = 22, // [distinct, scope, file, line, column] - METADATA_LEXICAL_BLOCK_FILE=23,//[distinct, scope, file, discriminator] - METADATA_NAMESPACE = 24, // [distinct, scope, file, name, line] - METADATA_TEMPLATE_TYPE = 25, // [distinct, scope, name, type, ...] - METADATA_TEMPLATE_VALUE= 26, // [distinct, scope, name, type, value, ...] - METADATA_GLOBAL_VAR = 27, // [distinct, ...] - METADATA_LOCAL_VAR = 28, // [distinct, ...] - METADATA_EXPRESSION = 29, // [distinct, n x element] - METADATA_OBJC_PROPERTY = 30, // [distinct, name, file, line, ...] - METADATA_IMPORTED_ENTITY=31, // [distinct, tag, scope, entity, line, name] - METADATA_MODULE = 32, // [distinct, scope, name, ...] - METADATA_MACRO = 33, // [distinct, macinfo, line, name, value] - METADATA_MACRO_FILE = 34, // [distinct, macinfo, line, file, ...] - }; - - // The constants block (CONSTANTS_BLOCK_ID) describes emission for each - // constant and maintains an implicit current type value. - enum ConstantsCodes { - CST_CODE_SETTYPE = 1, // SETTYPE: [typeid] - CST_CODE_NULL = 2, // NULL - CST_CODE_UNDEF = 3, // UNDEF - CST_CODE_INTEGER = 4, // INTEGER: [intval] - CST_CODE_WIDE_INTEGER = 5, // WIDE_INTEGER: [n x intval] - CST_CODE_FLOAT = 6, // FLOAT: [fpval] - CST_CODE_AGGREGATE = 7, // AGGREGATE: [n x value number] - CST_CODE_STRING = 8, // STRING: [values] - CST_CODE_CSTRING = 9, // CSTRING: [values] - CST_CODE_CE_BINOP = 10, // CE_BINOP: [opcode, opval, opval] - CST_CODE_CE_CAST = 11, // CE_CAST: [opcode, opty, opval] - CST_CODE_CE_GEP = 12, // CE_GEP: [n x operands] - CST_CODE_CE_SELECT = 13, // CE_SELECT: [opval, opval, opval] - CST_CODE_CE_EXTRACTELT = 14, // CE_EXTRACTELT: [opty, opval, opval] - CST_CODE_CE_INSERTELT = 15, // CE_INSERTELT: [opval, opval, opval] - CST_CODE_CE_SHUFFLEVEC = 16, // CE_SHUFFLEVEC: [opval, opval, opval] - CST_CODE_CE_CMP = 17, // CE_CMP: [opty, opval, opval, pred] - CST_CODE_INLINEASM_OLD = 18, // INLINEASM: [sideeffect|alignstack, - // asmstr,conststr] - CST_CODE_CE_SHUFVEC_EX = 19, // SHUFVEC_EX: [opty, opval, opval, opval] - CST_CODE_CE_INBOUNDS_GEP = 20,// INBOUNDS_GEP: [n x operands] - CST_CODE_BLOCKADDRESS = 21, // CST_CODE_BLOCKADDRESS [fnty, fnval, bb#] - CST_CODE_DATA = 22, // DATA: [n x elements] - CST_CODE_INLINEASM = 23 // INLINEASM: [sideeffect|alignstack| - // asmdialect,asmstr,conststr] - }; - - /// CastOpcodes - These are values used in the bitcode files to encode which - /// cast a CST_CODE_CE_CAST or a XXX refers to. The values of these enums - /// have no fixed relation to the LLVM IR enum values. Changing these will - /// break compatibility with old files. - enum CastOpcodes { - CAST_TRUNC = 0, - CAST_ZEXT = 1, - CAST_SEXT = 2, - CAST_FPTOUI = 3, - CAST_FPTOSI = 4, - CAST_UITOFP = 5, - CAST_SITOFP = 6, - CAST_FPTRUNC = 7, - CAST_FPEXT = 8, - CAST_PTRTOINT = 9, - CAST_INTTOPTR = 10, - CAST_BITCAST = 11, - CAST_ADDRSPACECAST = 12 - }; - - /// BinaryOpcodes - These are values used in the bitcode files to encode which - /// binop a CST_CODE_CE_BINOP or a XXX refers to. The values of these enums - /// have no fixed relation to the LLVM IR enum values. Changing these will - /// break compatibility with old files. - enum BinaryOpcodes { - BINOP_ADD = 0, - BINOP_SUB = 1, - BINOP_MUL = 2, - BINOP_UDIV = 3, - BINOP_SDIV = 4, // overloaded for FP - BINOP_UREM = 5, - BINOP_SREM = 6, // overloaded for FP - BINOP_SHL = 7, - BINOP_LSHR = 8, - BINOP_ASHR = 9, - BINOP_AND = 10, - BINOP_OR = 11, - BINOP_XOR = 12 - }; - - /// These are values used in the bitcode files to encode AtomicRMW operations. - /// The values of these enums have no fixed relation to the LLVM IR enum - /// values. Changing these will break compatibility with old files. - enum RMWOperations { - RMW_XCHG = 0, - RMW_ADD = 1, - RMW_SUB = 2, - RMW_AND = 3, - RMW_NAND = 4, - RMW_OR = 5, - RMW_XOR = 6, - RMW_MAX = 7, - RMW_MIN = 8, - RMW_UMAX = 9, - RMW_UMIN = 10 - }; - - /// OverflowingBinaryOperatorOptionalFlags - Flags for serializing - /// OverflowingBinaryOperator's SubclassOptionalData contents. - enum OverflowingBinaryOperatorOptionalFlags { - OBO_NO_UNSIGNED_WRAP = 0, - OBO_NO_SIGNED_WRAP = 1 - }; - - /// PossiblyExactOperatorOptionalFlags - Flags for serializing - /// PossiblyExactOperator's SubclassOptionalData contents. - enum PossiblyExactOperatorOptionalFlags { - PEO_EXACT = 0 - }; - - /// Encoded AtomicOrdering values. - enum AtomicOrderingCodes { - ORDERING_NOTATOMIC = 0, - ORDERING_UNORDERED = 1, - ORDERING_MONOTONIC = 2, - ORDERING_ACQUIRE = 3, - ORDERING_RELEASE = 4, - ORDERING_ACQREL = 5, - ORDERING_SEQCST = 6 - }; - - /// Encoded SynchronizationScope values. - enum AtomicSynchScopeCodes { - SYNCHSCOPE_SINGLETHREAD = 0, - SYNCHSCOPE_CROSSTHREAD = 1 - }; - - /// Markers and flags for call instruction. - enum CallMarkersFlags { - CALL_TAIL = 0, - CALL_CCONV = 1, - CALL_MUSTTAIL = 14, - CALL_EXPLICIT_TYPE = 15, - CALL_NOTAIL = 16, - CALL_FMF = 17 // Call has optional fast-math-flags. - }; - - // The function body block (FUNCTION_BLOCK_ID) describes function bodies. It - // can contain a constant block (CONSTANTS_BLOCK_ID). - enum FunctionCodes { - FUNC_CODE_DECLAREBLOCKS = 1, // DECLAREBLOCKS: [n] - - FUNC_CODE_INST_BINOP = 2, // BINOP: [opcode, ty, opval, opval] - FUNC_CODE_INST_CAST = 3, // CAST: [opcode, ty, opty, opval] - FUNC_CODE_INST_GEP_OLD = 4, // GEP: [n x operands] - FUNC_CODE_INST_SELECT = 5, // SELECT: [ty, opval, opval, opval] - FUNC_CODE_INST_EXTRACTELT = 6, // EXTRACTELT: [opty, opval, opval] - FUNC_CODE_INST_INSERTELT = 7, // INSERTELT: [ty, opval, opval, opval] - FUNC_CODE_INST_SHUFFLEVEC = 8, // SHUFFLEVEC: [ty, opval, opval, opval] - FUNC_CODE_INST_CMP = 9, // CMP: [opty, opval, opval, pred] - - FUNC_CODE_INST_RET = 10, // RET: [opty,opval<both optional>] - FUNC_CODE_INST_BR = 11, // BR: [bb#, bb#, cond] or [bb#] - FUNC_CODE_INST_SWITCH = 12, // SWITCH: [opty, op0, op1, ...] - FUNC_CODE_INST_INVOKE = 13, // INVOKE: [attr, fnty, op0,op1, ...] - // 14 is unused. - FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE - - FUNC_CODE_INST_PHI = 16, // PHI: [ty, val0,bb0, ...] - // 17 is unused. - // 18 is unused. - FUNC_CODE_INST_ALLOCA = 19, // ALLOCA: [instty, opty, op, align] - FUNC_CODE_INST_LOAD = 20, // LOAD: [opty, op, align, vol] - // 21 is unused. - // 22 is unused. - FUNC_CODE_INST_VAARG = 23, // VAARG: [valistty, valist, instty] - // This store code encodes the pointer type, rather than the value type - // this is so information only available in the pointer type (e.g. address - // spaces) is retained. - FUNC_CODE_INST_STORE_OLD = 24, // STORE: [ptrty,ptr,val, align, vol] - // 25 is unused. - FUNC_CODE_INST_EXTRACTVAL = 26, // EXTRACTVAL: [n x operands] - FUNC_CODE_INST_INSERTVAL = 27, // INSERTVAL: [n x operands] - // fcmp/icmp returning Int1TY or vector of Int1Ty. Same as CMP, exists to - // support legacy vicmp/vfcmp instructions. - FUNC_CODE_INST_CMP2 = 28, // CMP2: [opty, opval, opval, pred] - // new select on i1 or [N x i1] - FUNC_CODE_INST_VSELECT = 29, // VSELECT: [ty,opval,opval,predty,pred] - FUNC_CODE_INST_INBOUNDS_GEP_OLD = 30, // INBOUNDS_GEP: [n x operands] - FUNC_CODE_INST_INDIRECTBR = 31, // INDIRECTBR: [opty, op0, op1, ...] - // 32 is unused. - FUNC_CODE_DEBUG_LOC_AGAIN = 33, // DEBUG_LOC_AGAIN - - FUNC_CODE_INST_CALL = 34, // CALL: [attr, cc, fnty, fnid, args...] - - FUNC_CODE_DEBUG_LOC = 35, // DEBUG_LOC: [Line,Col,ScopeVal, IAVal] - FUNC_CODE_INST_FENCE = 36, // FENCE: [ordering, synchscope] - FUNC_CODE_INST_CMPXCHG_OLD = 37, // CMPXCHG: [ptrty,ptr,cmp,new, align, vol, - // ordering, synchscope] - FUNC_CODE_INST_ATOMICRMW = 38, // ATOMICRMW: [ptrty,ptr,val, operation, - // align, vol, - // ordering, synchscope] - FUNC_CODE_INST_RESUME = 39, // RESUME: [opval] - FUNC_CODE_INST_LANDINGPAD_OLD = 40, // LANDINGPAD: [ty,val,val,num,id0,val0...] - FUNC_CODE_INST_LOADATOMIC = 41, // LOAD: [opty, op, align, vol, - // ordering, synchscope] - FUNC_CODE_INST_STOREATOMIC_OLD = 42, // STORE: [ptrty,ptr,val, align, vol - // ordering, synchscope] - FUNC_CODE_INST_GEP = 43, // GEP: [inbounds, n x operands] - FUNC_CODE_INST_STORE = 44, // STORE: [ptrty,ptr,valty,val, align, vol] - FUNC_CODE_INST_STOREATOMIC = 45, // STORE: [ptrty,ptr,val, align, vol - FUNC_CODE_INST_CMPXCHG = 46, // CMPXCHG: [ptrty,ptr,valty,cmp,new, align, - // vol,ordering,synchscope] - FUNC_CODE_INST_LANDINGPAD = 47, // LANDINGPAD: [ty,val,num,id0,val0...] - FUNC_CODE_INST_CLEANUPRET = 48, // CLEANUPRET: [val] or [val,bb#] - FUNC_CODE_INST_CATCHRET = 49, // CATCHRET: [val,bb#] - FUNC_CODE_INST_CATCHPAD = 50, // CATCHPAD: [bb#,bb#,num,args...] - FUNC_CODE_INST_CLEANUPPAD = 51, // CLEANUPPAD: [num,args...] - FUNC_CODE_INST_CATCHSWITCH = 52, // CATCHSWITCH: [num,args...] or [num,args...,bb] - // 53 is unused. - // 54 is unused. - FUNC_CODE_OPERAND_BUNDLE = 55, // OPERAND_BUNDLE: [tag#, value...] - }; - - enum UseListCodes { - USELIST_CODE_DEFAULT = 1, // DEFAULT: [index..., value-id] - USELIST_CODE_BB = 2 // BB: [index..., bb-id] - }; - - enum AttributeKindCodes { - // = 0 is unused - ATTR_KIND_ALIGNMENT = 1, - ATTR_KIND_ALWAYS_INLINE = 2, - ATTR_KIND_BY_VAL = 3, - ATTR_KIND_INLINE_HINT = 4, - ATTR_KIND_IN_REG = 5, - ATTR_KIND_MIN_SIZE = 6, - ATTR_KIND_NAKED = 7, - ATTR_KIND_NEST = 8, - ATTR_KIND_NO_ALIAS = 9, - ATTR_KIND_NO_BUILTIN = 10, - ATTR_KIND_NO_CAPTURE = 11, - ATTR_KIND_NO_DUPLICATE = 12, - ATTR_KIND_NO_IMPLICIT_FLOAT = 13, - ATTR_KIND_NO_INLINE = 14, - ATTR_KIND_NON_LAZY_BIND = 15, - ATTR_KIND_NO_RED_ZONE = 16, - ATTR_KIND_NO_RETURN = 17, - ATTR_KIND_NO_UNWIND = 18, - ATTR_KIND_OPTIMIZE_FOR_SIZE = 19, - ATTR_KIND_READ_NONE = 20, - ATTR_KIND_READ_ONLY = 21, - ATTR_KIND_RETURNED = 22, - ATTR_KIND_RETURNS_TWICE = 23, - ATTR_KIND_S_EXT = 24, - ATTR_KIND_STACK_ALIGNMENT = 25, - ATTR_KIND_STACK_PROTECT = 26, - ATTR_KIND_STACK_PROTECT_REQ = 27, - ATTR_KIND_STACK_PROTECT_STRONG = 28, - ATTR_KIND_STRUCT_RET = 29, - ATTR_KIND_SANITIZE_ADDRESS = 30, - ATTR_KIND_SANITIZE_THREAD = 31, - ATTR_KIND_SANITIZE_MEMORY = 32, - ATTR_KIND_UW_TABLE = 33, - ATTR_KIND_Z_EXT = 34, - ATTR_KIND_BUILTIN = 35, - ATTR_KIND_COLD = 36, - ATTR_KIND_OPTIMIZE_NONE = 37, - ATTR_KIND_IN_ALLOCA = 38, - ATTR_KIND_NON_NULL = 39, - ATTR_KIND_JUMP_TABLE = 40, - ATTR_KIND_DEREFERENCEABLE = 41, - ATTR_KIND_DEREFERENCEABLE_OR_NULL = 42, - ATTR_KIND_CONVERGENT = 43, - ATTR_KIND_SAFESTACK = 44, - ATTR_KIND_ARGMEMONLY = 45, - ATTR_KIND_SWIFT_SELF = 46, - ATTR_KIND_SWIFT_ERROR = 47, - ATTR_KIND_NO_RECURSE = 48, - ATTR_KIND_INACCESSIBLEMEM_ONLY = 49, - ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY = 50 - }; - - enum ComdatSelectionKindCodes { - COMDAT_SELECTION_KIND_ANY = 1, - COMDAT_SELECTION_KIND_EXACT_MATCH = 2, - COMDAT_SELECTION_KIND_LARGEST = 3, - COMDAT_SELECTION_KIND_NO_DUPLICATES = 4, - COMDAT_SELECTION_KIND_SAME_SIZE = 5, - }; +/// MODULE blocks have a number of optional fields and subblocks. +enum ModuleCodes { + MODULE_CODE_VERSION = 1, // VERSION: [version#] + MODULE_CODE_TRIPLE = 2, // TRIPLE: [strchr x N] + MODULE_CODE_DATALAYOUT = 3, // DATALAYOUT: [strchr x N] + MODULE_CODE_ASM = 4, // ASM: [strchr x N] + MODULE_CODE_SECTIONNAME = 5, // SECTIONNAME: [strchr x N] + + // FIXME: Remove DEPLIB in 4.0. + MODULE_CODE_DEPLIB = 6, // DEPLIB: [strchr x N] + + // GLOBALVAR: [pointer type, isconst, initid, + // linkage, alignment, section, visibility, threadlocal] + MODULE_CODE_GLOBALVAR = 7, + + // FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment, + // section, visibility, gc, unnamed_addr] + MODULE_CODE_FUNCTION = 8, + + // ALIAS: [alias type, aliasee val#, linkage, visibility] + MODULE_CODE_ALIAS_OLD = 9, + + // MODULE_CODE_PURGEVALS: [numvals] + MODULE_CODE_PURGEVALS = 10, + + MODULE_CODE_GCNAME = 11, // GCNAME: [strchr x N] + MODULE_CODE_COMDAT = 12, // COMDAT: [selection_kind, name] + + MODULE_CODE_VSTOFFSET = 13, // VSTOFFSET: [offset] + + // ALIAS: [alias value type, addrspace, aliasee val#, linkage, visibility] + MODULE_CODE_ALIAS = 14, + + MODULE_CODE_METADATA_VALUES_UNUSED = 15, + + // SOURCE_FILENAME: [namechar x N] + MODULE_CODE_SOURCE_FILENAME = 16, + + // HASH: [5*i32] + MODULE_CODE_HASH = 17, + + // IFUNC: [ifunc value type, addrspace, resolver val#, linkage, visibility] + MODULE_CODE_IFUNC = 18, +}; + +/// PARAMATTR blocks have code for defining a parameter attribute set. +enum AttributeCodes { + // FIXME: Remove `PARAMATTR_CODE_ENTRY_OLD' in 4.0 + PARAMATTR_CODE_ENTRY_OLD = 1, // ENTRY: [paramidx0, attr0, + // paramidx1, attr1...] + PARAMATTR_CODE_ENTRY = 2, // ENTRY: [paramidx0, attrgrp0, + // paramidx1, attrgrp1, ...] + PARAMATTR_GRP_CODE_ENTRY = 3 // ENTRY: [id, attr0, att1, ...] +}; + +/// TYPE blocks have codes for each type primitive they use. +enum TypeCodes { + TYPE_CODE_NUMENTRY = 1, // NUMENTRY: [numentries] + + // Type Codes + TYPE_CODE_VOID = 2, // VOID + TYPE_CODE_FLOAT = 3, // FLOAT + TYPE_CODE_DOUBLE = 4, // DOUBLE + TYPE_CODE_LABEL = 5, // LABEL + TYPE_CODE_OPAQUE = 6, // OPAQUE + TYPE_CODE_INTEGER = 7, // INTEGER: [width] + TYPE_CODE_POINTER = 8, // POINTER: [pointee type] + + TYPE_CODE_FUNCTION_OLD = 9, // FUNCTION: [vararg, attrid, retty, + // paramty x N] + + TYPE_CODE_HALF = 10, // HALF + + TYPE_CODE_ARRAY = 11, // ARRAY: [numelts, eltty] + TYPE_CODE_VECTOR = 12, // VECTOR: [numelts, eltty] + + // These are not with the other floating point types because they're + // a late addition, and putting them in the right place breaks + // binary compatibility. + TYPE_CODE_X86_FP80 = 13, // X86 LONG DOUBLE + TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa) + TYPE_CODE_PPC_FP128 = 15, // PPC LONG DOUBLE (2 doubles) + + TYPE_CODE_METADATA = 16, // METADATA + + TYPE_CODE_X86_MMX = 17, // X86 MMX + + TYPE_CODE_STRUCT_ANON = 18, // STRUCT_ANON: [ispacked, eltty x N] + TYPE_CODE_STRUCT_NAME = 19, // STRUCT_NAME: [strchr x N] + TYPE_CODE_STRUCT_NAMED = 20, // STRUCT_NAMED: [ispacked, eltty x N] + + TYPE_CODE_FUNCTION = 21, // FUNCTION: [vararg, retty, paramty x N] + + TYPE_CODE_TOKEN = 22 // TOKEN +}; + +enum OperandBundleTagCode { + OPERAND_BUNDLE_TAG = 1, // TAG: [strchr x N] +}; + +// The type symbol table only has one code (TST_ENTRY_CODE). +enum TypeSymtabCodes { + TST_CODE_ENTRY = 1 // TST_ENTRY: [typeid, namechar x N] +}; + +// Value symbol table codes. +enum ValueSymtabCodes { + VST_CODE_ENTRY = 1, // VST_ENTRY: [valueid, namechar x N] + VST_CODE_BBENTRY = 2, // VST_BBENTRY: [bbid, namechar x N] + VST_CODE_FNENTRY = 3, // VST_FNENTRY: [valueid, offset, namechar x N] + // VST_COMBINED_ENTRY: [valueid, refguid] + VST_CODE_COMBINED_ENTRY = 5 +}; + +// The module path symbol table only has one code (MST_CODE_ENTRY). +enum ModulePathSymtabCodes { + MST_CODE_ENTRY = 1, // MST_ENTRY: [modid, namechar x N] + MST_CODE_HASH = 2, // MST_HASH: [5*i32] +}; + +// The summary section uses different codes in the per-module +// and combined index cases. +enum GlobalValueSummarySymtabCodes { + // PERMODULE: [valueid, flags, instcount, numrefs, numrefs x valueid, + // n x (valueid, callsitecount)] + FS_PERMODULE = 1, + // PERMODULE_PROFILE: [valueid, flags, instcount, numrefs, + // numrefs x valueid, + // n x (valueid, callsitecount, profilecount)] + FS_PERMODULE_PROFILE = 2, + // PERMODULE_GLOBALVAR_INIT_REFS: [valueid, flags, n x valueid] + FS_PERMODULE_GLOBALVAR_INIT_REFS = 3, + // COMBINED: [valueid, modid, flags, instcount, numrefs, numrefs x valueid, + // n x (valueid, callsitecount)] + FS_COMBINED = 4, + // COMBINED_PROFILE: [valueid, modid, flags, instcount, numrefs, + // numrefs x valueid, + // n x (valueid, callsitecount, profilecount)] + FS_COMBINED_PROFILE = 5, + // COMBINED_GLOBALVAR_INIT_REFS: [valueid, modid, flags, n x valueid] + FS_COMBINED_GLOBALVAR_INIT_REFS = 6, + // ALIAS: [valueid, flags, valueid] + FS_ALIAS = 7, + // COMBINED_ALIAS: [valueid, modid, flags, valueid] + FS_COMBINED_ALIAS = 8, + // COMBINED_ORIGINAL_NAME: [original_name_hash] + FS_COMBINED_ORIGINAL_NAME = 9, + // VERSION of the summary, bumped when adding flags for instance. + FS_VERSION = 10, +}; + +enum MetadataCodes { + METADATA_STRING_OLD = 1, // MDSTRING: [values] + METADATA_VALUE = 2, // VALUE: [type num, value num] + METADATA_NODE = 3, // NODE: [n x md num] + METADATA_NAME = 4, // STRING: [values] + METADATA_DISTINCT_NODE = 5, // DISTINCT_NODE: [n x md num] + METADATA_KIND = 6, // [n x [id, name]] + METADATA_LOCATION = 7, // [distinct, line, col, scope, inlined-at?] + METADATA_OLD_NODE = 8, // OLD_NODE: [n x (type num, value num)] + METADATA_OLD_FN_NODE = 9, // OLD_FN_NODE: [n x (type num, value num)] + METADATA_NAMED_NODE = 10, // NAMED_NODE: [n x mdnodes] + METADATA_ATTACHMENT = 11, // [m x [value, [n x [id, mdnode]]] + METADATA_GENERIC_DEBUG = 12, // [distinct, tag, vers, header, n x md num] + METADATA_SUBRANGE = 13, // [distinct, count, lo] + METADATA_ENUMERATOR = 14, // [distinct, value, name] + METADATA_BASIC_TYPE = 15, // [distinct, tag, name, size, align, enc] + METADATA_FILE = 16, // [distinct, filename, directory] + METADATA_DERIVED_TYPE = 17, // [distinct, ...] + METADATA_COMPOSITE_TYPE = 18, // [distinct, ...] + METADATA_SUBROUTINE_TYPE = 19, // [distinct, flags, types, cc] + METADATA_COMPILE_UNIT = 20, // [distinct, ...] + METADATA_SUBPROGRAM = 21, // [distinct, ...] + METADATA_LEXICAL_BLOCK = 22, // [distinct, scope, file, line, column] + METADATA_LEXICAL_BLOCK_FILE = 23, //[distinct, scope, file, discriminator] + METADATA_NAMESPACE = 24, // [distinct, scope, file, name, line] + METADATA_TEMPLATE_TYPE = 25, // [distinct, scope, name, type, ...] + METADATA_TEMPLATE_VALUE = 26, // [distinct, scope, name, type, value, ...] + METADATA_GLOBAL_VAR = 27, // [distinct, ...] + METADATA_LOCAL_VAR = 28, // [distinct, ...] + METADATA_EXPRESSION = 29, // [distinct, n x element] + METADATA_OBJC_PROPERTY = 30, // [distinct, name, file, line, ...] + METADATA_IMPORTED_ENTITY = 31, // [distinct, tag, scope, entity, line, name] + METADATA_MODULE = 32, // [distinct, scope, name, ...] + METADATA_MACRO = 33, // [distinct, macinfo, line, name, value] + METADATA_MACRO_FILE = 34, // [distinct, macinfo, line, file, ...] + METADATA_STRINGS = 35, // [count, offset] blob([lengths][chars]) + METADATA_GLOBAL_DECL_ATTACHMENT = 36, // [valueid, n x [id, mdnode]] +}; + +// The constants block (CONSTANTS_BLOCK_ID) describes emission for each +// constant and maintains an implicit current type value. +enum ConstantsCodes { + CST_CODE_SETTYPE = 1, // SETTYPE: [typeid] + CST_CODE_NULL = 2, // NULL + CST_CODE_UNDEF = 3, // UNDEF + CST_CODE_INTEGER = 4, // INTEGER: [intval] + CST_CODE_WIDE_INTEGER = 5, // WIDE_INTEGER: [n x intval] + CST_CODE_FLOAT = 6, // FLOAT: [fpval] + CST_CODE_AGGREGATE = 7, // AGGREGATE: [n x value number] + CST_CODE_STRING = 8, // STRING: [values] + CST_CODE_CSTRING = 9, // CSTRING: [values] + CST_CODE_CE_BINOP = 10, // CE_BINOP: [opcode, opval, opval] + CST_CODE_CE_CAST = 11, // CE_CAST: [opcode, opty, opval] + CST_CODE_CE_GEP = 12, // CE_GEP: [n x operands] + CST_CODE_CE_SELECT = 13, // CE_SELECT: [opval, opval, opval] + CST_CODE_CE_EXTRACTELT = 14, // CE_EXTRACTELT: [opty, opval, opval] + CST_CODE_CE_INSERTELT = 15, // CE_INSERTELT: [opval, opval, opval] + CST_CODE_CE_SHUFFLEVEC = 16, // CE_SHUFFLEVEC: [opval, opval, opval] + CST_CODE_CE_CMP = 17, // CE_CMP: [opty, opval, opval, pred] + CST_CODE_INLINEASM_OLD = 18, // INLINEASM: [sideeffect|alignstack, + // asmstr,conststr] + CST_CODE_CE_SHUFVEC_EX = 19, // SHUFVEC_EX: [opty, opval, opval, opval] + CST_CODE_CE_INBOUNDS_GEP = 20, // INBOUNDS_GEP: [n x operands] + CST_CODE_BLOCKADDRESS = 21, // CST_CODE_BLOCKADDRESS [fnty, fnval, bb#] + CST_CODE_DATA = 22, // DATA: [n x elements] + CST_CODE_INLINEASM = 23 // INLINEASM: [sideeffect|alignstack| + // asmdialect,asmstr,conststr] +}; + +/// CastOpcodes - These are values used in the bitcode files to encode which +/// cast a CST_CODE_CE_CAST or a XXX refers to. The values of these enums +/// have no fixed relation to the LLVM IR enum values. Changing these will +/// break compatibility with old files. +enum CastOpcodes { + CAST_TRUNC = 0, + CAST_ZEXT = 1, + CAST_SEXT = 2, + CAST_FPTOUI = 3, + CAST_FPTOSI = 4, + CAST_UITOFP = 5, + CAST_SITOFP = 6, + CAST_FPTRUNC = 7, + CAST_FPEXT = 8, + CAST_PTRTOINT = 9, + CAST_INTTOPTR = 10, + CAST_BITCAST = 11, + CAST_ADDRSPACECAST = 12 +}; + +/// BinaryOpcodes - These are values used in the bitcode files to encode which +/// binop a CST_CODE_CE_BINOP or a XXX refers to. The values of these enums +/// have no fixed relation to the LLVM IR enum values. Changing these will +/// break compatibility with old files. +enum BinaryOpcodes { + BINOP_ADD = 0, + BINOP_SUB = 1, + BINOP_MUL = 2, + BINOP_UDIV = 3, + BINOP_SDIV = 4, // overloaded for FP + BINOP_UREM = 5, + BINOP_SREM = 6, // overloaded for FP + BINOP_SHL = 7, + BINOP_LSHR = 8, + BINOP_ASHR = 9, + BINOP_AND = 10, + BINOP_OR = 11, + BINOP_XOR = 12 +}; + +/// These are values used in the bitcode files to encode AtomicRMW operations. +/// The values of these enums have no fixed relation to the LLVM IR enum +/// values. Changing these will break compatibility with old files. +enum RMWOperations { + RMW_XCHG = 0, + RMW_ADD = 1, + RMW_SUB = 2, + RMW_AND = 3, + RMW_NAND = 4, + RMW_OR = 5, + RMW_XOR = 6, + RMW_MAX = 7, + RMW_MIN = 8, + RMW_UMAX = 9, + RMW_UMIN = 10 +}; + +/// OverflowingBinaryOperatorOptionalFlags - Flags for serializing +/// OverflowingBinaryOperator's SubclassOptionalData contents. +enum OverflowingBinaryOperatorOptionalFlags { + OBO_NO_UNSIGNED_WRAP = 0, + OBO_NO_SIGNED_WRAP = 1 +}; + +/// PossiblyExactOperatorOptionalFlags - Flags for serializing +/// PossiblyExactOperator's SubclassOptionalData contents. +enum PossiblyExactOperatorOptionalFlags { PEO_EXACT = 0 }; + +/// Encoded AtomicOrdering values. +enum AtomicOrderingCodes { + ORDERING_NOTATOMIC = 0, + ORDERING_UNORDERED = 1, + ORDERING_MONOTONIC = 2, + ORDERING_ACQUIRE = 3, + ORDERING_RELEASE = 4, + ORDERING_ACQREL = 5, + ORDERING_SEQCST = 6 +}; + +/// Encoded SynchronizationScope values. +enum AtomicSynchScopeCodes { + SYNCHSCOPE_SINGLETHREAD = 0, + SYNCHSCOPE_CROSSTHREAD = 1 +}; + +/// Markers and flags for call instruction. +enum CallMarkersFlags { + CALL_TAIL = 0, + CALL_CCONV = 1, + CALL_MUSTTAIL = 14, + CALL_EXPLICIT_TYPE = 15, + CALL_NOTAIL = 16, + CALL_FMF = 17 // Call has optional fast-math-flags. +}; + +// The function body block (FUNCTION_BLOCK_ID) describes function bodies. It +// can contain a constant block (CONSTANTS_BLOCK_ID). +enum FunctionCodes { + FUNC_CODE_DECLAREBLOCKS = 1, // DECLAREBLOCKS: [n] + + FUNC_CODE_INST_BINOP = 2, // BINOP: [opcode, ty, opval, opval] + FUNC_CODE_INST_CAST = 3, // CAST: [opcode, ty, opty, opval] + FUNC_CODE_INST_GEP_OLD = 4, // GEP: [n x operands] + FUNC_CODE_INST_SELECT = 5, // SELECT: [ty, opval, opval, opval] + FUNC_CODE_INST_EXTRACTELT = 6, // EXTRACTELT: [opty, opval, opval] + FUNC_CODE_INST_INSERTELT = 7, // INSERTELT: [ty, opval, opval, opval] + FUNC_CODE_INST_SHUFFLEVEC = 8, // SHUFFLEVEC: [ty, opval, opval, opval] + FUNC_CODE_INST_CMP = 9, // CMP: [opty, opval, opval, pred] + + FUNC_CODE_INST_RET = 10, // RET: [opty,opval<both optional>] + FUNC_CODE_INST_BR = 11, // BR: [bb#, bb#, cond] or [bb#] + FUNC_CODE_INST_SWITCH = 12, // SWITCH: [opty, op0, op1, ...] + FUNC_CODE_INST_INVOKE = 13, // INVOKE: [attr, fnty, op0,op1, ...] + // 14 is unused. + FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE + + FUNC_CODE_INST_PHI = 16, // PHI: [ty, val0,bb0, ...] + // 17 is unused. + // 18 is unused. + FUNC_CODE_INST_ALLOCA = 19, // ALLOCA: [instty, opty, op, align] + FUNC_CODE_INST_LOAD = 20, // LOAD: [opty, op, align, vol] + // 21 is unused. + // 22 is unused. + FUNC_CODE_INST_VAARG = 23, // VAARG: [valistty, valist, instty] + // This store code encodes the pointer type, rather than the value type + // this is so information only available in the pointer type (e.g. address + // spaces) is retained. + FUNC_CODE_INST_STORE_OLD = 24, // STORE: [ptrty,ptr,val, align, vol] + // 25 is unused. + FUNC_CODE_INST_EXTRACTVAL = 26, // EXTRACTVAL: [n x operands] + FUNC_CODE_INST_INSERTVAL = 27, // INSERTVAL: [n x operands] + // fcmp/icmp returning Int1TY or vector of Int1Ty. Same as CMP, exists to + // support legacy vicmp/vfcmp instructions. + FUNC_CODE_INST_CMP2 = 28, // CMP2: [opty, opval, opval, pred] + // new select on i1 or [N x i1] + FUNC_CODE_INST_VSELECT = 29, // VSELECT: [ty,opval,opval,predty,pred] + FUNC_CODE_INST_INBOUNDS_GEP_OLD = 30, // INBOUNDS_GEP: [n x operands] + FUNC_CODE_INST_INDIRECTBR = 31, // INDIRECTBR: [opty, op0, op1, ...] + // 32 is unused. + FUNC_CODE_DEBUG_LOC_AGAIN = 33, // DEBUG_LOC_AGAIN + + FUNC_CODE_INST_CALL = 34, // CALL: [attr, cc, fnty, fnid, args...] + + FUNC_CODE_DEBUG_LOC = 35, // DEBUG_LOC: [Line,Col,ScopeVal, IAVal] + FUNC_CODE_INST_FENCE = 36, // FENCE: [ordering, synchscope] + FUNC_CODE_INST_CMPXCHG_OLD = 37, // CMPXCHG: [ptrty,ptr,cmp,new, align, vol, + // ordering, synchscope] + FUNC_CODE_INST_ATOMICRMW = 38, // ATOMICRMW: [ptrty,ptr,val, operation, + // align, vol, + // ordering, synchscope] + FUNC_CODE_INST_RESUME = 39, // RESUME: [opval] + FUNC_CODE_INST_LANDINGPAD_OLD = + 40, // LANDINGPAD: [ty,val,val,num,id0,val0...] + FUNC_CODE_INST_LOADATOMIC = 41, // LOAD: [opty, op, align, vol, + // ordering, synchscope] + FUNC_CODE_INST_STOREATOMIC_OLD = 42, // STORE: [ptrty,ptr,val, align, vol + // ordering, synchscope] + FUNC_CODE_INST_GEP = 43, // GEP: [inbounds, n x operands] + FUNC_CODE_INST_STORE = 44, // STORE: [ptrty,ptr,valty,val, align, vol] + FUNC_CODE_INST_STOREATOMIC = 45, // STORE: [ptrty,ptr,val, align, vol + FUNC_CODE_INST_CMPXCHG = 46, // CMPXCHG: [ptrty,ptr,valty,cmp,new, align, + // vol,ordering,synchscope] + FUNC_CODE_INST_LANDINGPAD = 47, // LANDINGPAD: [ty,val,num,id0,val0...] + FUNC_CODE_INST_CLEANUPRET = 48, // CLEANUPRET: [val] or [val,bb#] + FUNC_CODE_INST_CATCHRET = 49, // CATCHRET: [val,bb#] + FUNC_CODE_INST_CATCHPAD = 50, // CATCHPAD: [bb#,bb#,num,args...] + FUNC_CODE_INST_CLEANUPPAD = 51, // CLEANUPPAD: [num,args...] + FUNC_CODE_INST_CATCHSWITCH = + 52, // CATCHSWITCH: [num,args...] or [num,args...,bb] + // 53 is unused. + // 54 is unused. + FUNC_CODE_OPERAND_BUNDLE = 55, // OPERAND_BUNDLE: [tag#, value...] +}; + +enum UseListCodes { + USELIST_CODE_DEFAULT = 1, // DEFAULT: [index..., value-id] + USELIST_CODE_BB = 2 // BB: [index..., bb-id] +}; + +enum AttributeKindCodes { + // = 0 is unused + ATTR_KIND_ALIGNMENT = 1, + ATTR_KIND_ALWAYS_INLINE = 2, + ATTR_KIND_BY_VAL = 3, + ATTR_KIND_INLINE_HINT = 4, + ATTR_KIND_IN_REG = 5, + ATTR_KIND_MIN_SIZE = 6, + ATTR_KIND_NAKED = 7, + ATTR_KIND_NEST = 8, + ATTR_KIND_NO_ALIAS = 9, + ATTR_KIND_NO_BUILTIN = 10, + ATTR_KIND_NO_CAPTURE = 11, + ATTR_KIND_NO_DUPLICATE = 12, + ATTR_KIND_NO_IMPLICIT_FLOAT = 13, + ATTR_KIND_NO_INLINE = 14, + ATTR_KIND_NON_LAZY_BIND = 15, + ATTR_KIND_NO_RED_ZONE = 16, + ATTR_KIND_NO_RETURN = 17, + ATTR_KIND_NO_UNWIND = 18, + ATTR_KIND_OPTIMIZE_FOR_SIZE = 19, + ATTR_KIND_READ_NONE = 20, + ATTR_KIND_READ_ONLY = 21, + ATTR_KIND_RETURNED = 22, + ATTR_KIND_RETURNS_TWICE = 23, + ATTR_KIND_S_EXT = 24, + ATTR_KIND_STACK_ALIGNMENT = 25, + ATTR_KIND_STACK_PROTECT = 26, + ATTR_KIND_STACK_PROTECT_REQ = 27, + ATTR_KIND_STACK_PROTECT_STRONG = 28, + ATTR_KIND_STRUCT_RET = 29, + ATTR_KIND_SANITIZE_ADDRESS = 30, + ATTR_KIND_SANITIZE_THREAD = 31, + ATTR_KIND_SANITIZE_MEMORY = 32, + ATTR_KIND_UW_TABLE = 33, + ATTR_KIND_Z_EXT = 34, + ATTR_KIND_BUILTIN = 35, + ATTR_KIND_COLD = 36, + ATTR_KIND_OPTIMIZE_NONE = 37, + ATTR_KIND_IN_ALLOCA = 38, + ATTR_KIND_NON_NULL = 39, + ATTR_KIND_JUMP_TABLE = 40, + ATTR_KIND_DEREFERENCEABLE = 41, + ATTR_KIND_DEREFERENCEABLE_OR_NULL = 42, + ATTR_KIND_CONVERGENT = 43, + ATTR_KIND_SAFESTACK = 44, + ATTR_KIND_ARGMEMONLY = 45, + ATTR_KIND_SWIFT_SELF = 46, + ATTR_KIND_SWIFT_ERROR = 47, + ATTR_KIND_NO_RECURSE = 48, + ATTR_KIND_INACCESSIBLEMEM_ONLY = 49, + ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY = 50, + ATTR_KIND_ALLOC_SIZE = 51, + ATTR_KIND_WRITEONLY = 52 +}; + +enum ComdatSelectionKindCodes { + COMDAT_SELECTION_KIND_ANY = 1, + COMDAT_SELECTION_KIND_EXACT_MATCH = 2, + COMDAT_SELECTION_KIND_LARGEST = 3, + COMDAT_SELECTION_KIND_NO_DUPLICATES = 4, + COMDAT_SELECTION_KIND_SAME_SIZE = 5, +}; } // End bitc namespace } // End llvm namespace diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h index 60d865fd23555..76a60a0b8d25c 100644 --- a/include/llvm/Bitcode/ReaderWriter.h +++ b/include/llvm/Bitcode/ReaderWriter.h @@ -15,7 +15,7 @@ #define LLVM_BITCODE_READERWRITER_H #include "llvm/IR/DiagnosticInfo.h" -#include "llvm/IR/FunctionInfo.h" +#include "llvm/IR/ModuleSummaryIndex.h" #include "llvm/Support/Endian.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/MemoryBuffer.h" @@ -30,6 +30,14 @@ namespace llvm { class ModulePass; class raw_ostream; + /// Offsets of the 32-bit fields of bitcode wrapper header. + static const unsigned BWH_MagicField = 0*4; + static const unsigned BWH_VersionField = 1*4; + static const unsigned BWH_OffsetField = 2*4; + static const unsigned BWH_SizeField = 3*4; + static const unsigned BWH_CPUTypeField = 4*4; + static const unsigned BWH_HeaderSize = 5*4; + /// Read the header of the specified bitcode buffer and prepare for lazy /// deserialization of function bodies. If ShouldLazyLoadMetadata is true, /// lazily load metadata as well. If successful, this moves Buffer. On @@ -52,6 +60,11 @@ namespace llvm { std::string getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context); + /// Return true if \p Buffer contains a bitcode file with ObjC code (category + /// or class) in it. + bool isBitcodeContainingObjCCategory(MemoryBufferRef Buffer, + LLVMContext &Context); + /// Read the header of the specified bitcode buffer and extract just the /// producer string information. If successful, this returns a string. On /// error, this returns "". @@ -62,29 +75,15 @@ namespace llvm { ErrorOr<std::unique_ptr<Module>> parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context); - /// Check if the given bitcode buffer contains a function summary block. - bool hasFunctionSummary(MemoryBufferRef Buffer, - DiagnosticHandlerFunction DiagnosticHandler); - - /// Parse the specified bitcode buffer, returning the function info index. - /// If IsLazy is true, parse the entire function summary into - /// the index. Otherwise skip the function summary section, and only create - /// an index object with a map from function name to function summary offset. - /// The index is used to perform lazy function summary reading later. - ErrorOr<std::unique_ptr<FunctionInfoIndex>> - getFunctionInfoIndex(MemoryBufferRef Buffer, - DiagnosticHandlerFunction DiagnosticHandler, - bool IsLazy = false); - - /// This method supports lazy reading of function summary data from the - /// combined index during function importing. When reading the combined index - /// file, getFunctionInfoIndex is first invoked with IsLazy=true. - /// Then this method is called for each function considered for importing, - /// to parse the summary information for the given function name into - /// the index. - std::error_code readFunctionSummary( - MemoryBufferRef Buffer, DiagnosticHandlerFunction DiagnosticHandler, - StringRef FunctionName, std::unique_ptr<FunctionInfoIndex> Index); + /// Check if the given bitcode buffer contains a summary block. + bool + hasGlobalValueSummary(MemoryBufferRef Buffer, + const DiagnosticHandlerFunction &DiagnosticHandler); + + /// Parse the specified bitcode buffer, returning the module summary index. + ErrorOr<std::unique_ptr<ModuleSummaryIndex>> + getModuleSummaryIndex(MemoryBufferRef Buffer, + const DiagnosticHandlerFunction &DiagnosticHandler); /// \brief Write the specified module to the specified raw output stream. /// @@ -95,17 +94,21 @@ namespace llvm { /// Value in \c M. These will be reconstructed exactly when \a M is /// deserialized. /// - /// If \c EmitFunctionSummary, emit the function summary index (currently + /// If \c EmitSummaryIndex, emit the module's summary index (currently /// for use in ThinLTO optimization). void WriteBitcodeToFile(const Module *M, raw_ostream &Out, bool ShouldPreserveUseListOrder = false, - bool EmitFunctionSummary = false); + const ModuleSummaryIndex *Index = nullptr, + bool GenerateHash = false); - /// Write the specified function summary index to the given raw output stream, + /// Write the specified module summary index to the given raw output stream, /// where it will be written in a new bitcode block. This is used when - /// writing the combined index file for ThinLTO. - void WriteFunctionSummaryToFile(const FunctionInfoIndex &Index, - raw_ostream &Out); + /// writing the combined index file for ThinLTO. When writing a subset of the + /// index for a distributed backend, provide the \p ModuleToSummariesForIndex + /// map. + void WriteIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out, + std::map<std::string, GVSummaryMapTy> + *ModuleToSummariesForIndex = nullptr); /// isBitcodeWrapper - Return true if the given bytes are the magic bytes /// for an LLVM IR bitcode wrapper. @@ -163,20 +166,16 @@ namespace llvm { inline bool SkipBitcodeWrapperHeader(const unsigned char *&BufPtr, const unsigned char *&BufEnd, bool VerifyBufferSize) { - enum { - KnownHeaderSize = 4*4, // Size of header we read. - OffsetField = 2*4, // Offset in bytes to Offset field. - SizeField = 3*4 // Offset in bytes to Size field. - }; - - // Must contain the header! - if (BufEnd-BufPtr < KnownHeaderSize) return true; + // Must contain the offset and size field! + if (unsigned(BufEnd - BufPtr) < BWH_SizeField + 4) + return true; - unsigned Offset = support::endian::read32le(&BufPtr[OffsetField]); - unsigned Size = support::endian::read32le(&BufPtr[SizeField]); + unsigned Offset = support::endian::read32le(&BufPtr[BWH_OffsetField]); + unsigned Size = support::endian::read32le(&BufPtr[BWH_SizeField]); + uint64_t BitcodeOffsetEnd = (uint64_t)Offset + (uint64_t)Size; // Verify that Offset+Size fits in the file. - if (VerifyBufferSize && Offset+Size > unsigned(BufEnd-BufPtr)) + if (VerifyBufferSize && BitcodeOffsetEnd > uint64_t(BufEnd-BufPtr)) return true; BufPtr += Offset; BufEnd = BufPtr+Size; |