[llvm] [IR] Remove Value::HasMetadata (PR #189917)
Alexis Engelke via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 1 03:46:41 PDT 2026
https://github.com/aengelke updated https://github.com/llvm/llvm-project/pull/189917
>From 1926270fae630e00ed9fc775b2be1fedffe54389 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Wed, 1 Apr 2026 08:44:47 +0000
Subject: [PATCH 1/3] [spr] initial version
Created using spr 1.3.8-wip
---
llvm/include/llvm/IR/GlobalObject.h | 37 +++++++++++++++++++++++++++--
llvm/include/llvm/IR/Instruction.h | 7 +++---
llvm/include/llvm/IR/Value.h | 35 +++------------------------
llvm/lib/IR/Globals.cpp | 8 ++++++-
llvm/lib/IR/Instruction.cpp | 11 ++++++---
llvm/lib/IR/Metadata.cpp | 29 ++++++++--------------
llvm/lib/IR/Value.cpp | 9 +++----
7 files changed, 70 insertions(+), 66 deletions(-)
diff --git a/llvm/include/llvm/IR/GlobalObject.h b/llvm/include/llvm/IR/GlobalObject.h
index d6b04001fdc09..1e03e22f0403b 100644
--- a/llvm/include/llvm/IR/GlobalObject.h
+++ b/llvm/include/llvm/IR/GlobalObject.h
@@ -144,10 +144,43 @@ class GlobalObject : public GlobalValue {
using Value::eraseMetadata;
using Value::eraseMetadataIf;
using Value::getAllMetadata;
- using Value::getMetadata;
- using Value::hasMetadata;
using Value::setMetadata;
+ /// Return true if this GlobalObject has any metadata attached to it.
+ bool hasMetadata() const { return MetadataIndex != 0; }
+
+ /// Return true if this instruction has the given type of metadata attached.
+ bool hasMetadata(unsigned KindID) const {
+ return getMetadata(KindID) != nullptr;
+ }
+
+ /// Return true if this instruction has the given type of metadata attached.
+ bool hasMetadata(StringRef Kind) const {
+ return getMetadata(Kind) != nullptr;
+ }
+
+ /// Get the metadata of given kind attached to this GlobalObject.
+ /// If the metadata is not found then return null.
+ MDNode *getMetadata(unsigned KindID) const {
+ return hasMetadata() ? getMetadataImpl(KindID) : nullptr;
+ }
+
+ /// Get the metadata of given kind attached to this GlobalObject.
+ /// If the metadata is not found then return null.
+ MDNode *getMetadata(StringRef Kind) const {
+ return hasMetadata() ? Value::getMetadata(Kind) : nullptr;
+ }
+
+ /// Appends all attachments with the given ID to \c MDs in insertion order.
+ /// If the Value has no attachments with the given ID, or if ID is invalid,
+ /// leaves MDs unchanged.
+ /// @{
+ LLVM_ABI void getMetadata(unsigned KindID,
+ SmallVectorImpl<MDNode *> &MDs) const;
+ LLVM_ABI void getMetadata(StringRef Kind,
+ SmallVectorImpl<MDNode *> &MDs) const;
+ /// @}
+
LLVM_ABI bool hasMetadataOtherThanDebugLoc() const;
/// Copy metadata from Src, adjusting offsets by Offset.
diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h
index 396d8a5f25ba3..be35f645009f5 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -439,7 +439,7 @@ class Instruction : public User,
//===--------------------------------------------------------------------===//
/// Return true if this instruction has any metadata attached to it.
- bool hasMetadata() const { return DbgLoc || Value::hasMetadata(); }
+ bool hasMetadata() const { return DbgLoc || MetadataIndex != 0; }
// Return true if this instruction contains loop metadata other than
// a debug location
@@ -447,7 +447,7 @@ class Instruction : public User,
/// Return true if this instruction has metadata attached to it other than a
/// debug location.
- bool hasMetadataOtherThanDebugLoc() const { return Value::hasMetadata(); }
+ bool hasMetadataOtherThanDebugLoc() const { return MetadataIndex != 0; }
/// Return true if this instruction has the given type of metadata attached.
bool hasMetadata(unsigned KindID) const {
@@ -465,7 +465,8 @@ class Instruction : public User,
// 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);
+ return hasMetadataOtherThanDebugLoc() ? Value::getMetadataImpl(KindID)
+ : nullptr;
}
/// Get the metadata of given kind attached to this Instruction.
diff --git a/llvm/include/llvm/IR/Value.h b/llvm/include/llvm/IR/Value.h
index b149fe55375b1..9b424a6703394 100644
--- a/llvm/include/llvm/IR/Value.h
+++ b/llvm/include/llvm/IR/Value.h
@@ -105,13 +105,12 @@ class Value {
///
/// Note, this should *NOT* be used directly by any class other than User.
/// User uses this value to find the Use list.
- enum : unsigned { NumUserOperandsBits = 27 };
+ enum : unsigned { NumUserOperandsBits = 28 };
unsigned NumUserOperands : NumUserOperandsBits;
// Use the same type as the bitfield above so that MSVC will pack them.
unsigned IsUsedByMD : 1;
unsigned HasName : 1;
- unsigned HasMetadata : 1; // Has metadata attached to this?
unsigned HasHungOffUses : 1;
unsigned HasDescriptor : 1;
@@ -574,12 +573,7 @@ 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 {
- if (!HasMetadata)
- return nullptr;
- return getMetadataImpl(KindID);
- }
- LLVM_ABI MDNode *getMetadata(StringRef Kind) const;
+ LLVM_ABI MDNode *getMetadata(StringRef Kind) const LLVM_READONLY;
/// @}
private:
@@ -587,16 +581,6 @@ class Value {
LLVM_ABI unsigned &getMetadataIndex();
protected:
- /// Appends all attachments with the given ID to \c MDs in insertion order.
- /// If the Value has no attachments with the given ID, or if ID is invalid,
- /// leaves MDs unchanged.
- /// @{
- LLVM_ABI void getMetadata(unsigned KindID,
- SmallVectorImpl<MDNode *> &MDs) const;
- LLVM_ABI void getMetadata(StringRef Kind,
- SmallVectorImpl<MDNode *> &MDs) const;
- /// @}
-
/// Appends all metadata attached to this value to \c MDs, sorting by
/// KindID. The first element of each pair returned is the KindID, the second
/// element is the metadata value. Attachments with the same ID appear in
@@ -604,19 +588,6 @@ class Value {
LLVM_ABI void
getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const;
- /// Return true if this value has any metadata attached to it.
- bool hasMetadata() const { return (bool)HasMetadata; }
-
- /// Return true if this value has the given type of metadata attached.
- /// @{
- bool hasMetadata(unsigned KindID) const {
- return getMetadata(KindID) != nullptr;
- }
- bool hasMetadata(StringRef Kind) const {
- return getMetadata(Kind) != nullptr;
- }
- /// @}
-
/// Set a particular kind of metadata attachment.
///
/// Sets the given attachment to \c MD, erasing it if \c MD is \c nullptr or
@@ -646,7 +617,7 @@ class Value {
/// Get metadata for the given kind, if any.
/// This is an internal function that must only be called after
/// checking that `hasMetadata()` returns true.
- LLVM_ABI MDNode *getMetadataImpl(unsigned KindID) const;
+ LLVM_ABI MDNode *getMetadataImpl(unsigned KindID) const LLVM_READONLY;
public:
/// Return true if this value is a swifterror value.
diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp
index 81976f389ff9d..1bd7e9605ffc7 100644
--- a/llvm/lib/IR/Globals.cpp
+++ b/llvm/lib/IR/Globals.cpp
@@ -105,7 +105,13 @@ void GlobalValue::eraseFromParent() {
llvm_unreachable("not a global");
}
-GlobalObject::~GlobalObject() { setComdat(nullptr); }
+GlobalObject::~GlobalObject() {
+ // Remove associated metadata from context.
+ if (hasMetadata())
+ clearMetadata();
+
+ setComdat(nullptr);
+}
bool GlobalValue::isInterposable() const {
if (isInterposableLinkage(getLinkage()))
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index 5205d36a228c1..d3b3e6eea53ff 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -74,9 +74,14 @@ Instruction::~Instruction() {
if (isUsedByMetadata())
ValueAsMetadata::handleRAUW(this, PoisonValue::get(getType()));
- // Explicitly remove DIAssignID metadata to clear up ID -> Instruction(s)
- // mapping in LLVMContext.
- setMetadata(LLVMContext::MD_DIAssignID, nullptr);
+ // Remove associated metadata from context.
+ if (hasMetadata()) {
+ // Explicitly remove DIAssignID metadata to clear up ID -> Instruction(s)
+ // mapping in LLVMContext.
+ // TODO: still needed?
+ setMetadata(LLVMContext::MD_DIAssignID, nullptr);
+ clearMetadata();
+ }
}
const Module *Instruction::getModule() const {
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index e3c837885de8b..4f4662df774a1 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -1558,8 +1558,6 @@ unsigned Value::getMetadataIndex() const {
}
MDNode *Value::getMetadata(StringRef Kind) const {
- if (!hasMetadata())
- return nullptr;
unsigned KindID = getContext().getMDKindID(Kind);
return getMetadataImpl(KindID);
}
@@ -1576,9 +1574,10 @@ MDNode *Value::getMetadataImpl(unsigned KindID) const {
return nullptr;
}
-void Value::getMetadata(unsigned KindID, SmallVectorImpl<MDNode *> &MDs) const {
+void GlobalObject::getMetadata(unsigned KindID,
+ SmallVectorImpl<MDNode *> &MDs) const {
const LLVMContext &Ctx = getContext();
- unsigned Idx = getMetadataIndex();
+ unsigned Idx = MetadataIndex;
while (Idx) {
const MDAttachment &A = Ctx.pImpl->Metadatas[Idx];
if (A.MDKind == KindID)
@@ -1589,7 +1588,8 @@ void Value::getMetadata(unsigned KindID, SmallVectorImpl<MDNode *> &MDs) const {
std::reverse(MDs.begin(), MDs.end());
}
-void Value::getMetadata(StringRef Kind, SmallVectorImpl<MDNode *> &MDs) const {
+void GlobalObject::getMetadata(StringRef Kind,
+ SmallVectorImpl<MDNode *> &MDs) const {
getMetadata(getContext().getMDKindID(Kind), MDs);
}
@@ -1613,20 +1613,17 @@ void Value::getAllMetadata(
void Value::setMetadata(unsigned KindID, MDNode *Node) {
assert(isa<Instruction>(this) || isa<GlobalObject>(this));
- eraseMetadata(KindID);
+ if (getMetadataIndex() != 0)
+ eraseMetadata(KindID);
if (Node)
addMetadata(KindID, *Node);
}
void Value::setMetadata(StringRef Kind, MDNode *Node) {
- if (!Node && !HasMetadata)
- return;
setMetadata(getContext().getMDKindID(Kind), Node);
}
void Value::addMetadata(unsigned KindID, MDNode &MD) {
- if (!HasMetadata)
- HasMetadata = true;
const LLVMContext &Ctx = getContext();
unsigned &Idx = getMetadataIndex();
unsigned NewIdx = Ctx.pImpl->MetadataRecycleHead;
@@ -1677,8 +1674,6 @@ void Value::eraseMetadataIf(function_ref<bool(unsigned, MDNode *)> Pred) {
Idx = &A.Next;
}
}
- if (getMetadataIndex() == 0)
- HasMetadata = false;
}
void Value::clearMetadata() {
@@ -1686,8 +1681,6 @@ void Value::clearMetadata() {
}
void Instruction::setMetadata(StringRef Kind, MDNode *Node) {
- if (!Node && !hasMetadata())
- return;
setMetadata(getContext().getMDKindID(Kind), Node);
}
@@ -1696,7 +1689,7 @@ MDNode *Instruction::getMetadataImpl(StringRef Kind) const {
unsigned KindID = Ctx.getMDKindID(Kind);
if (KindID == LLVMContext::MD_dbg)
return DbgLoc.getAsMDNode();
- return Value::getMetadata(KindID);
+ return Value::getMetadataImpl(KindID);
}
void Instruction::eraseMetadataIf(function_ref<bool(unsigned, MDNode *)> Pred) {
@@ -1707,7 +1700,7 @@ void Instruction::eraseMetadataIf(function_ref<bool(unsigned, MDNode *)> Pred) {
}
void Instruction::dropUnknownNonDebugMetadata(ArrayRef<unsigned> KnownIDs) {
- if (!Value::hasMetadata())
+ if (!hasMetadataOtherThanDebugLoc())
return; // Nothing to remove!
SmallSet<unsigned, 32> KnownSet(llvm::from_range, KnownIDs);
@@ -1824,9 +1817,7 @@ void Instruction::addAnnotationMetadata(StringRef Name) {
AAMDNodes Instruction::getAAMetadata() const {
AAMDNodes Result;
- // Not using Instruction::hasMetadata() because we're not interested in
- // DebugInfoMetadata.
- if (Value::hasMetadata()) {
+ if (hasMetadataOtherThanDebugLoc()) {
unsigned Idx = MetadataIndex;
const auto &Metadatas = getContext().pImpl->Metadatas;
while (Idx) {
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index 0bb493438b13b..360bf0f8fc47f 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -53,7 +53,7 @@ static inline Type *checkType(Type *Ty) {
Value::Value(Type *ty, unsigned scid)
: SubclassID(scid), HasValueHandle(0), SubclassOptionalData(0),
SubclassData(0), NumUserOperands(0), IsUsedByMD(false), HasName(false),
- HasMetadata(false), VTy(checkType(ty)) {
+ VTy(checkType(ty)) {
static_assert(ConstantFirstVal == 0, "!(SubclassID < ConstantFirstVal)");
// FIXME: Why isn't this in the subclass gunk??
// Note, we cannot call isa<CallInst> before the CallInst has been
@@ -80,10 +80,6 @@ Value::~Value() {
if (isUsedByMetadata())
ValueAsMetadata::handleDeletion(this);
- // Remove associated metadata from context.
- if (HasMetadata)
- clearMetadata();
-
#ifndef NDEBUG // Only in -g mode...
// Check to make sure that there are no uses of this value that are still
// around when the value is destroyed. If there are, then we have a dangling
@@ -848,7 +844,8 @@ bool Value::canBeFreed() const {
return false;
}
- if (isa<IntToPtrInst>(this) && getMetadata(LLVMContext::MD_nofree))
+ if (auto *ITP = dyn_cast<IntToPtrInst>(this);
+ ITP && ITP->hasMetadata(LLVMContext::MD_nofree))
return false;
const Function *F = nullptr;
>From eed5592b0cdc33a2bdb5d339981bb5b76c5a5392 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Wed, 1 Apr 2026 10:06:29 +0000
Subject: [PATCH 2/3] fix perf regression
Created using spr 1.3.8-wip
---
llvm/lib/IR/Instruction.cpp | 3 +--
llvm/lib/IR/Metadata.cpp | 2 ++
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index d3b3e6eea53ff..8aa19a436a157 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -78,8 +78,7 @@ Instruction::~Instruction() {
if (hasMetadata()) {
// Explicitly remove DIAssignID metadata to clear up ID -> Instruction(s)
// mapping in LLVMContext.
- // TODO: still needed?
- setMetadata(LLVMContext::MD_DIAssignID, nullptr);
+ updateDIAssignIDMapping(nullptr);
clearMetadata();
}
}
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 4f4662df774a1..80db7824b754c 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -1620,6 +1620,8 @@ void Value::setMetadata(unsigned KindID, MDNode *Node) {
}
void Value::setMetadata(StringRef Kind, MDNode *Node) {
+ if (!Node && getMetadataIndex() == 0)
+ return;
setMetadata(getContext().getMDKindID(Kind), Node);
}
>From 853cbc2ed1b8bd49b2e3e8e276300531732e160d Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Wed, 1 Apr 2026 10:46:01 +0000
Subject: [PATCH 3/3] second attempt of perf regression fix...
Created using spr 1.3.8-wip
---
llvm/lib/IR/Metadata.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 80db7824b754c..82f224438eec5 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -1683,6 +1683,8 @@ void Value::clearMetadata() {
}
void Instruction::setMetadata(StringRef Kind, MDNode *Node) {
+ if (!Node && MetadataIndex == 0)
+ return;
setMetadata(getContext().getMDKindID(Kind), Node);
}
More information about the llvm-commits
mailing list