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
This commit is contained in:
Teresa Johnson 2015-11-15 02:00:09 +00:00
parent 1fbb445098
commit 778af35f66
4 changed files with 74 additions and 12 deletions

View File

@ -50,7 +50,9 @@ enum BlockIDs {
MODULE_STRTAB_BLOCK_ID, MODULE_STRTAB_BLOCK_ID,
FUNCTION_SUMMARY_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, /// Identification block contains a string that describes the producer details,

View File

@ -405,6 +405,8 @@ private:
std::error_code globalCleanup(); std::error_code globalCleanup();
std::error_code resolveGlobalAndAliasInits(); std::error_code resolveGlobalAndAliasInits();
std::error_code parseMetadata(); std::error_code parseMetadata();
std::error_code parseMetadataKinds();
std::error_code parseMetadataKindRecord(SmallVectorImpl<uint64_t> &Record);
std::error_code parseMetadataAttachment(Function &F); std::error_code parseMetadataAttachment(Function &F);
ErrorOr<std::string> parseModuleTriple(); ErrorOr<std::string> parseModuleTriple();
std::error_code parseUseLists(); 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<uint64_t> &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; } static int64_t unrotateSign(uint64_t U) { return U & 1 ? ~(U >> 1) : U >> 1; }
std::error_code BitcodeReader::parseMetadata() { std::error_code BitcodeReader::parseMetadata() {
@ -2351,15 +2368,10 @@ std::error_code BitcodeReader::parseMetadata() {
break; break;
} }
case bitc::METADATA_KIND: { case bitc::METADATA_KIND: {
if (Record.size() < 2) // Support older bitcode files that had METADATA_KIND records in a
return error("Invalid record"); // block with METADATA_BLOCK_ID.
if (std::error_code EC = parseMetadataKindRecord(Record))
unsigned Kind = Record[0]; return EC;
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");
break; break;
} }
} }
@ -2367,6 +2379,43 @@ std::error_code BitcodeReader::parseMetadata() {
#undef GET_OR_DISTINCT #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");
SmallVector<uint64_t, 64> Record;
// Read all the records.
while (1) {
BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
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;
}
}
}
}
/// Decode a signed value stored with the sign bit in the LSB for dense VBR /// Decode a signed value stored with the sign bit in the LSB for dense VBR
/// encoding. /// encoding.
uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) { uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) {
@ -3229,6 +3278,10 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
if (std::error_code EC = parseMetadata()) if (std::error_code EC = parseMetadata())
return EC; return EC;
break; break;
case bitc::METADATA_KIND_BLOCK_ID:
if (std::error_code EC = parseMetadataKinds())
return EC;
break;
case bitc::FUNCTION_BLOCK_ID: case bitc::FUNCTION_BLOCK_ID:
// If this is the first function body we've seen, reverse the // If this is the first function body we've seen, reverse the
// FunctionsWithBodies list. // FunctionsWithBodies list.

View File

@ -1383,7 +1383,7 @@ static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) {
if (Names.empty()) return; 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) { for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) {
Record.push_back(MDKindID); Record.push_back(MDKindID);

View File

@ -114,6 +114,7 @@ static const char *GetBlockName(unsigned BlockID,
return "IDENTIFICATION_BLOCK_ID"; return "IDENTIFICATION_BLOCK_ID";
case bitc::VALUE_SYMTAB_BLOCK_ID: return "VALUE_SYMTAB"; case bitc::VALUE_SYMTAB_BLOCK_ID: return "VALUE_SYMTAB";
case bitc::METADATA_BLOCK_ID: return "METADATA_BLOCK"; 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::METADATA_ATTACHMENT_ID: return "METADATA_ATTACHMENT_BLOCK";
case bitc::USELIST_BLOCK_ID: return "USELIST_BLOCK_ID"; case bitc::USELIST_BLOCK_ID: return "USELIST_BLOCK_ID";
case bitc::FUNCTION_SUMMARY_BLOCK_ID: case bitc::FUNCTION_SUMMARY_BLOCK_ID:
@ -305,7 +306,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
default:return nullptr; default:return nullptr;
STRINGIFY_CODE(METADATA, STRING) STRINGIFY_CODE(METADATA, STRING)
STRINGIFY_CODE(METADATA, NAME) 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, NODE)
STRINGIFY_CODE(METADATA, VALUE) STRINGIFY_CODE(METADATA, VALUE)
STRINGIFY_CODE(METADATA, OLD_NODE) 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, IMPORTED_ENTITY)
STRINGIFY_CODE(METADATA, MODULE) STRINGIFY_CODE(METADATA, MODULE)
} }
case bitc::METADATA_KIND_BLOCK_ID:
switch (CodeID) {
default:
return nullptr;
STRINGIFY_CODE(METADATA, KIND)
}
case bitc::USELIST_BLOCK_ID: case bitc::USELIST_BLOCK_ID:
switch(CodeID) { switch(CodeID) {
default:return nullptr; default:return nullptr;