diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index f2a6056d15c7..172f30920484 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -360,13 +360,14 @@ bool LLParser::ParseDeclare() { } /// toplevelentity -/// ::= 'define' FunctionHeader '{' ... +/// ::= 'define' FunctionHeader (!dbg !56)* '{' ... bool LLParser::ParseDefine() { assert(Lex.getKind() == lltok::kw_define); Lex.Lex(); Function *F; return ParseFunctionHeader(F, true) || + ParseOptionalFunctionMetadata(*F) || ParseFunctionBody(*F); } @@ -1523,6 +1524,20 @@ bool LLParser::ParseInstructionMetadata(Instruction &Inst) { return false; } +/// ParseOptionalFunctionMetadata +/// ::= (!dbg !57)* +bool LLParser::ParseOptionalFunctionMetadata(Function &F) { + while (Lex.getKind() == lltok::MetadataVar) { + unsigned MDK; + MDNode *N; + if (ParseMetadataAttachment(MDK, N)) + return true; + + F.setMetadata(MDK, N); + } + return false; +} + /// ParseOptionalAlignment /// ::= /* empty */ /// ::= 'align' 4 diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index ea18b58d32f5..a43a4b06a946 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -394,6 +394,7 @@ namespace llvm { bool ParseMDNodeVector(SmallVectorImpl &MDs); bool ParseMetadataAttachment(unsigned &Kind, MDNode *&MD); bool ParseInstructionMetadata(Instruction &Inst); + bool ParseOptionalFunctionMetadata(Function &F); template bool ParseMDField(LocTy Loc, StringRef Name, FieldTy &Result); diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 5f7a5ea12919..b6528cbbeccb 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -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 parseModuleTriple(); std::error_code ParseUseLists(); std::error_code InitStream(); @@ -3215,7 +3215,7 @@ ErrorOr 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(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: diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 52a5d480fddc..b8baabd22d8a 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1279,6 +1279,15 @@ static void WriteMetadataAttachment(const Function &F, // Write metadata attachments // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]] SmallVector, 4> MDs; + F.getAllMetadata(MDs); + if (!MDs.empty()) { + for (const auto &I : MDs) { + Record.push_back(I.first); + Record.push_back(VE.getMetadataID(I.second)); + } + Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0); + Record.clear(); + } for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); @@ -2091,7 +2100,7 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE, // Keep a running idea of what the instruction ID is. unsigned InstID = CstEnd; - bool NeedsMetadataAttachment = false; + bool NeedsMetadataAttachment = F.hasMetadata(); MDLocation *LastDL = nullptr; diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 7f576d758bd5..652851f4cc16 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -348,6 +348,11 @@ ValueEnumerator::ValueEnumerator(const Module &M, for (const Argument &A : F.args()) EnumerateType(A.getType()); + // Enumerate metadata attached to this function. + F.getAllMetadata(MDs); + for (const auto &I : MDs) + EnumerateMetadata(I.second); + for (const BasicBlock &BB : F) for (const Instruction &I : BB) { for (const Use &Op : I.operands()) { diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 299665531f3f..0564513c94ab 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -776,12 +776,12 @@ void SlotTracker::processFunction() { if (!BB.hasName()) CreateFunctionSlot(&BB); + processFunctionMetadata(*TheFunction); + for (auto &I : BB) { if (!I.getType()->isVoidTy() && !I.hasName()) CreateFunctionSlot(&I); - processInstructionMetadata(I); - // We allow direct calls to any llvm.foo function here, because the // target may not be linked into the optimizer. if (const CallInst *CI = dyn_cast(&I)) { @@ -804,9 +804,15 @@ void SlotTracker::processFunction() { } void SlotTracker::processFunctionMetadata(const Function &F) { - for (auto &BB : F) + SmallVector, 4> MDs; + for (auto &BB : F) { + F.getAllMetadata(MDs); + for (auto &MD : MDs) + CreateMetadataSlot(MD.second); + for (auto &I : BB) processInstructionMetadata(I); + } } void SlotTracker::processInstructionMetadata(const Instruction &I) { @@ -2541,6 +2547,10 @@ void AssemblyWriter::printFunction(const Function *F) { writeOperand(F->getPrologueData(), true); } + SmallVector, 4> MDs; + F->getAllMetadata(MDs); + printMetadataAttachments(MDs, " "); + if (F->isDeclaration()) { Out << '\n'; } else { diff --git a/llvm/test/Assembler/metadata.ll b/llvm/test/Assembler/metadata.ll index b483fc3f4cfc..21a47ddb7348 100644 --- a/llvm/test/Assembler/metadata.ll +++ b/llvm/test/Assembler/metadata.ll @@ -11,8 +11,22 @@ define void @test() { ret void, !foo !0, !bar !1 } +; CHECK: define void @test2() !foo !2 !baz !3 +define void @test2() !foo !2 !baz !3 { + unreachable +} + +; CHECK: define void @test3() !bar !3 +; CHECK: unreachable, !bar !4 +define void @test3() !bar !3 { + unreachable, !bar !4 +} + !0 = !MDLocation(line: 662302, column: 26, scope: !1) !1 = !MDSubprogram(name: "foo") +!2 = distinct !{} +!3 = distinct !{} +!4 = distinct !{} declare void @llvm.dbg.func.start(metadata) nounwind readnone