IR: Add assembly/bitcode support for function metadata attachments

Add serialization support for function metadata attachments (added in
r235783).  The syntax is:

    define @foo() !attach !0 {

Metadata attachments are only allowed on functions with bodies.  Since
they come before the `{`, they're not really part of the body; since
they require a body, they're not really part of the header.  In
`LLParser` I gave them a separate function called from `ParseDefine()`,
`ParseOptionalFunctionMetadata()`.

In bitcode, I'm using the same `METADATA_ATTACHMENT` record used by
instructions.  Instruction metadata attachments are included in a
special "attachment" block at the end of a `Function`.  The attachment
records are laid out like this:

    InstID (KindID MetadataID)+

Note that these records always have an odd number of fields.  The new
code takes advantage of this to recognize function attachments (which
don't need an instruction ID):

    (KindID MetadataID)+

This means we can use the same attachment block already used for
instructions.

This is part of PR23340.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235785 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith
2015-04-24 22:04:41 +00:00
parent ef477f3580
commit ae3211466a
7 changed files with 76 additions and 9 deletions

View File

@ -370,7 +370,7 @@ private:
std::error_code GlobalCleanup();
std::error_code ResolveGlobalAndAliasInits();
std::error_code ParseMetadata();
std::error_code ParseMetadataAttachment();
std::error_code ParseMetadataAttachment(Function &F);
ErrorOr<std::string> parseModuleTriple();
std::error_code ParseUseLists();
std::error_code InitStream();
@ -3215,7 +3215,7 @@ ErrorOr<std::string> BitcodeReader::parseTriple() {
}
/// ParseMetadataAttachment - Parse metadata attachments.
std::error_code BitcodeReader::ParseMetadataAttachment() {
std::error_code BitcodeReader::ParseMetadataAttachment(Function &F) {
if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
return Error("Invalid record");
@ -3241,8 +3241,21 @@ std::error_code BitcodeReader::ParseMetadataAttachment() {
break;
case bitc::METADATA_ATTACHMENT: {
unsigned RecordLength = Record.size();
if (Record.empty() || (RecordLength - 1) % 2 == 1)
if (Record.empty())
return Error("Invalid record");
if (RecordLength % 2 == 0) {
// A function attachment.
for (unsigned I = 0; I != RecordLength; I += 2) {
auto K = MDKindMap.find(Record[I]);
if (K == MDKindMap.end())
return Error("Invalid ID");
Metadata *MD = MDValueList.getValueFwdRef(Record[I + 1]);
F.setMetadata(K->second, cast<MDNode>(MD));
}
continue;
}
// An instruction attachment.
Instruction *Inst = InstructionList[Record[0]];
for (unsigned i = 1; i != RecordLength; i = i+2) {
unsigned Kind = Record[i];
@ -3319,7 +3332,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
return EC;
break;
case bitc::METADATA_ATTACHMENT_ID:
if (std::error_code EC = ParseMetadataAttachment())
if (std::error_code EC = ParseMetadataAttachment(*F))
return EC;
break;
case bitc::METADATA_BLOCK_ID: