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.
llvm-svn: 235785
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user