[llvm] [MapVector] Introduce {keys, values} iterator, use in VPlan (PR #169675)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 26 08:59:36 PST 2025
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/169675
>From c19124a3d4ce8a07f5be0b4c8f63fb77947e62c1 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Wed, 26 Nov 2025 15:07:04 +0000
Subject: [PATCH 1/2] [MapVector] Introduce {keys,values} iterator, use in
VPlan
Similar to DenseMap::{keys,values}, introduce MapVector::{keys,values},
and use it to simplify some code in VPlan.
---
llvm/include/llvm/ADT/MapVector.h | 20 +++++++++++++++++
llvm/lib/Transforms/Vectorize/VPlan.h | 26 ++++++----------------
llvm/lib/Transforms/Vectorize/VPlanValue.h | 5 -----
llvm/unittests/ADT/MapVectorTest.cpp | 18 +++++++++++++++
4 files changed, 45 insertions(+), 24 deletions(-)
diff --git a/llvm/include/llvm/ADT/MapVector.h b/llvm/include/llvm/ADT/MapVector.h
index 80bcb7e0b7ba4..b1e543e282a03 100644
--- a/llvm/include/llvm/ADT/MapVector.h
+++ b/llvm/include/llvm/ADT/MapVector.h
@@ -99,6 +99,26 @@ class MapVector {
return try_emplace_impl(Key).first->second;
}
+ [[nodiscard]] inline auto keys() {
+ return map_range(
+ Vector, [](const std::pair<KeyT, ValueT> &KV) { return KV.first; });
+ }
+
+ [[nodiscard]] inline auto values() {
+ return map_range(
+ Vector, [](const std::pair<KeyT, ValueT> &KV) { return KV.second; });
+ }
+
+ [[nodiscard]] inline auto keys() const {
+ return map_range(
+ Vector, [](const std::pair<KeyT, ValueT> &KV) { return KV.first; });
+ }
+
+ [[nodiscard]] inline auto values() const {
+ return map_range(
+ Vector, [](const std::pair<KeyT, ValueT> &KV) { return KV.second; });
+ }
+
// Returns a copy of the value. Only allowed if ValueT is copyable.
[[nodiscard]] ValueT lookup(const KeyT &Key) const {
static_assert(std::is_copy_constructible_v<ValueT>,
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index 0c7d9c0193a03..b22d2083adf0b 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -25,7 +25,7 @@
#define LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
#include "VPlanValue.h"
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
@@ -4336,13 +4336,9 @@ class VPlan {
/// Represents the loop-invariant VF * UF of the vector loop region.
VPValue VFxUF;
- /// Holds a mapping between Values and their corresponding VPValue inside
- /// VPlan.
- Value2VPValueTy Value2VPValue;
-
- /// Contains all the external definitions created for this VPlan. External
- /// definitions are VPValues that hold a pointer to their underlying IR.
- SmallVector<VPValue *, 16> VPLiveIns;
+ /// Contains all the external definitions created for this VPlan, as a mapping
+ /// from IR Values to VPValues.
+ SmallMapVector<Value *, VPValue *, 16> LiveIns;
/// Blocks allocated and owned by the VPlan. They will be deleted once the
/// VPlan is destroyed.
@@ -4539,10 +4535,9 @@ class VPlan {
/// yet) for \p V.
VPValue *getOrAddLiveIn(Value *V) {
assert(V && "Trying to get or add the VPValue of a null Value");
- auto [It, Inserted] = Value2VPValue.try_emplace(V);
+ auto [It, Inserted] = LiveIns.try_emplace(V);
if (Inserted) {
VPValue *VPV = new VPValue(V);
- VPLiveIns.push_back(VPV);
assert(VPV->isLiveIn() && "VPV must be a live-in.");
It->second = VPV;
}
@@ -4574,17 +4569,10 @@ class VPlan {
}
/// Return the live-in VPValue for \p V, if there is one or nullptr otherwise.
- VPValue *getLiveIn(Value *V) const { return Value2VPValue.lookup(V); }
+ VPValue *getLiveIn(Value *V) const { return LiveIns.lookup(V); }
/// Return the list of live-in VPValues available in the VPlan.
- ArrayRef<VPValue *> getLiveIns() const {
- assert(all_of(Value2VPValue,
- [this](const auto &P) {
- return is_contained(VPLiveIns, P.second);
- }) &&
- "all VPValues in Value2VPValue must also be in VPLiveIns");
- return VPLiveIns;
- }
+ auto getLiveIns() const { return LiveIns.values(); }
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
/// Print the live-ins of this VPlan to \p O.
diff --git a/llvm/lib/Transforms/Vectorize/VPlanValue.h b/llvm/lib/Transforms/Vectorize/VPlanValue.h
index 63eacd3d75721..6d7c8312afa7b 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanValue.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanValue.h
@@ -20,10 +20,8 @@
#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLAN_VALUE_H
#define LLVM_TRANSFORMS_VECTORIZE_VPLAN_VALUE_H
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Compiler.h"
@@ -196,9 +194,6 @@ class LLVM_ABI_FOR_TEST VPValue {
}
};
-typedef DenseMap<Value *, VPValue *> Value2VPValueTy;
-typedef DenseMap<VPValue *, Value *> VPValue2ValueTy;
-
LLVM_ABI_FOR_TEST raw_ostream &operator<<(raw_ostream &OS,
const VPRecipeBase &R);
diff --git a/llvm/unittests/ADT/MapVectorTest.cpp b/llvm/unittests/ADT/MapVectorTest.cpp
index e0589445e3271..b11d4603b90b7 100644
--- a/llvm/unittests/ADT/MapVectorTest.cpp
+++ b/llvm/unittests/ADT/MapVectorTest.cpp
@@ -307,6 +307,24 @@ TEST(MapVectorTest, AtTest) {
EXPECT_EQ(ConstMV.at(1), 12);
}
+TEST(MapVectorTest, KeysValuesIterator) {
+ MapVector<int, int> MV;
+
+ MV.insert(std::make_pair(1, 11));
+ MV.insert(std::make_pair(2, 12));
+ MV.insert(std::make_pair(3, 13));
+ MV.insert(std::make_pair(4, 14));
+ MV.insert(std::make_pair(5, 15));
+ MV.insert(std::make_pair(6, 16));
+
+ EXPECT_THAT(MV.keys(), testing::ElementsAre(1, 2, 3, 4, 5, 6));
+ EXPECT_THAT(MV.values(), testing::ElementsAre(11, 12, 13, 14, 15, 16));
+
+ const MapVector<int, int> &ConstMV = MV;
+ EXPECT_THAT(ConstMV.keys(), testing::ElementsAre(1, 2, 3, 4, 5, 6));
+ EXPECT_THAT(ConstMV.values(), testing::ElementsAre(11, 12, 13, 14, 15, 16));
+}
+
template <class IntType> struct MapVectorMappedTypeTest : ::testing::Test {
using int_type = IntType;
};
>From 6a0618152e16c5d686b02d49a40a5f46948f527b Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Wed, 26 Nov 2025 16:57:20 +0000
Subject: [PATCH 2/2] [MapVector] Use make_(first|second)_range
---
llvm/include/llvm/ADT/MapVector.h | 23 ++++-------------------
1 file changed, 4 insertions(+), 19 deletions(-)
diff --git a/llvm/include/llvm/ADT/MapVector.h b/llvm/include/llvm/ADT/MapVector.h
index b1e543e282a03..250504dbaf52a 100644
--- a/llvm/include/llvm/ADT/MapVector.h
+++ b/llvm/include/llvm/ADT/MapVector.h
@@ -99,25 +99,10 @@ class MapVector {
return try_emplace_impl(Key).first->second;
}
- [[nodiscard]] inline auto keys() {
- return map_range(
- Vector, [](const std::pair<KeyT, ValueT> &KV) { return KV.first; });
- }
-
- [[nodiscard]] inline auto values() {
- return map_range(
- Vector, [](const std::pair<KeyT, ValueT> &KV) { return KV.second; });
- }
-
- [[nodiscard]] inline auto keys() const {
- return map_range(
- Vector, [](const std::pair<KeyT, ValueT> &KV) { return KV.first; });
- }
-
- [[nodiscard]] inline auto values() const {
- return map_range(
- Vector, [](const std::pair<KeyT, ValueT> &KV) { return KV.second; });
- }
+ [[nodiscard]] inline auto keys() { return make_first_range(Vector); }
+ [[nodiscard]] inline auto values() { return make_second_range(Vector); }
+ [[nodiscard]] inline auto keys() const { return make_first_range(Vector); }
+ [[nodiscard]] inline auto values() const { return make_second_range(Vector); }
// Returns a copy of the value. Only allowed if ValueT is copyable.
[[nodiscard]] ValueT lookup(const KeyT &Key) const {
More information about the llvm-commits
mailing list