Skip to content

Metadata: Optimize metadata queries #70700

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions llvm/include/llvm/IR/Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,10 @@ class Instruction : public User,
/// Get the metadata of given kind attached to this Instruction.
/// If the metadata is not found then return null.
MDNode *getMetadata(unsigned KindID) const {
if (!hasMetadata()) return nullptr;
return getMetadataImpl(KindID);
// 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);
}

/// Get the metadata of given kind attached to this Instruction.
Expand Down Expand Up @@ -594,7 +596,6 @@ class Instruction : public User,

private:
// These are all implemented in Metadata.cpp.
MDNode *getMetadataImpl(unsigned KindID) const;
MDNode *getMetadataImpl(StringRef Kind) const;
void
getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned, MDNode *>> &) const;
Expand Down
11 changes: 10 additions & 1 deletion llvm/include/llvm/IR/Value.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,11 @@ class Value {
/// These functions require that the value have at most a single attachment
/// of the given kind, and return \c nullptr if such an attachment is missing.
/// @{
MDNode *getMetadata(unsigned KindID) const;
MDNode *getMetadata(unsigned KindID) const {
if (!HasMetadata)
return nullptr;
return getMetadataImpl(KindID);
}
MDNode *getMetadata(StringRef Kind) const;
/// @}

Expand Down Expand Up @@ -617,6 +621,11 @@ class Value {
/// Erase all metadata attached to this Value.
void clearMetadata();

/// Get metadata for the given kind, if any.
/// This is an internal function that must only be called after
/// checking that `hasMetadata()` returns true.
MDNode *getMetadataImpl(unsigned KindID) const;

public:
/// Return true if this value is a swifterror value.
///
Expand Down
45 changes: 19 additions & 26 deletions llvm/lib/IR/Metadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1351,25 +1351,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 {
Expand All @@ -1382,8 +1379,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);
}
}
Expand All @@ -1393,7 +1389,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;
Expand All @@ -1406,7 +1402,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);
Expand Down Expand Up @@ -1438,7 +1434,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();
Expand All @@ -1461,7 +1457,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) {
Expand All @@ -1475,7 +1475,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);
Expand Down Expand Up @@ -1598,7 +1598,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);
Expand All @@ -1619,13 +1619,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();
Expand Down