diff options
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 21 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 5 |
3 files changed, 32 insertions, 5 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 5f7a5ea1291..b6528cbbecc 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<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: diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 52a5d480fdd..b8baabd22d8 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<std::pair<unsigned, MDNode *>, 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 7f576d758bd..652851f4cc1 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()) { |