aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Metadata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/Metadata.cpp')
-rw-r--r--llvm/lib/IR/Metadata.cpp130
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();