diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
commit | dd58ef019b700900793a1eb48b52123db01b654e (patch) | |
tree | fcfbb4df56a744f4ddc6122c50521dd3f1c5e196 /include/llvm/Bitcode | |
parent | 2fe5752e3a7c345cdb59e869278d36af33c13fa4 (diff) |
Notes
Diffstat (limited to 'include/llvm/Bitcode')
-rw-r--r-- | include/llvm/Bitcode/BitcodeWriterPass.h | 16 | ||||
-rw-r--r-- | include/llvm/Bitcode/BitstreamReader.h | 2 | ||||
-rw-r--r-- | include/llvm/Bitcode/BitstreamWriter.h | 125 | ||||
-rw-r--r-- | include/llvm/Bitcode/LLVMBitCodes.h | 122 | ||||
-rw-r--r-- | include/llvm/Bitcode/ReaderWriter.h | 64 |
5 files changed, 240 insertions, 89 deletions
diff --git a/include/llvm/Bitcode/BitcodeWriterPass.h b/include/llvm/Bitcode/BitcodeWriterPass.h index ae915c688ba0..a1272cf156e5 100644 --- a/include/llvm/Bitcode/BitcodeWriterPass.h +++ b/include/llvm/Bitcode/BitcodeWriterPass.h @@ -29,8 +29,12 @@ 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). ModulePass *createBitcodeWriterPass(raw_ostream &Str, - bool ShouldPreserveUseListOrder = false); + bool ShouldPreserveUseListOrder = false, + bool EmitFunctionSummary = false); /// \brief Pass for writing a module of IR out to a bitcode file. /// @@ -39,15 +43,21 @@ ModulePass *createBitcodeWriterPass(raw_ostream &Str, class BitcodeWriterPass { raw_ostream &OS; bool ShouldPreserveUseListOrder; + bool EmitFunctionSummary; public: /// \brief Construct a bitcode writer pass around a particular output stream. /// /// 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). explicit BitcodeWriterPass(raw_ostream &OS, - bool ShouldPreserveUseListOrder = false) - : OS(OS), ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {} + bool ShouldPreserveUseListOrder = false, + bool EmitFunctionSummary = false) + : OS(OS), ShouldPreserveUseListOrder(ShouldPreserveUseListOrder), + EmitFunctionSummary(EmitFunctionSummary) {} /// \brief Run the bitcode writer pass, and output the module to the selected /// output stream. diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h index 4c040a7f3e22..c0cf6cde887f 100644 --- a/include/llvm/Bitcode/BitstreamReader.h +++ b/include/llvm/Bitcode/BitstreamReader.h @@ -325,6 +325,8 @@ public: // If we run out of data, stop at the end of the stream. if (BytesRead == 0) { + CurWord = 0; + BitsInCurWord = 0; Size = NextChar; return; } diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h index 9f23023a1419..438f4a6fb69b 100644 --- a/include/llvm/Bitcode/BitstreamWriter.h +++ b/include/llvm/Bitcode/BitstreamWriter.h @@ -15,6 +15,8 @@ #ifndef LLVM_BITCODE_BITSTREAMWRITER_H #define LLVM_BITCODE_BITSTREAMWRITER_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Bitcode/BitCodes.h" @@ -45,9 +47,9 @@ class BitstreamWriter { struct Block { unsigned PrevCodeSize; - unsigned StartSizeWord; + size_t StartSizeWord; std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> PrevAbbrevs; - Block(unsigned PCS, unsigned SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {} + Block(unsigned PCS, size_t SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {} }; /// BlockScope - This tracks the current blocks that we have entered. @@ -61,12 +63,6 @@ class BitstreamWriter { }; std::vector<BlockInfo> BlockInfoRecords; - // BackpatchWord - Backpatch a 32-bit word in the output with the specified - // value. - void BackpatchWord(unsigned ByteNo, unsigned NewWord) { - support::endian::write32le(&Out[ByteNo], NewWord); - } - void WriteByte(unsigned char Value) { Out.push_back(Value); } @@ -77,12 +73,10 @@ class BitstreamWriter { reinterpret_cast<const char *>(&Value + 1)); } - unsigned GetBufferOffset() const { - return Out.size(); - } + size_t GetBufferOffset() const { return Out.size(); } - unsigned GetWordIndex() const { - unsigned Offset = GetBufferOffset(); + size_t GetWordIndex() const { + size_t Offset = GetBufferOffset(); assert((Offset & 3) == 0 && "Not 32-bit aligned"); return Offset / 4; } @@ -99,10 +93,25 @@ public: /// \brief Retrieve the current position in the stream, in bits. uint64_t GetCurrentBitNo() const { return GetBufferOffset() * 8 + CurBit; } + /// \brief Retrieve the number of bits currently used to encode an abbrev ID. + unsigned GetAbbrevIDWidth() const { return CurCodeSize; } + //===--------------------------------------------------------------------===// // Basic Primitives for emitting bits to the stream. //===--------------------------------------------------------------------===// + /// Backpatch a 32-bit word in the output at the given bit offset + /// with the specified value. + void BackpatchWord(uint64_t BitNo, unsigned NewWord) { + using namespace llvm::support; + unsigned ByteNo = BitNo / 8; + assert((!endian::readAtBitAlignment<uint32_t, little, unaligned>( + &Out[ByteNo], BitNo & 7)) && + "Expected to be patching over 0-value placeholders"); + endian::writeAtBitAlignment<uint32_t, little, unaligned>( + &Out[ByteNo], NewWord, BitNo & 7); + } + void Emit(uint32_t Val, unsigned NumBits) { assert(NumBits && NumBits <= 32 && "Invalid value size!"); assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!"); @@ -200,7 +209,7 @@ public: EmitVBR(CodeLen, bitc::CodeLenWidth); FlushToWord(); - unsigned BlockSizeWordIndex = GetWordIndex(); + size_t BlockSizeWordIndex = GetWordIndex(); unsigned OldCodeSize = CurCodeSize; // Emit a placeholder, which will be replaced when the block is popped. @@ -231,11 +240,11 @@ public: FlushToWord(); // Compute the size of the block, in words, not counting the size field. - unsigned SizeInWords = GetWordIndex() - B.StartSizeWord - 1; - unsigned ByteNo = B.StartSizeWord*4; + size_t SizeInWords = GetWordIndex() - B.StartSizeWord - 1; + uint64_t BitNo = uint64_t(B.StartSizeWord) * 32; // Update the block size field in the header of this sub-block. - BackpatchWord(ByteNo, SizeInWords); + BackpatchWord(BitNo, SizeInWords); // Restore the inner block's code size and abbrev table. CurCodeSize = B.PrevCodeSize; @@ -285,10 +294,12 @@ private: /// EmitRecordWithAbbrevImpl - This is the core implementation of the record /// emission code. If BlobData is non-null, then it specifies an array of /// data that should be emitted as part of the Blob or Array operand that is - /// known to exist at the end of the record. - template<typename uintty> - void EmitRecordWithAbbrevImpl(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, - StringRef Blob) { + /// known to exist at the end of the record. If Code is specified, then + /// it is the record code to emit before the Vals, which must not contain + /// the code. + template <typename uintty> + void EmitRecordWithAbbrevImpl(unsigned Abbrev, ArrayRef<uintty> Vals, + StringRef Blob, Optional<unsigned> Code) { const char *BlobData = Blob.data(); unsigned BlobLen = (unsigned) Blob.size(); unsigned AbbrevNo = Abbrev-bitc::FIRST_APPLICATION_ABBREV; @@ -297,9 +308,23 @@ private: EmitCode(Abbrev); + unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos()); + if (Code) { + assert(e && "Expected non-empty abbreviation"); + const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i++); + + if (Op.isLiteral()) + EmitAbbreviatedLiteral(Op, Code.getValue()); + else { + assert(Op.getEncoding() != BitCodeAbbrevOp::Array && + Op.getEncoding() != BitCodeAbbrevOp::Blob && + "Expected literal or scalar"); + EmitAbbreviatedField(Op, Code.getValue()); + } + } + unsigned RecordIdx = 0; - for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos()); - i != e; ++i) { + for (; i != e; ++i) { const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); if (Op.isLiteral()) { assert(RecordIdx < Vals.size() && "Invalid abbrev/record"); @@ -307,7 +332,7 @@ private: ++RecordIdx; } else if (Op.getEncoding() == BitCodeAbbrevOp::Array) { // Array case. - assert(i+2 == e && "array op not second to last?"); + assert(i + 2 == e && "array op not second to last?"); const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); // If this record has blob data, emit it, otherwise we must have record @@ -381,32 +406,29 @@ public: /// EmitRecord - Emit the specified record to the stream, using an abbrev if /// we have one to compress the output. - template<typename uintty> - void EmitRecord(unsigned Code, SmallVectorImpl<uintty> &Vals, - unsigned Abbrev = 0) { + template <typename Container> + void EmitRecord(unsigned Code, const Container &Vals, unsigned Abbrev = 0) { if (!Abbrev) { // If we don't have an abbrev to use, emit this in its fully unabbreviated // form. + auto Count = static_cast<uint32_t>(makeArrayRef(Vals).size()); EmitCode(bitc::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) + EmitVBR(Count, 6); + for (unsigned i = 0, e = Count; i != e; ++i) EmitVBR64(Vals[i], 6); return; } - // Insert the code into Vals to treat it uniformly. - Vals.insert(Vals.begin(), Code); - - EmitRecordWithAbbrev(Abbrev, Vals); + EmitRecordWithAbbrevImpl(Abbrev, makeArrayRef(Vals), StringRef(), Code); } /// EmitRecordWithAbbrev - Emit a record with the specified abbreviation. /// Unlike EmitRecord, the code for the record should be included in Vals as /// the first entry. - template<typename uintty> - void EmitRecordWithAbbrev(unsigned Abbrev, SmallVectorImpl<uintty> &Vals) { - EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef()); + template <typename Container> + void EmitRecordWithAbbrev(unsigned Abbrev, const Container &Vals) { + EmitRecordWithAbbrevImpl(Abbrev, makeArrayRef(Vals), StringRef(), None); } /// EmitRecordWithBlob - Emit the specified record to the stream, using an @@ -414,29 +436,30 @@ public: /// specified by the pointer and length specified at the end. In contrast to /// EmitRecord, this routine expects that the first entry in Vals is the code /// of the record. - template<typename uintty> - void EmitRecordWithBlob(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, + template <typename Container> + void EmitRecordWithBlob(unsigned Abbrev, const Container &Vals, StringRef Blob) { - EmitRecordWithAbbrevImpl(Abbrev, Vals, Blob); + EmitRecordWithAbbrevImpl(Abbrev, makeArrayRef(Vals), Blob, None); } - template<typename uintty> - void EmitRecordWithBlob(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, + template <typename Container> + void EmitRecordWithBlob(unsigned Abbrev, const Container &Vals, const char *BlobData, unsigned BlobLen) { - return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(BlobData, BlobLen)); + return EmitRecordWithAbbrevImpl(Abbrev, makeArrayRef(Vals), + StringRef(BlobData, BlobLen), None); } /// EmitRecordWithArray - Just like EmitRecordWithBlob, works with records /// that end with an array. - template<typename uintty> - void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, - StringRef Array) { - EmitRecordWithAbbrevImpl(Abbrev, Vals, Array); + template <typename Container> + void EmitRecordWithArray(unsigned Abbrev, const Container &Vals, + StringRef Array) { + EmitRecordWithAbbrevImpl(Abbrev, makeArrayRef(Vals), Array, None); } - template<typename uintty> - void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, - const char *ArrayData, unsigned ArrayLen) { - return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(ArrayData, - ArrayLen)); + template <typename Container> + void EmitRecordWithArray(unsigned Abbrev, const Container &Vals, + const char *ArrayData, unsigned ArrayLen) { + return EmitRecordWithAbbrevImpl(Abbrev, makeArrayRef(Vals), + StringRef(ArrayData, ArrayLen), None); } //===--------------------------------------------------------------------===// diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index 7130ee755237..bcc84bedbed0 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -23,28 +23,52 @@ namespace llvm { namespace bitc { // The only top-level block type defined is for a module. - enum BlockIDs { - // Blocks - MODULE_BLOCK_ID = FIRST_APPLICATION_BLOCKID, +enum BlockIDs { + // Blocks + MODULE_BLOCK_ID = FIRST_APPLICATION_BLOCKID, - // Module sub-block id's. - PARAMATTR_BLOCK_ID, - PARAMATTR_GROUP_BLOCK_ID, + // Module sub-block id's. + PARAMATTR_BLOCK_ID, + PARAMATTR_GROUP_BLOCK_ID, - CONSTANTS_BLOCK_ID, - FUNCTION_BLOCK_ID, + CONSTANTS_BLOCK_ID, + FUNCTION_BLOCK_ID, - UNUSED_ID1, + // Block intended to contains information on the bitcode versioning. + // Can be used to provide better error messages when we fail to parse a + // bitcode file. + IDENTIFICATION_BLOCK_ID, - VALUE_SYMTAB_BLOCK_ID, - METADATA_BLOCK_ID, - METADATA_ATTACHMENT_ID, + VALUE_SYMTAB_BLOCK_ID, + METADATA_BLOCK_ID, + METADATA_ATTACHMENT_ID, - TYPE_BLOCK_ID_NEW, + TYPE_BLOCK_ID_NEW, - USELIST_BLOCK_ID - }; + USELIST_BLOCK_ID, + + MODULE_STRTAB_BLOCK_ID, + FUNCTION_SUMMARY_BLOCK_ID, + + OPERAND_BUNDLE_TAGS_BLOCK_ID, + + METADATA_KIND_BLOCK_ID +}; + +/// Identification block contains a string that describes the producer details, +/// and an epoch that defines the auto-upgrade capability. +enum IdentificationCodes { + IDENTIFICATION_CODE_STRING = 1, // IDENTIFICATION: [strchr x N] + IDENTIFICATION_CODE_EPOCH = 2, // EPOCH: [epoch#] +}; +/// The epoch that defines the auto-upgrade compatibility for the bitcode. +/// +/// LLVM guarantees in a major release that a minor release can read bitcode +/// generated by previous minor releases. We translate this by making the reader +/// accepting only bitcode with the same epoch, except for the X.0 release which +/// also accepts N-1. +enum { BITCODE_CURRENT_EPOCH = 0 }; /// MODULE blocks have a number of optional fields and subblocks. enum ModuleCodes { @@ -66,13 +90,21 @@ namespace bitc { MODULE_CODE_FUNCTION = 8, // ALIAS: [alias type, aliasee val#, linkage, visibility] - MODULE_CODE_ALIAS = 9, + 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. @@ -121,7 +153,13 @@ namespace bitc { 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_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). @@ -129,10 +167,25 @@ namespace bitc { TST_CODE_ENTRY = 1 // TST_ENTRY: [typeid, namechar x N] }; - // The value symbol table only has one code (VST_ENTRY_CODE). + // Value symbol table codes. enum ValueSymtabCodes { - VST_CODE_ENTRY = 1, // VST_ENTRY: [valid, namechar x N] - VST_CODE_BBENTRY = 2 // VST_BBENTRY: [bbid, namechar x N] + 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 { @@ -167,7 +220,9 @@ namespace bitc { 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_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 @@ -287,6 +342,16 @@ namespace bitc { 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 { @@ -354,6 +419,14 @@ namespace bitc { 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 { @@ -407,7 +480,12 @@ namespace bitc { ATTR_KIND_DEREFERENCEABLE_OR_NULL = 42, ATTR_KIND_CONVERGENT = 43, ATTR_KIND_SAFESTACK = 44, - ATTR_KIND_ARGMEMONLY = 45 + 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 { diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h index 452ec3bd0187..60d865fd2355 100644 --- a/include/llvm/Bitcode/ReaderWriter.h +++ b/include/llvm/Bitcode/ReaderWriter.h @@ -15,6 +15,7 @@ #define LLVM_BITCODE_READERWRITER_H #include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/FunctionInfo.h" #include "llvm/Support/Endian.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/MemoryBuffer.h" @@ -36,27 +37,54 @@ namespace llvm { ErrorOr<std::unique_ptr<Module>> getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer, LLVMContext &Context, - DiagnosticHandlerFunction DiagnosticHandler = nullptr, bool ShouldLazyLoadMetadata = false); /// Read the header of the specified stream and prepare for lazy /// deserialization and streaming of function bodies. - ErrorOr<std::unique_ptr<Module>> getStreamedBitcodeModule( - StringRef Name, std::unique_ptr<DataStreamer> Streamer, - LLVMContext &Context, - DiagnosticHandlerFunction DiagnosticHandler = nullptr); + ErrorOr<std::unique_ptr<Module>> + getStreamedBitcodeModule(StringRef Name, + std::unique_ptr<DataStreamer> Streamer, + LLVMContext &Context); /// Read the header of the specified bitcode buffer and extract just the /// triple information. If successful, this returns a string. On error, this /// returns "". - std::string - getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context, - DiagnosticHandlerFunction DiagnosticHandler = nullptr); + std::string getBitcodeTargetTriple(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 "". + std::string getBitcodeProducerString(MemoryBufferRef Buffer, + LLVMContext &Context); /// Read the specified bitcode file, returning the module. - ErrorOr<std::unique_ptr<Module>> - parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context, - DiagnosticHandlerFunction DiagnosticHandler = nullptr); + 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); /// \brief Write the specified module to the specified raw output stream. /// @@ -66,8 +94,18 @@ namespace llvm { /// If \c ShouldPreserveUseListOrder, encode the use-list order for each \a /// Value in \c M. These will be reconstructed exactly when \a M is /// deserialized. + /// + /// If \c EmitFunctionSummary, emit the function summary index (currently + /// for use in ThinLTO optimization). void WriteBitcodeToFile(const Module *M, raw_ostream &Out, - bool ShouldPreserveUseListOrder = false); + bool ShouldPreserveUseListOrder = false, + bool EmitFunctionSummary = false); + + /// Write the specified function 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); /// isBitcodeWrapper - Return true if the given bytes are the magic bytes /// for an LLVM IR bitcode wrapper. @@ -159,7 +197,7 @@ namespace llvm { BitcodeDiagnosticInfo(std::error_code EC, DiagnosticSeverity Severity, const Twine &Msg); void print(DiagnosticPrinter &DP) const override; - std::error_code getError() const { return EC; }; + std::error_code getError() const { return EC; } static bool classof(const DiagnosticInfo *DI) { return DI->getKind() == DK_Bitcode; |