From 778af35f6634f4fbd1da65dc9cf680e4a50d0597 Mon Sep 17 00:00:00 2001 From: Teresa Johnson Date: Sun, 15 Nov 2015 02:00:09 +0000 Subject: [PATCH] Use a different block id for block of metadata kind records Summary: There are currently two blocks with the METADATA_BLOCK id at module scope. The first has the module-level metadata values (consisting of some combination of METADATA_* record codes except for METADATA_KIND). The second consists only of METADATA_KIND records. The latter is used only in the METADATA_ATTACHMENT block within function blocks (for metadata attached to instructions). For ThinLTO we want to delay the parsing of module level metadata until all functions have been imported from that module (there is some bookkeeping used to suture it up when we read it during a post-pass). However, we do need the METADATA_KIND records when parsing the function body during importing, since those kinds are used as described above. To simplify identification and parsing of just the block containing the metadata kinds, use a different block id (METADATA_KIND_BLOCK_ID). Support older bitcode without the new block id as well. Reviewers: dexonsmith, joker.eph Subscribers: davidxl, llvm-commits Differential Revision: http://reviews.llvm.org/D14654 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253154 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Bitcode/LLVMBitCodes.h | 4 +- lib/Bitcode/Reader/BitcodeReader.cpp | 69 ++++++++++++++++++++--- lib/Bitcode/Writer/BitcodeWriter.cpp | 2 +- tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp | 9 ++- 4 files changed, 73 insertions(+), 11 deletions(-) diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index ad24d357065..efce0fbcd80 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -50,7 +50,9 @@ enum BlockIDs { MODULE_STRTAB_BLOCK_ID, FUNCTION_SUMMARY_BLOCK_ID, - OPERAND_BUNDLE_TAGS_BLOCK_ID + OPERAND_BUNDLE_TAGS_BLOCK_ID, + + METADATA_KIND_BLOCK_ID }; /// Identification block contains a string that describes the producer details, diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 7e760e25784..3a2d5be21db 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -405,6 +405,8 @@ private: std::error_code globalCleanup(); std::error_code resolveGlobalAndAliasInits(); std::error_code parseMetadata(); + std::error_code parseMetadataKinds(); + std::error_code parseMetadataKindRecord(SmallVectorImpl &Record); std::error_code parseMetadataAttachment(Function &F); ErrorOr parseModuleTriple(); std::error_code parseUseLists(); @@ -1893,6 +1895,21 @@ std::error_code BitcodeReader::parseValueSymbolTable(uint64_t Offset) { } } +/// Parse a single METADATA_KIND record, inserting result in MDKindMap. +std::error_code +BitcodeReader::parseMetadataKindRecord(SmallVectorImpl &Record) { + if (Record.size() < 2) + return error("Invalid record"); + + unsigned Kind = Record[0]; + SmallString<8> Name(Record.begin() + 1, Record.end()); + + unsigned NewKind = TheModule->getMDKindID(Name.str()); + if (!MDKindMap.insert(std::make_pair(Kind, NewKind)).second) + return error("Conflicting METADATA_KIND records"); + return std::error_code(); +} + static int64_t unrotateSign(uint64_t U) { return U & 1 ? ~(U >> 1) : U >> 1; } std::error_code BitcodeReader::parseMetadata() { @@ -2351,20 +2368,52 @@ std::error_code BitcodeReader::parseMetadata() { break; } case bitc::METADATA_KIND: { - if (Record.size() < 2) - return error("Invalid record"); + // Support older bitcode files that had METADATA_KIND records in a + // block with METADATA_BLOCK_ID. + if (std::error_code EC = parseMetadataKindRecord(Record)) + return EC; + break; + } + } + } +#undef GET_OR_DISTINCT +} + +/// Parse the metadata kinds out of the METADATA_KIND_BLOCK. +std::error_code BitcodeReader::parseMetadataKinds() { + if (Stream.EnterSubBlock(bitc::METADATA_KIND_BLOCK_ID)) + return error("Invalid record"); - unsigned Kind = Record[0]; - SmallString<8> Name(Record.begin()+1, Record.end()); + SmallVector Record; + + // Read all the records. + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); - unsigned NewKind = TheModule->getMDKindID(Name.str()); - if (!MDKindMap.insert(std::make_pair(Kind, NewKind)).second) - return error("Conflicting METADATA_KIND records"); + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return std::error_code(); + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + Record.clear(); + unsigned Code = Stream.readRecord(Entry.ID, Record); + switch (Code) { + default: // Default behavior: ignore. + break; + case bitc::METADATA_KIND: { + if (std::error_code EC = parseMetadataKindRecord(Record)) + return EC; break; } } } -#undef GET_OR_DISTINCT } /// Decode a signed value stored with the sign bit in the LSB for dense VBR @@ -3229,6 +3278,10 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit, if (std::error_code EC = parseMetadata()) return EC; break; + case bitc::METADATA_KIND_BLOCK_ID: + if (std::error_code EC = parseMetadataKinds()) + return EC; + break; case bitc::FUNCTION_BLOCK_ID: // If this is the first function body we've seen, reverse the // FunctionsWithBodies list. diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 62a99c7014b..7586112325e 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1383,7 +1383,7 @@ static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) { if (Names.empty()) return; - Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); + Stream.EnterSubblock(bitc::METADATA_KIND_BLOCK_ID, 3); for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) { Record.push_back(MDKindID); diff --git a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp index 3c82779ab1e..c460eb534cd 100644 --- a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp +++ b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp @@ -114,6 +114,7 @@ static const char *GetBlockName(unsigned BlockID, return "IDENTIFICATION_BLOCK_ID"; case bitc::VALUE_SYMTAB_BLOCK_ID: return "VALUE_SYMTAB"; case bitc::METADATA_BLOCK_ID: return "METADATA_BLOCK"; + case bitc::METADATA_KIND_BLOCK_ID: return "METADATA_KIND_BLOCK"; case bitc::METADATA_ATTACHMENT_ID: return "METADATA_ATTACHMENT_BLOCK"; case bitc::USELIST_BLOCK_ID: return "USELIST_BLOCK_ID"; case bitc::FUNCTION_SUMMARY_BLOCK_ID: @@ -305,7 +306,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID, default:return nullptr; STRINGIFY_CODE(METADATA, STRING) STRINGIFY_CODE(METADATA, NAME) - STRINGIFY_CODE(METADATA, KIND) + STRINGIFY_CODE(METADATA, KIND) // Older bitcode has it in a MODULE_BLOCK STRINGIFY_CODE(METADATA, NODE) STRINGIFY_CODE(METADATA, VALUE) STRINGIFY_CODE(METADATA, OLD_NODE) @@ -335,6 +336,12 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID, STRINGIFY_CODE(METADATA, IMPORTED_ENTITY) STRINGIFY_CODE(METADATA, MODULE) } + case bitc::METADATA_KIND_BLOCK_ID: + switch (CodeID) { + default: + return nullptr; + STRINGIFY_CODE(METADATA, KIND) + } case bitc::USELIST_BLOCK_ID: switch(CodeID) { default:return nullptr; -- 2.34.1