diff options
Diffstat (limited to 'llvm/lib/IR/Metadata.cpp')
| -rw-r--r-- | llvm/lib/IR/Metadata.cpp | 130 |
1 files changed, 92 insertions, 38 deletions
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp index c153ffb71a73..7bc25e30b893 100644 --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -32,6 +32,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" +#include "llvm/IR/DebugProgramInstruction.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalObject.h" #include "llvm/IR/GlobalVariable.h" @@ -147,6 +148,32 @@ void MetadataAsValue::untrack() { MetadataTracking::untrack(MD); } +DPValue *DebugValueUser::getUser() { return static_cast<DPValue *>(this); } +const DPValue *DebugValueUser::getUser() const { + return static_cast<const DPValue *>(this); +} +void DebugValueUser::handleChangedValue(Metadata *NewMD) { + getUser()->handleChangedLocation(NewMD); +} + +void DebugValueUser::trackDebugValue() { + if (DebugValue) + MetadataTracking::track(&DebugValue, *DebugValue, *this); +} + +void DebugValueUser::untrackDebugValue() { + if (DebugValue) + MetadataTracking::untrack(DebugValue); +} + +void DebugValueUser::retrackDebugValue(DebugValueUser &X) { + assert(DebugValue == X.DebugValue && "Expected values to match"); + if (X.DebugValue) { + MetadataTracking::retrack(X.DebugValue, DebugValue); + X.DebugValue = nullptr; + } +} + bool MetadataTracking::track(void *Ref, Metadata &MD, OwnerTy Owner) { assert(Ref && "Expected live reference"); assert((Owner || *static_cast<Metadata **>(Ref) == &MD) && @@ -195,6 +222,8 @@ SmallVector<Metadata *> ReplaceableMetadataImpl::getAllArgListUsers() { SmallVector<std::pair<OwnerTy, uint64_t> *> MDUsersWithID; for (auto Pair : UseMap) { OwnerTy Owner = Pair.second.first; + if (Owner.isNull()) + continue; if (!isa<Metadata *>(Owner)) continue; Metadata *OwnerMD = cast<Metadata *>(Owner); @@ -210,6 +239,30 @@ SmallVector<Metadata *> ReplaceableMetadataImpl::getAllArgListUsers() { return MDUsers; } +SmallVector<DPValue *> ReplaceableMetadataImpl::getAllDPValueUsers() { + SmallVector<std::pair<OwnerTy, uint64_t> *> DPVUsersWithID; + for (auto Pair : UseMap) { + OwnerTy Owner = Pair.second.first; + if (Owner.isNull()) + continue; + if (!Owner.is<DebugValueUser *>()) + continue; + DPVUsersWithID.push_back(&UseMap[Pair.first]); + } + // Order DPValue users in reverse-creation order. Normal dbg.value users + // of MetadataAsValues are ordered by their UseList, i.e. reverse order of + // when they were added: we need to replicate that here. The structure of + // debug-info output depends on the ordering of intrinsics, thus we need + // to keep them consistent for comparisons sake. + llvm::sort(DPVUsersWithID, [](auto UserA, auto UserB) { + return UserA->second > UserB->second; + }); + SmallVector<DPValue *> DPVUsers; + for (auto UserWithID : DPVUsersWithID) + DPVUsers.push_back(UserWithID->first.get<DebugValueUser *>()->getUser()); + return DPVUsers; +} + void ReplaceableMetadataImpl::addRef(void *Ref, OwnerTy Owner) { bool WasInserted = UseMap.insert(std::make_pair(Ref, std::make_pair(Owner, NextIndex))) @@ -308,6 +361,11 @@ void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) { continue; } + if (Owner.is<DebugValueUser *>()) { + Owner.get<DebugValueUser *>()->getUser()->handleChangedLocation(MD); + continue; + } + // There's a Metadata owner -- dispatch. Metadata *OwnerMD = cast<Metadata *>(Owner); switch (OwnerMD->getMetadataID()) { @@ -343,7 +401,7 @@ void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) { auto Owner = Pair.second.first; if (!Owner) continue; - if (isa<MetadataAsValue *>(Owner)) + if (!Owner.is<Metadata *>()) continue; // Resolve MDNodes that point at this. @@ -356,22 +414,29 @@ void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) { } } +// Special handing of DIArgList is required in the RemoveDIs project, see +// commentry in DIArgList::handleChangedOperand for details. Hidden behind +// conditional compilation to avoid a compile time regression. ReplaceableMetadataImpl *ReplaceableMetadataImpl::getOrCreate(Metadata &MD) { if (auto *N = dyn_cast<MDNode>(&MD)) return N->isResolved() ? nullptr : N->Context.getOrCreateReplaceableUses(); + if (auto ArgList = dyn_cast<DIArgList>(&MD)) + return ArgList; return dyn_cast<ValueAsMetadata>(&MD); } ReplaceableMetadataImpl *ReplaceableMetadataImpl::getIfExists(Metadata &MD) { if (auto *N = dyn_cast<MDNode>(&MD)) return N->isResolved() ? nullptr : N->Context.getReplaceableUses(); + if (auto ArgList = dyn_cast<DIArgList>(&MD)) + return ArgList; return dyn_cast<ValueAsMetadata>(&MD); } bool ReplaceableMetadataImpl::isReplaceable(const Metadata &MD) { if (auto *N = dyn_cast<MDNode>(&MD)) return !N->isResolved(); - return isa<ValueAsMetadata>(&MD); + return isa<ValueAsMetadata>(&MD) || isa<DIArgList>(&MD); } static DISubprogram *getLocalFunctionMetadata(Value *V) { @@ -1351,25 +1416,22 @@ bool MDAttachments::erase(unsigned ID) { return OldSize != Attachments.size(); } -MDNode *Value::getMetadata(unsigned KindID) const { +MDNode *Value::getMetadata(StringRef Kind) const { if (!hasMetadata()) return nullptr; - const auto &Info = getContext().pImpl->ValueMetadata[this]; - assert(!Info.empty() && "bit out of sync with hash table"); - return Info.lookup(KindID); + unsigned KindID = getContext().getMDKindID(Kind); + return getMetadataImpl(KindID); } -MDNode *Value::getMetadata(StringRef Kind) const { - if (!hasMetadata()) - return nullptr; - const auto &Info = getContext().pImpl->ValueMetadata[this]; - assert(!Info.empty() && "bit out of sync with hash table"); - return Info.lookup(getContext().getMDKindID(Kind)); +MDNode *Value::getMetadataImpl(unsigned KindID) const { + const LLVMContext &Ctx = getContext(); + const MDAttachments &Attachements = Ctx.pImpl->ValueMetadata.at(this); + return Attachements.lookup(KindID); } void Value::getMetadata(unsigned KindID, SmallVectorImpl<MDNode *> &MDs) const { if (hasMetadata()) - getContext().pImpl->ValueMetadata[this].get(KindID, MDs); + getContext().pImpl->ValueMetadata.at(this).get(KindID, MDs); } void Value::getMetadata(StringRef Kind, SmallVectorImpl<MDNode *> &MDs) const { @@ -1382,8 +1444,7 @@ void Value::getAllMetadata( if (hasMetadata()) { assert(getContext().pImpl->ValueMetadata.count(this) && "bit out of sync with hash table"); - const auto &Info = getContext().pImpl->ValueMetadata.find(this)->second; - assert(!Info.empty() && "Shouldn't have called this"); + const MDAttachments &Info = getContext().pImpl->ValueMetadata.at(this); Info.getAll(MDs); } } @@ -1393,7 +1454,7 @@ void Value::setMetadata(unsigned KindID, MDNode *Node) { // Handle the case when we're adding/updating metadata on a value. if (Node) { - auto &Info = getContext().pImpl->ValueMetadata[this]; + MDAttachments &Info = getContext().pImpl->ValueMetadata[this]; assert(!Info.empty() == HasMetadata && "bit out of sync with hash table"); if (Info.empty()) HasMetadata = true; @@ -1406,7 +1467,7 @@ void Value::setMetadata(unsigned KindID, MDNode *Node) { "bit out of sync with hash table"); if (!HasMetadata) return; // Nothing to remove! - auto &Info = getContext().pImpl->ValueMetadata[this]; + MDAttachments &Info = getContext().pImpl->ValueMetadata.find(this)->second; // Handle removal of an existing value. Info.erase(KindID); @@ -1438,7 +1499,7 @@ bool Value::eraseMetadata(unsigned KindID) { if (!HasMetadata) return false; - auto &Store = getContext().pImpl->ValueMetadata[this]; + MDAttachments &Store = getContext().pImpl->ValueMetadata.find(this)->second; bool Changed = Store.erase(KindID); if (Store.empty()) clearMetadata(); @@ -1461,7 +1522,11 @@ void Instruction::setMetadata(StringRef Kind, MDNode *Node) { } MDNode *Instruction::getMetadataImpl(StringRef Kind) const { - return getMetadataImpl(getContext().getMDKindID(Kind)); + const LLVMContext &Ctx = getContext(); + unsigned KindID = Ctx.getMDKindID(Kind); + if (KindID == LLVMContext::MD_dbg) + return DbgLoc.getAsMDNode(); + return Value::getMetadata(KindID); } void Instruction::dropUnknownNonDebugMetadata(ArrayRef<unsigned> KnownIDs) { @@ -1475,7 +1540,7 @@ void Instruction::dropUnknownNonDebugMetadata(ArrayRef<unsigned> KnownIDs) { KnownSet.insert(LLVMContext::MD_DIAssignID); auto &MetadataStore = getContext().pImpl->ValueMetadata; - auto &Info = MetadataStore[this]; + MDAttachments &Info = MetadataStore.find(this)->second; assert(!Info.empty() && "bit out of sync with hash table"); Info.remove_if([&KnownSet](const MDAttachments::Attachment &I) { return !KnownSet.count(I.MDKind); @@ -1542,13 +1607,10 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) { } void Instruction::addAnnotationMetadata(SmallVector<StringRef> Annotations) { - SmallSetVector<StringRef, 2> AnnotationsSet(Annotations.begin(), - Annotations.end()); - MDBuilder MDB(getContext()); - - auto *Existing = getMetadata(LLVMContext::MD_annotation); SmallVector<Metadata *, 4> Names; - if (Existing) { + if (auto *Existing = getMetadata(LLVMContext::MD_annotation)) { + SmallSetVector<StringRef, 2> AnnotationsSet(Annotations.begin(), + Annotations.end()); auto *Tuple = cast<MDTuple>(Existing); for (auto &N : Tuple->operands()) { if (isa<MDString>(N.get())) { @@ -1564,6 +1626,7 @@ void Instruction::addAnnotationMetadata(SmallVector<StringRef> Annotations) { } } + MDBuilder MDB(getContext()); SmallVector<Metadata *> MDAnnotationStrings; for (StringRef Annotation : Annotations) MDAnnotationStrings.push_back(MDB.createString(Annotation)); @@ -1574,11 +1637,8 @@ void Instruction::addAnnotationMetadata(SmallVector<StringRef> Annotations) { } void Instruction::addAnnotationMetadata(StringRef Name) { - MDBuilder MDB(getContext()); - - auto *Existing = getMetadata(LLVMContext::MD_annotation); SmallVector<Metadata *, 4> Names; - if (Existing) { + if (auto *Existing = getMetadata(LLVMContext::MD_annotation)) { auto *Tuple = cast<MDTuple>(Existing); for (auto &N : Tuple->operands()) { if (isa<MDString>(N.get()) && @@ -1588,6 +1648,7 @@ void Instruction::addAnnotationMetadata(StringRef Name) { } } + MDBuilder MDB(getContext()); Names.push_back(MDB.createString(Name)); MDNode *MD = MDTuple::get(getContext(), Names); setMetadata(LLVMContext::MD_annotation, MD); @@ -1598,7 +1659,7 @@ AAMDNodes Instruction::getAAMetadata() const { // Not using Instruction::hasMetadata() because we're not interested in // DebugInfoMetadata. if (Value::hasMetadata()) { - const auto &Info = getContext().pImpl->ValueMetadata[this]; + const MDAttachments &Info = getContext().pImpl->ValueMetadata.at(this); Result.TBAA = Info.lookup(LLVMContext::MD_tbaa); Result.TBAAStruct = Info.lookup(LLVMContext::MD_tbaa_struct); Result.Scope = Info.lookup(LLVMContext::MD_alias_scope); @@ -1619,13 +1680,6 @@ void Instruction::setNoSanitizeMetadata() { llvm::MDNode::get(getContext(), std::nullopt)); } -MDNode *Instruction::getMetadataImpl(unsigned KindID) const { - // Handle 'dbg' as a special case since it is not stored in the hash table. - if (KindID == LLVMContext::MD_dbg) - return DbgLoc.getAsMDNode(); - return Value::getMetadata(KindID); -} - void Instruction::getAllMetadataImpl( SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const { Result.clear(); |
