Index: llvm/trunk/docs/BitCodeFormat.rst =================================================================== --- llvm/trunk/docs/BitCodeFormat.rst +++ llvm/trunk/docs/BitCodeFormat.rst @@ -856,6 +856,16 @@ ``gc`` attributes within the module. These records can be referenced by 1-based index in the *gc* fields of ``FUNCTION`` records. +MODULE_CODE_GLOBALVAR_ATTACHMENT Record +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``[GLOBALVAR_ATTACHMENT, valueid, n x [id, mdnode]]`` + +The ``GLOBALVAR_ATTACHMENT`` record (code 19) describes the metadata +attachments for a global variable. The ``valueid`` is the value index for +the global variable, and the remaining fields are pairs of metadata name +indices and metadata node indices. + .. _PARAMATTR_BLOCK: PARAMATTR_BLOCK Contents Index: llvm/trunk/docs/LangRef.rst =================================================================== --- llvm/trunk/docs/LangRef.rst +++ llvm/trunk/docs/LangRef.rst @@ -619,7 +619,8 @@ iterate over them as an array, alignment padding would break this iteration. The maximum alignment is ``1 << 29``. -Globals can also have a :ref:`DLL storage class `. +Globals can also have a :ref:`DLL storage class ` and +an optional list of attached :ref:`metadata `, Variables and aliases can have a :ref:`Thread Local Storage Model `. @@ -630,7 +631,7 @@ [unnamed_addr] [AddrSpace] [ExternallyInitialized] [] [, section "name"] [, comdat [($name)]] - [, align ] + [, align ] (, !name !N)* For example, the following defines a global in a numbered address space with an initializer, section, and alignment: Index: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h =================================================================== --- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h +++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h @@ -113,6 +113,9 @@ // IFUNC: [ifunc value type, addrspace, resolver val#, linkage, visibility] MODULE_CODE_IFUNC = 18, + + // GLOBALVAR_ATTACHMENT: [valueid, n x [id, mdnode]] + MODULE_CODE_GLOBALVAR_ATTACHMENT = 19, }; /// PARAMATTR blocks have code for defining a parameter attribute set. Index: llvm/trunk/include/llvm/IR/Function.h =================================================================== --- llvm/trunk/include/llvm/IR/Function.h +++ llvm/trunk/include/llvm/IR/Function.h @@ -72,13 +72,8 @@ /// Bits from GlobalObject::GlobalObjectSubclassData. enum { /// Whether this function is materializable. - IsMaterializableBit = 1 << 0, - HasMetadataHashEntryBit = 1 << 1 + IsMaterializableBit = 0, }; - void setGlobalObjectBit(unsigned Mask, bool Value) { - setGlobalObjectSubClassData((~Mask & getGlobalObjectSubClassData()) | - (Value ? Mask : 0u)); - } friend class SymbolTableListTraits; @@ -614,35 +609,6 @@ /// setjmp or other function that gcc recognizes as "returning twice". bool callsFunctionThatReturnsTwice() const; - /// \brief Check if this has any metadata. - bool hasMetadata() const { return hasMetadataHashEntry(); } - - /// \brief Get the current metadata attachment, if any. - /// - /// Returns \c nullptr if such an attachment is missing. - /// @{ - MDNode *getMetadata(unsigned KindID) const; - MDNode *getMetadata(StringRef Kind) const; - /// @} - - /// \brief Set a particular kind of metadata attachment. - /// - /// Sets the given attachment to \c MD, erasing it if \c MD is \c nullptr or - /// replacing it if it already exists. - /// @{ - void setMetadata(unsigned KindID, MDNode *MD); - void setMetadata(StringRef Kind, MDNode *MD); - /// @} - - /// \brief Get all current metadata attachments. - void - getAllMetadata(SmallVectorImpl> &MDs) const; - - /// \brief Drop metadata not in the given list. - /// - /// Drop all metadata from \c this not included in \c KnownIDs. - void dropUnknownMetadata(ArrayRef KnownIDs); - /// \brief Set the attached subprogram. /// /// Calls \a setMetadata() with \a LLVMContext::MD_dbg. @@ -664,15 +630,6 @@ Value::setValueSubclassData(D); } void setValueSubclassDataBit(unsigned Bit, bool On); - - bool hasMetadataHashEntry() const { - return getGlobalObjectSubClassData() & HasMetadataHashEntryBit; - } - void setHasMetadataHashEntry(bool HasEntry) { - setGlobalObjectBit(HasMetadataHashEntryBit, HasEntry); - } - - void clearMetadata(); }; template <> Index: llvm/trunk/include/llvm/IR/GlobalObject.h =================================================================== --- llvm/trunk/include/llvm/IR/GlobalObject.h +++ llvm/trunk/include/llvm/IR/GlobalObject.h @@ -20,6 +20,7 @@ namespace llvm { class Comdat; +class MDNode; class Module; class GlobalObject : public GlobalValue { @@ -36,12 +37,19 @@ std::string Section; // Section to emit this into, empty means default Comdat *ObjComdat; - static const unsigned AlignmentBits = 5; + enum { + LastAlignmentBit = 4, + HasMetadataHashEntryBit, + + GlobalObjectBits, + }; static const unsigned GlobalObjectSubClassDataBits = - GlobalValueSubClassDataBits - AlignmentBits; + GlobalValueSubClassDataBits - GlobalObjectBits; private: + static const unsigned AlignmentBits = LastAlignmentBit + 1; static const unsigned AlignmentMask = (1 << AlignmentBits) - 1; + static const unsigned GlobalObjectMask = (1 << GlobalObjectBits) - 1; public: unsigned getAlignment() const { @@ -63,6 +71,35 @@ Comdat *getComdat() { return ObjComdat; } void setComdat(Comdat *C) { ObjComdat = C; } + /// Check if this has any metadata. + bool hasMetadata() const { return hasMetadataHashEntry(); } + + /// Get the current metadata attachment, if any. + /// + /// Returns \c nullptr if such an attachment is missing. + /// @{ + MDNode *getMetadata(unsigned KindID) const; + MDNode *getMetadata(StringRef Kind) const; + /// @} + + /// Set a particular kind of metadata attachment. + /// + /// Sets the given attachment to \c MD, erasing it if \c MD is \c nullptr or + /// replacing it if it already exists. + /// @{ + void setMetadata(unsigned KindID, MDNode *MD); + void setMetadata(StringRef Kind, MDNode *MD); + /// @} + + /// Get all current metadata attachments. + void + getAllMetadata(SmallVectorImpl> &MDs) const; + + /// Drop metadata not in the given list. + /// + /// Drop all metadata from \c this not included in \c KnownIDs. + void dropUnknownMetadata(ArrayRef KnownIDs); + void copyAttributesFrom(const GlobalValue *Src) override; // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -70,6 +107,19 @@ return V->getValueID() == Value::FunctionVal || V->getValueID() == Value::GlobalVariableVal; } + +protected: + void clearMetadata(); + +private: + bool hasMetadataHashEntry() const { + return getGlobalValueSubClassData() & (1 << HasMetadataHashEntryBit); + } + void setHasMetadataHashEntry(bool HasEntry) { + unsigned Mask = 1 << HasMetadataHashEntryBit; + setGlobalValueSubClassData((~Mask & getGlobalValueSubClassData()) | + (HasEntry ? Mask : 0u)); + } }; } // End llvm namespace Index: llvm/trunk/include/llvm/IR/GlobalVariable.h =================================================================== --- llvm/trunk/include/llvm/IR/GlobalVariable.h +++ llvm/trunk/include/llvm/IR/GlobalVariable.h @@ -159,6 +159,10 @@ /// void eraseFromParent() override; + /// Drop all references in preparation to destroy the GlobalVariable. This + /// drops not only the reference to the initializer but also to any metadata. + void dropAllReferences(); + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Value *V) { return V->getValueID() == Value::GlobalVariableVal; Index: llvm/trunk/lib/AsmParser/LLParser.h =================================================================== --- llvm/trunk/lib/AsmParser/LLParser.h +++ llvm/trunk/lib/AsmParser/LLParser.h @@ -424,6 +424,7 @@ bool ParseMDNodeVector(SmallVectorImpl &MDs); bool ParseMetadataAttachment(unsigned &Kind, MDNode *&MD); bool ParseInstructionMetadata(Instruction &Inst); + bool ParseGlobalObjectMetadataAttachment(GlobalObject &GO); bool ParseOptionalFunctionMetadata(Function &F); template Index: llvm/trunk/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp +++ llvm/trunk/lib/AsmParser/LLParser.cpp @@ -891,6 +891,9 @@ unsigned Alignment; if (ParseOptionalAlignment(Alignment)) return true; GV->setAlignment(Alignment); + } else if (Lex.getKind() == lltok::MetadataVar) { + if (ParseGlobalObjectMetadataAttachment(*GV)) + return true; } else { Comdat *C; if (parseOptionalComdat(Name, C)) @@ -1708,17 +1711,24 @@ return false; } +/// ParseGlobalObjectMetadataAttachment +/// ::= !dbg !57 +bool LLParser::ParseGlobalObjectMetadataAttachment(GlobalObject &GO) { + unsigned MDK; + MDNode *N; + if (ParseMetadataAttachment(MDK, N)) + return true; + + GO.setMetadata(MDK, N); + return false; +} + /// ParseOptionalFunctionMetadata /// ::= (!dbg !57)* bool LLParser::ParseOptionalFunctionMetadata(Function &F) { - while (Lex.getKind() == lltok::MetadataVar) { - unsigned MDK; - MDNode *N; - if (ParseMetadataAttachment(MDK, N)) + while (Lex.getKind() == lltok::MetadataVar) + if (ParseGlobalObjectMetadataAttachment(F)) return true; - - F.setMetadata(MDK, N); - } return false; } Index: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp @@ -443,6 +443,9 @@ unsigned &NextMetadataNo); std::error_code parseMetadataKinds(); std::error_code parseMetadataKindRecord(SmallVectorImpl &Record); + std::error_code + parseGlobalObjectAttachment(GlobalObject &GO, + ArrayRef Record); std::error_code parseMetadataAttachment(Function &F); ErrorOr parseModuleTriple(); std::error_code parseUseLists(); @@ -3820,6 +3823,16 @@ } break; } + case bitc::MODULE_CODE_GLOBALVAR_ATTACHMENT: { + if (Record.size() % 2 == 0) + return error("Invalid record"); + unsigned ValueID = Record[0]; + if (ValueID >= ValueList.size()) + return error("Invalid record"); + if (auto *GV = dyn_cast(ValueList[ValueID])) + parseGlobalObjectAttachment(*GV, ArrayRef(Record).slice(1)); + break; + } // FUNCTION: [type, callingconv, isproto, linkage, paramattr, // alignment, section, visibility, gc, unnamed_addr, // prologuedata, dllstorageclass, comdat, prefixdata] @@ -4144,6 +4157,21 @@ } } +std::error_code BitcodeReader::parseGlobalObjectAttachment( + GlobalObject &GO, ArrayRef Record) { + assert(Record.size() % 2 == 0); + for (unsigned I = 0, E = Record.size(); I != E; I += 2) { + auto K = MDKindMap.find(Record[I]); + if (K == MDKindMap.end()) + return error("Invalid ID"); + MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[I + 1]); + if (!MD) + return error("Invalid metadata attachment"); + GO.setMetadata(K->second, MD); + } + return std::error_code(); +} + /// Parse metadata attachments. std::error_code BitcodeReader::parseMetadataAttachment(Function &F) { if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID)) @@ -4175,15 +4203,8 @@ 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"); - MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[I + 1]); - if (!MD) - return error("Invalid metadata attachment"); - F.setMetadata(K->second, MD); - } + if (std::error_code EC = parseGlobalObjectAttachment(F, Record)) + return EC; continue; } Index: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -223,7 +223,10 @@ SmallVectorImpl &Record); void writeModuleMetadata(); void writeFunctionMetadata(const Function &F); - void writeMetadataAttachment(const Function &F); + void writeFunctionMetadataAttachment(const Function &F); + void writeGlobalVariableMetadataAttachment(const GlobalVariable &GV); + void pushGlobalMetadataAttachment(SmallVectorImpl &Record, + const GlobalObject &GO); void writeModuleMetadataStore(); void writeOperandBundleTags(); void writeConstants(unsigned FirstVal, unsigned LastVal, bool isGlobal); @@ -1831,24 +1834,31 @@ Stream.ExitBlock(); } -void ModuleBitcodeWriter::writeMetadataAttachment(const Function &F) { +void ModuleBitcodeWriter::pushGlobalMetadataAttachment( + SmallVectorImpl &Record, const GlobalObject &GO) { + // [n x [id, mdnode]] + SmallVector, 4> MDs; + GO.getAllMetadata(MDs); + for (const auto &I : MDs) { + Record.push_back(I.first); + Record.push_back(VE.getMetadataID(I.second)); + } +} + +void ModuleBitcodeWriter::writeFunctionMetadataAttachment(const Function &F) { Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3); SmallVector Record; - // 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)); - } + if (F.hasMetadata()) { + pushGlobalMetadataAttachment(Record, F); Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0); Record.clear(); } + // Write metadata attachments + // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]] + SmallVector, 4> MDs; for (const BasicBlock &BB : F) for (const Instruction &I : BB) { MDs.clear(); @@ -2894,7 +2904,7 @@ writeValueSymbolTable(F.getValueSymbolTable()); if (NeedsMetadataAttachment) - writeMetadataAttachment(F); + writeFunctionMetadataAttachment(F); if (VE.shouldPreserveUseListOrder()) writeUseListBlock(&F); VE.purgeFunction(); @@ -3597,6 +3607,14 @@ writeValueSymbolTable(M.getValueSymbolTable(), /* IsModuleLevel */ true, &FunctionToBitcodeIndex); + for (const GlobalVariable &GV : M.globals()) + if (GV.hasMetadata()) { + SmallVector Record; + Record.push_back(VE.getValueID(&GV)); + pushGlobalMetadataAttachment(Record, GV); + Stream.EmitRecord(bitc::MODULE_CODE_GLOBALVAR_ATTACHMENT, Record); + } + if (GenerateHash) { writeModuleHash(BlockStartPos); } Index: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h =================================================================== --- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h +++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h @@ -255,7 +255,7 @@ /// it's an \a MDNode. const MDNode *enumerateMetadataImpl(unsigned F, const Metadata *MD); - unsigned getMetadataFunctionID(const Function *F) const; + unsigned getMetadataGlobalID(const GlobalObject *GO) const; /// Enumerate reachable metadata in (almost) post-order. /// @@ -272,7 +272,7 @@ /// \a organizeMetadata() will later partition distinct nodes ahead of /// uniqued ones. ///{ - void EnumerateMetadata(const Function *F, const Metadata *MD); + void EnumerateMetadata(const GlobalObject *GO, const Metadata *MD); void EnumerateMetadata(unsigned F, const Metadata *MD); ///} Index: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp =================================================================== --- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp +++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -344,6 +344,11 @@ EnumerateNamedMetadata(M); SmallVector, 8> MDs; + for (const GlobalVariable &GV : M.globals()) { + GV.getAllMetadata(MDs); + for (const auto &I : MDs) + EnumerateMetadata(&GV, I.second); + } // Enumerate types used by function bodies and argument lists. for (const Function &F : M) { @@ -523,17 +528,18 @@ EnumerateMetadata(nullptr, MD->getOperand(i)); } -unsigned ValueEnumerator::getMetadataFunctionID(const Function *F) const { - return F ? getValueID(F) + 1 : 0; +unsigned ValueEnumerator::getMetadataGlobalID(const GlobalObject *GO) const { + return GO ? getValueID(GO) + 1 : 0; } -void ValueEnumerator::EnumerateMetadata(const Function *F, const Metadata *MD) { - EnumerateMetadata(getMetadataFunctionID(F), MD); +void ValueEnumerator::EnumerateMetadata(const GlobalObject *GO, + const Metadata *MD) { + EnumerateMetadata(getMetadataGlobalID(GO), MD); } void ValueEnumerator::EnumerateFunctionLocalMetadata( const Function &F, const LocalAsMetadata *Local) { - EnumerateFunctionLocalMetadata(getMetadataFunctionID(&F), Local); + EnumerateFunctionLocalMetadata(getMetadataGlobalID(&F), Local); } void ValueEnumerator::dropFunctionFromMetadata( Index: llvm/trunk/lib/IR/AsmWriter.cpp =================================================================== --- llvm/trunk/lib/IR/AsmWriter.cpp +++ llvm/trunk/lib/IR/AsmWriter.cpp @@ -681,6 +681,9 @@ /// Add all of the functions arguments, basic blocks, and instructions. void processFunction(); + /// Add the metadata directly attached to a GlobalObject. + void processGlobalObjectMetadata(const GlobalObject &GO); + /// Add all of the metadata from a function. void processFunctionMetadata(const Function &F); @@ -799,6 +802,7 @@ for (const GlobalVariable &Var : TheModule->globals()) { if (!Var.hasName()) CreateModuleSlot(&Var); + processGlobalObjectMetadata(Var); } for (const GlobalAlias &A : TheModule->aliases()) { @@ -882,12 +886,15 @@ ST_DEBUG("end processFunction!\n"); } -void SlotTracker::processFunctionMetadata(const Function &F) { +void SlotTracker::processGlobalObjectMetadata(const GlobalObject &GO) { SmallVector, 4> MDs; - F.getAllMetadata(MDs); + GO.getAllMetadata(MDs); for (auto &MD : MDs) CreateMetadataSlot(MD.second); +} +void SlotTracker::processFunctionMetadata(const Function &F) { + processGlobalObjectMetadata(F); for (auto &BB : F) { for (auto &I : BB) processInstructionMetadata(I); @@ -2473,6 +2480,10 @@ if (GV->getAlignment()) Out << ", align " << GV->getAlignment(); + SmallVector, 4> MDs; + GV->getAllMetadata(MDs); + printMetadataAttachments(MDs, ", "); + printInfoComment(*GV); } Index: llvm/trunk/lib/IR/Function.cpp =================================================================== --- llvm/trunk/lib/IR/Function.cpp +++ llvm/trunk/lib/IR/Function.cpp @@ -218,11 +218,13 @@ //===----------------------------------------------------------------------===// bool Function::isMaterializable() const { - return getGlobalObjectSubClassData() & IsMaterializableBit; + return getGlobalObjectSubClassData() & (1 << IsMaterializableBit); } void Function::setIsMaterializable(bool V) { - setGlobalObjectBit(IsMaterializableBit, V); + unsigned Mask = 1 << IsMaterializableBit; + setGlobalObjectSubClassData((~Mask & getGlobalObjectSubClassData()) | + (V ? Mask : 0u)); } LLVMContext &Function::getContext() const { Index: llvm/trunk/lib/IR/Globals.cpp =================================================================== --- llvm/trunk/lib/IR/Globals.cpp +++ llvm/trunk/lib/IR/Globals.cpp @@ -81,13 +81,13 @@ unsigned GlobalObject::getGlobalObjectSubClassData() const { unsigned ValueData = getGlobalValueSubClassData(); - return ValueData >> AlignmentBits; + return ValueData >> GlobalObjectBits; } void GlobalObject::setGlobalObjectSubClassData(unsigned Val) { unsigned OldData = getGlobalValueSubClassData(); - setGlobalValueSubClassData((OldData & AlignmentMask) | - (Val << AlignmentBits)); + setGlobalValueSubClassData((OldData & GlobalObjectMask) | + (Val << GlobalObjectBits)); assert(getGlobalObjectSubClassData() == Val && "representation error"); } @@ -301,6 +301,10 @@ } } +void GlobalVariable::dropAllReferences() { + User::dropAllReferences(); + clearMetadata(); +} //===----------------------------------------------------------------------===// // GlobalIndirectSymbol Implementation Index: llvm/trunk/lib/IR/LLVMContextImpl.h =================================================================== --- llvm/trunk/lib/IR/LLVMContextImpl.h +++ llvm/trunk/lib/IR/LLVMContextImpl.h @@ -1107,8 +1107,8 @@ /// Collection of per-instruction metadata used in this context. DenseMap InstructionMetadata; - /// Collection of per-function metadata used in this context. - DenseMap FunctionMetadata; + /// Collection of per-GlobalObject metadata used in this context. + DenseMap GlobalObjectMetadata; /// DiscriminatorTable - This table maps file:line locations to an /// integer representing the next DWARF path discriminator to assign to Index: llvm/trunk/lib/IR/Metadata.cpp =================================================================== --- llvm/trunk/lib/IR/Metadata.cpp +++ llvm/trunk/lib/IR/Metadata.cpp @@ -1281,24 +1281,24 @@ setHasMetadataHashEntry(false); } -MDNode *Function::getMetadata(unsigned KindID) const { +MDNode *GlobalObject::getMetadata(unsigned KindID) const { if (!hasMetadata()) return nullptr; - return getContext().pImpl->FunctionMetadata[this].lookup(KindID); + return getContext().pImpl->GlobalObjectMetadata[this].lookup(KindID); } -MDNode *Function::getMetadata(StringRef Kind) const { +MDNode *GlobalObject::getMetadata(StringRef Kind) const { if (!hasMetadata()) return nullptr; return getMetadata(getContext().getMDKindID(Kind)); } -void Function::setMetadata(unsigned KindID, MDNode *MD) { +void GlobalObject::setMetadata(unsigned KindID, MDNode *MD) { if (MD) { if (!hasMetadata()) setHasMetadataHashEntry(true); - getContext().pImpl->FunctionMetadata[this].set(KindID, *MD); + getContext().pImpl->GlobalObjectMetadata[this].set(KindID, *MD); return; } @@ -1306,29 +1306,29 @@ if (!hasMetadata()) return; - auto &Store = getContext().pImpl->FunctionMetadata[this]; + auto &Store = getContext().pImpl->GlobalObjectMetadata[this]; Store.erase(KindID); if (Store.empty()) clearMetadata(); } -void Function::setMetadata(StringRef Kind, MDNode *MD) { +void GlobalObject::setMetadata(StringRef Kind, MDNode *MD) { if (!MD && !hasMetadata()) return; setMetadata(getContext().getMDKindID(Kind), MD); } -void Function::getAllMetadata( +void GlobalObject::getAllMetadata( SmallVectorImpl> &MDs) const { MDs.clear(); if (!hasMetadata()) return; - getContext().pImpl->FunctionMetadata[this].getAll(MDs); + getContext().pImpl->GlobalObjectMetadata[this].getAll(MDs); } -void Function::dropUnknownMetadata(ArrayRef KnownIDs) { +void GlobalObject::dropUnknownMetadata(ArrayRef KnownIDs) { if (!hasMetadata()) return; if (KnownIDs.empty()) { @@ -1339,7 +1339,7 @@ SmallSet KnownSet; KnownSet.insert(KnownIDs.begin(), KnownIDs.end()); - auto &Store = getContext().pImpl->FunctionMetadata[this]; + auto &Store = getContext().pImpl->GlobalObjectMetadata[this]; assert(!Store.empty()); Store.remove_if([&KnownSet](const std::pair &I) { @@ -1350,10 +1350,10 @@ clearMetadata(); } -void Function::clearMetadata() { +void GlobalObject::clearMetadata() { if (!hasMetadata()) return; - getContext().pImpl->FunctionMetadata.erase(this); + getContext().pImpl->GlobalObjectMetadata.erase(this); setHasMetadataHashEntry(false); } Index: llvm/trunk/test/Assembler/metadata.ll =================================================================== --- llvm/trunk/test/Assembler/metadata.ll +++ llvm/trunk/test/Assembler/metadata.ll @@ -1,8 +1,11 @@ ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s ; RUN: verify-uselistorder %s +; CHECK: @global = global i32 0, !foo [[M2:![0-9]+]], !baz [[M3:![0-9]+]] +@global = global i32 0, !foo !2, !baz !3 + ; CHECK-LABEL: @test -; CHECK: ret void, !bar !4, !foo !3 +; CHECK: ret void, !foo [[M0:![0-9]+]], !bar [[M1:![0-9]+]] define void @test() !dbg !1 { add i32 2, 1, !bar !0 add i32 1, 2, !foo !1 @@ -11,24 +14,30 @@ ret void, !foo !0, !bar !1 } -; CHECK-LABEL: define void @test2() !foo !5 !baz !6 +; CHECK: define void @test2() !foo [[M2]] !baz [[M3]] define void @test2() !foo !2 !baz !3 { unreachable } -; CHECK-LABEL: define void @test3() !bar !6 -; CHECK: unreachable, !bar !7 +; CHECK: define void @test3() !bar [[M3]] +; CHECK: unreachable, !bar [[M4:![0-9]+]] define void @test3() !bar !3 { unreachable, !bar !4 } ; CHECK-LABEL: define void @test_attachment_name() { -; CHECK: unreachable, !\342abc !7 +; CHECK: unreachable, !\342abc [[M4]] define void @test_attachment_name() { ;; Escape the first character when printing text IR, since it's a digit unreachable, !\34\32abc !4 } +; CHECK: [[M2]] = distinct !{} +; CHECK: [[M3]] = distinct !{} +; CHECK: [[M0]] = !DILocation +; CHECK: [[M1]] = distinct !DISubprogram +; CHECK: [[M4]] = distinct !{} + !llvm.module.flags = !{!7} !llvm.dbg.cu = !{!5} !0 = !DILocation(line: 662302, column: 26, scope: !1)