From 19538d1e9fb4f8198b94f8450c6fc43528d8b868 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 20 Jul 2010 21:42:28 +0000 Subject: [PATCH] Add support for remapping metadata kind IDs when reading in a bitcode file, so that two bitcode files where the same metadata kind name happens to have been assigned a different ID can still be linked together. Eliminate the restriction that metadata kind IDs can't be 0. Change MD_dbg from 1 to 0, because we can now, and because it's less mysterious that way. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108939 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/LLVMContext.h | 2 +- lib/Bitcode/Reader/BitcodeReader.cpp | 12 ++++++++---- lib/Bitcode/Reader/BitcodeReader.h | 3 +++ lib/Bitcode/Writer/BitcodeWriter.cpp | 5 ++--- lib/VMCore/LLVMContext.cpp | 13 +++++-------- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/include/llvm/LLVMContext.h b/include/llvm/LLVMContext.h index afae08b07da..96dbf77a5ae 100644 --- a/include/llvm/LLVMContext.h +++ b/include/llvm/LLVMContext.h @@ -40,7 +40,7 @@ public: // Pinned metadata names, which always have the same value. This is a // compile-time performance optimization, not a correctness optimization. enum { - MD_dbg = 1 // "dbg" -> 1. + MD_dbg = 0 // "dbg" }; /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index b3f0776d29d..f486b51caec 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -39,6 +39,7 @@ void BitcodeReader::FreeState() { std::vector().swap(FunctionBBs); std::vector().swap(FunctionsWithBodies); DeferredFunctionInfo.clear(); + MDKindMap.clear(); } //===----------------------------------------------------------------------===// @@ -859,13 +860,12 @@ bool BitcodeReader::ParseMetadata() { SmallString<8> Name; Name.resize(RecordLength-1); unsigned Kind = Record[0]; - (void) Kind; for (unsigned i = 1; i != RecordLength; ++i) Name[i-1] = Record[i]; unsigned NewKind = TheModule->getMDKindID(Name.str()); - assert(Kind == NewKind && - "FIXME: Unable to handle custom metadata mismatch!");(void)NewKind; + if (!MDKindMap.insert(std::make_pair(Kind, NewKind)).second) + return Error("Conflicting METADATA_KIND records"); break; } } @@ -1621,8 +1621,12 @@ bool BitcodeReader::ParseMetadataAttachment() { Instruction *Inst = InstructionList[Record[0]]; for (unsigned i = 1; i != RecordLength; i = i+2) { unsigned Kind = Record[i]; + DenseMap::iterator I = + MDKindMap.find(Kind); + if (I == MDKindMap.end()) + return Error("Invalid metadata kind ID"); Value *Node = MDValueList.getValueFwdRef(Record[i+1]); - Inst->setMetadata(Kind, cast(Node)); + Inst->setMetadata(I->second, cast(Node)); } break; } diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index 55c71f7c886..a5ab5d29e91 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -156,6 +156,9 @@ class BitcodeReader : public GVMaterializer { // stored here with their replacement function. typedef std::vector > UpgradedIntrinsicMap; UpgradedIntrinsicMap UpgradedIntrinsics; + + // Map the bitcode's custom MDKind ID to the Module's MDKind ID. + DenseMap MDKindMap; // After the module header has been read, the FunctionsWithBodies list is // reversed. This keeps track of whether we've done this yet. diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index fa1b2c4bee2..985c16c783d 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -634,12 +634,11 @@ static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) { SmallVector Names; M->getMDKindNames(Names); - assert(Names[0] == "" && "MDKind #0 is invalid"); - if (Names.size() == 1) return; + if (Names.empty()) return; Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); - for (unsigned MDKindID = 1, e = Names.size(); MDKindID != e; ++MDKindID) { + for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) { Record.push_back(MDKindID); StringRef KName = Names[MDKindID]; Record.append(KName.begin(), KName.end()); diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp index 4d61363b939..563c651315a 100644 --- a/lib/VMCore/LLVMContext.cpp +++ b/lib/VMCore/LLVMContext.cpp @@ -110,21 +110,18 @@ static bool isValidName(StringRef MDName) { /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. unsigned LLVMContext::getMDKindID(StringRef Name) const { assert(isValidName(Name) && "Invalid MDNode name"); - - unsigned &Entry = pImpl->CustomMDKindNames[Name]; - + // If this is new, assign it its ID. - if (Entry == 0) Entry = pImpl->CustomMDKindNames.size(); - return Entry; + return + pImpl->CustomMDKindNames.GetOrCreateValue( + Name, pImpl->CustomMDKindNames.size()).second; } /// getHandlerNames - Populate client supplied smallvector using custome /// metadata name and ID. void LLVMContext::getMDKindNames(SmallVectorImpl &Names) const { - Names.resize(pImpl->CustomMDKindNames.size()+1); - Names[0] = ""; + Names.resize(pImpl->CustomMDKindNames.size()); for (StringMap::const_iterator I = pImpl->CustomMDKindNames.begin(), E = pImpl->CustomMDKindNames.end(); I != E; ++I) - // MD Handlers are numbered from 1. Names[I->second] = I->first(); } -- 2.34.1