[llvm] aeefb10 - [IR] Simplify ValueAsMetadata::handleRAUW. NFC (#223301)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 13 23:35:54 PDT 2026
Author: Fangrui Song
Date: 2026-09-13T23:35:49-07:00
New Revision: aeefb10b01fb7cf11a1917230f10b663d5ec109b
URL: https://github.com/llvm/llvm-project/commit/aeefb10b01fb7cf11a1917230f10b663d5ec109b
DIFF: https://github.com/llvm/llvm-project/commit/aeefb10b01fb7cf11a1917230f10b663d5ec109b.diff
LOG: [IR] Simplify ValueAsMetadata::handleRAUW. NFC (#223301)
Metadata refers to a Value through its unique ValueAsMetadata wrapper.
When a Value is RAUW'd, handleRAUW reuses the old value's wrapper for
the new value if the new value has none yet; otherwise it moves the uses
to the new value's wrapper, with special cases for a local becoming a
constant, a constant becoming a local, and a value moving to another
function.
Always move the uses (or drop them in the last two cases) and delete the
old wrapper, so that a ValueAsMetadata wraps the same value for its
whole life.
Instruction counts for SLPVectorizer.cpp and X86ISelLowering.cpp at -O2
-g are unchanged (-0.04%, -0.01%).
Aided by Opus 5
Added:
Modified:
llvm/lib/IR/Metadata.cpp
llvm/unittests/IR/MetadataTest.cpp
Removed:
################################################################################
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index fc03bf4a87eb1..87766f4d47437 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -551,15 +551,13 @@ void ValueAsMetadata::handleRAUW(Value *From, Value *To) {
assert(From != To && "Expected changed value");
assert(&From->getContext() == &To->getContext() && "Expected same context");
- LLVMContext &Context = From->getType()->getContext();
- auto &Store = Context.pImpl->ValuesAsMetadata;
+ auto &Store = From->getContext().pImpl->ValuesAsMetadata;
auto I = Store.find(From);
if (I == Store.end()) {
assert(!From->IsUsedByMD && "Expected From not to be used by metadata");
return;
}
- // Remove old entry from the map.
assert(From->IsUsedByMD && "Expected From to be used by metadata");
From->IsUsedByMD = false;
ValueAsMetadata *MD = I->second;
@@ -567,40 +565,19 @@ void ValueAsMetadata::handleRAUW(Value *From, Value *To) {
assert(MD->getValue() == From && "Expected valid mapping");
Store.erase(I);
- if (isa<LocalAsMetadata>(MD)) {
- if (auto *C = dyn_cast<Constant>(To)) {
- // Local became a constant.
- MD->replaceAllUsesWith(ConstantAsMetadata::get(C));
- delete MD;
- return;
- }
- if (getLocalFunctionMetadata(From) && getLocalFunctionMetadata(To) &&
- getLocalFunctionMetadata(From) != getLocalFunctionMetadata(To)) {
- // DISubprogram changed.
- MD->replaceAllUsesWith(nullptr);
- delete MD;
- return;
- }
- } else if (!isa<Constant>(To)) {
- // Changed to function-local value.
- MD->replaceAllUsesWith(nullptr);
- delete MD;
- return;
- }
-
- auto *&Entry = Store[To];
- if (Entry) {
- // The target already exists.
- MD->replaceAllUsesWith(Entry);
- delete MD;
- return;
- }
-
- // Update MD in place (and update the map entry).
- assert(!To->IsUsedByMD && "Expected this to be the only metadata use");
- To->IsUsedByMD = true;
- MD->V = To;
- Entry = MD;
+ // Move the uses to To's node. Uses of a function-local value are dropped if
+ // it becomes a local of another function or replaces a constant.
+ Metadata *New = nullptr;
+ if (isa<Constant>(To)) {
+ New = ValueAsMetadata::get(To);
+ } else if (isa<LocalAsMetadata>(MD)) {
+ DISubprogram *FromSP = getLocalFunctionMetadata(From);
+ DISubprogram *ToSP = FromSP ? getLocalFunctionMetadata(To) : nullptr;
+ if (!FromSP || !ToSP || FromSP == ToSP)
+ New = ValueAsMetadata::get(To);
+ }
+ MD->replaceAllUsesWith(New);
+ delete MD;
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index cb0096d8f4a2c..8edff02ca0b16 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -5209,9 +5209,12 @@ TEST_F(ValueAsMetadataTest, UpdatesOnRAUW) {
EXPECT_TRUE(MD->getValue() == GV0.get());
ASSERT_TRUE(GV0->use_empty());
+ TrackingMDRef Ref(MD);
std::unique_ptr<GlobalVariable> GV1(
new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
+ // RAUW updates `Ref`.
GV0->replaceAllUsesWith(GV1.get());
+ MD = cast<ValueAsMetadata>(Ref.get());
EXPECT_TRUE(MD->getValue() == GV1.get());
}
@@ -5224,11 +5227,13 @@ TEST_F(ValueAsMetadataTest, handleRAUWWithTypeChange) {
auto *I32Poison = PoisonValue::get(Type::getInt32Ty(Context));
auto *I64Poison = PoisonValue::get(Type::getInt64Ty(Context));
auto *MD = ConstantAsMetadata::get(I32Poison);
+ TrackingMDRef Ref(MD);
EXPECT_EQ(MD->getValue(), I32Poison);
EXPECT_NE(MD->getValue(), I64Poison);
ValueAsMetadata::handleRAUW(I32Poison, I64Poison);
+ MD = cast<ConstantAsMetadata>(Ref.get());
EXPECT_NE(MD->getValue(), I32Poison);
EXPECT_EQ(MD->getValue(), I64Poison);
More information about the llvm-commits
mailing list