diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/IR/Function.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 3 | ||||
-rw-r--r-- | llvm/lib/IR/Metadata.cpp | 76 |
3 files changed, 82 insertions, 0 deletions
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 227dfef9e98..ced989ab11d 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -324,6 +324,9 @@ void Function::dropAllReferences() { // Prefix and prologue data are stored in a side table. setPrefixData(nullptr); setPrologueData(nullptr); + + // Metadata is stored in a side-table. + clearMetadata(); } void Function::addAttribute(unsigned i, Attribute::AttrKind attr) { diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index a13afdd9b35..edffef31511 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -992,6 +992,9 @@ public: /// Collection of per-instruction metadata used in this context. DenseMap<const Instruction *, MDAttachmentMap> InstructionMetadata; + /// Collection of per-function metadata used in this context. + DenseMap<const Function *, MDAttachmentMap> FunctionMetadata; + /// DiscriminatorTable - This table maps file:line locations to an /// integer representing the next DWARF path discriminator to assign to /// instructions in different blocks at the same location. diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp index eb1bd310511..23a17a52b2b 100644 --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -1160,3 +1160,79 @@ void Instruction::clearMetadataHashEntries() { getContext().pImpl->InstructionMetadata.erase(this); setHasMetadataHashEntry(false); } + +MDNode *Function::getMetadata(unsigned KindID) const { + if (!hasMetadata()) + return nullptr; + return getContext().pImpl->FunctionMetadata[this].lookup(KindID); +} + +MDNode *Function::getMetadata(StringRef Kind) const { + if (!hasMetadata()) + return nullptr; + return getMetadata(getContext().getMDKindID(Kind)); +} + +void Function::setMetadata(unsigned KindID, MDNode *MD) { + if (MD) { + if (!hasMetadata()) + setHasMetadataHashEntry(true); + + getContext().pImpl->FunctionMetadata[this].set(KindID, *MD); + return; + } + + // Nothing to unset. + if (!hasMetadata()) + return; + + auto &Store = getContext().pImpl->FunctionMetadata[this]; + Store.erase(KindID); + if (Store.empty()) + clearMetadata(); +} + +void Function::setMetadata(StringRef Kind, MDNode *MD) { + if (!MD && !hasMetadata()) + return; + setMetadata(getContext().getMDKindID(Kind), MD); +} + +void Function::getAllMetadata( + SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const { + MDs.clear(); + + if (!hasMetadata()) + return; + + getContext().pImpl->FunctionMetadata[this].getAll(MDs); +} + +void Function::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) { + if (!hasMetadata()) + return; + if (KnownIDs.empty()) { + clearMetadata(); + return; + } + + SmallSet<unsigned, 5> KnownSet; + KnownSet.insert(KnownIDs.begin(), KnownIDs.end()); + + auto &Store = getContext().pImpl->FunctionMetadata[this]; + assert(!Store.empty()); + + Store.remove_if([&KnownSet](const std::pair<unsigned, TrackingMDNodeRef> &I) { + return !KnownSet.count(I.first); + }); + + if (Store.empty()) + clearMetadata(); +} + +void Function::clearMetadata() { + if (!hasMetadata()) + return; + getContext().pImpl->FunctionMetadata.erase(this); + setHasMetadataHashEntry(false); +} |