[llvm] [ADT] Move llvm::identity into IndexedMap (NFC) (PR #164568)

Kazu Hirata via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 22 13:16:27 PDT 2025


https://github.com/kazutakahirata updated https://github.com/llvm/llvm-project/pull/164568

>From 1c04cee59adae37c3bec49d93763c11425e7e96c Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Sun, 19 Oct 2025 18:02:42 -0700
Subject: [PATCH 1/4] [ADT] Modernize IndexedMap to use llvm::identity_cxx20
 (NFC)

The legacy llvm::identity differs from std::identity in C++20.
llvm::identity is a template struct with an ::argument_type member. In
contrast, llvm::identity_cxx20 (and std::identity) is a non-template
struct with a templated call operator and no ::argument_type.

This patch modernizes llvm::IndexedMap by updating its default functor
to llvm::identity_cxx20.  A new template parameter IndexT now
fulfills the role of ::argument_type.

To avoid modifying numerous existing IndexedMap uses with custom
functors (e.g., VirtReg2IndexFunctor), the detail::DeduceIndexType
helper automatically deduces IndexT.  It deduces ::argument_type for
legacy functors and unsigned for llvm::identity_cxx20.
---
 llvm/include/llvm/ADT/IndexedMap.h | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/ADT/IndexedMap.h b/llvm/include/llvm/ADT/IndexedMap.h
index cda0316dc78fa..8526db9cdf4e8 100644
--- a/llvm/include/llvm/ADT/IndexedMap.h
+++ b/llvm/include/llvm/ADT/IndexedMap.h
@@ -21,14 +21,33 @@
 #define LLVM_ADT_INDEXEDMAP_H
 
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/identity.h"
 #include <cassert>
+#include <type_traits>
 
 namespace llvm {
 
-template <typename T, typename ToIndexT = identity<unsigned>> class IndexedMap {
-  using IndexT = typename ToIndexT::argument_type;
+namespace detail {
+// Helper to compute the IndexT for IndexedMap.
+template <typename ToIndexT, typename = void> struct DeduceIndexType {
+  using type =
+      std::conditional_t<std::is_same_v<ToIndexT, llvm::identity_cxx20>,
+                         unsigned, void>;
+};
+
+template <typename ToIndexT>
+struct DeduceIndexType<ToIndexT,
+                       std::void_t<typename ToIndexT::argument_type>> {
+  using type = typename ToIndexT::argument_type;
+};
+} // namespace detail
+
+template <typename T, typename ToIndexT = llvm::identity_cxx20,
+          typename IndexT = typename detail::DeduceIndexType<ToIndexT>::type>
+class IndexedMap {
+  static_assert(!std::is_same_v<IndexT, void>,
+                "Could not deduce index type from the provided functor.");
   // Prefer SmallVector with zero inline storage over std::vector. IndexedMaps
   // can grow very large and SmallVector grows more efficiently as long as T
   // is trivially copyable.

>From 8869a6e3754a205681f7d25677c45e9c8b909a84 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Wed, 22 Oct 2025 07:56:35 -0700
Subject: [PATCH 2/4] [ADT] Modernize IndexedMap with llvm::identity_cxx20
 (NFC)

C++ is evolving in the direction of removing type alias
"argument_type" from functors.

This patch changes the default functor type to llvm::identity_cxx20,
backported from C++20, while templatizing those methods that use
toIndex_ with IndexT.  This way we no longer need to take
argument_type from ToIndexT.

Now, identity_cxx20()(int) is of type int, causing mixed sign
comparisons, so this patch first assigns the result to a temporary
variable of type unsigned before feeding it to assert.
---
 llvm/include/llvm/ADT/IndexedMap.h | 42 ++++++++++--------------------
 1 file changed, 14 insertions(+), 28 deletions(-)

diff --git a/llvm/include/llvm/ADT/IndexedMap.h b/llvm/include/llvm/ADT/IndexedMap.h
index 8526db9cdf4e8..e6b8c36ceed8a 100644
--- a/llvm/include/llvm/ADT/IndexedMap.h
+++ b/llvm/include/llvm/ADT/IndexedMap.h
@@ -20,34 +20,14 @@
 #ifndef LLVM_ADT_INDEXEDMAP_H
 #define LLVM_ADT_INDEXEDMAP_H
 
-#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/SmallVector.h"
 #include <cassert>
-#include <type_traits>
 
 namespace llvm {
 
-namespace detail {
-// Helper to compute the IndexT for IndexedMap.
-template <typename ToIndexT, typename = void> struct DeduceIndexType {
-  using type =
-      std::conditional_t<std::is_same_v<ToIndexT, llvm::identity_cxx20>,
-                         unsigned, void>;
-};
-
-template <typename ToIndexT>
-struct DeduceIndexType<ToIndexT,
-                       std::void_t<typename ToIndexT::argument_type>> {
-  using type = typename ToIndexT::argument_type;
-};
-} // namespace detail
-
-template <typename T, typename ToIndexT = llvm::identity_cxx20,
-          typename IndexT = typename detail::DeduceIndexType<ToIndexT>::type>
+template <typename T, typename ToIndexT = llvm::identity_cxx20>
 class IndexedMap {
-  static_assert(!std::is_same_v<IndexT, void>,
-                "Could not deduce index type from the provided functor.");
   // Prefer SmallVector with zero inline storage over std::vector. IndexedMaps
   // can grow very large and SmallVector grows more efficiently as long as T
   // is trivially copyable.
@@ -62,14 +42,17 @@ class IndexedMap {
 
   explicit IndexedMap(const T &val) : nullVal_(val) {}
 
-  typename StorageT::reference operator[](IndexT n) {
-    assert(toIndex_(n) < storage_.size() && "index out of bounds!");
-    return storage_[toIndex_(n)];
+  template <typename IndexT> typename StorageT::reference operator[](IndexT n) {
+    unsigned Index = toIndex_(n);
+    assert(Index < storage_.size() && "index out of bounds!");
+    return storage_[Index];
   }
 
+  template <typename IndexT>
   typename StorageT::const_reference operator[](IndexT n) const {
-    assert(toIndex_(n) < storage_.size() && "index out of bounds!");
-    return storage_[toIndex_(n)];
+    unsigned Index = toIndex_(n);
+    assert(Index < storage_.size() && "index out of bounds!");
+    return storage_[Index];
   }
 
   void reserve(typename StorageT::size_type s) { storage_.reserve(s); }
@@ -78,13 +61,16 @@ class IndexedMap {
 
   void clear() { storage_.clear(); }
 
-  void grow(IndexT n) {
+  template <typename IndexT> void grow(IndexT n) {
     unsigned NewSize = toIndex_(n) + 1;
     if (NewSize > storage_.size())
       resize(NewSize);
   }
 
-  bool inBounds(IndexT n) const { return toIndex_(n) < storage_.size(); }
+  template <typename IndexT> bool inBounds(IndexT n) const {
+    unsigned Index = toIndex_(n);
+    return Index < storage_.size();
+  }
 
   typename StorageT::size_type size() const { return storage_.size(); }
 };

>From 20e337977fd4b63e2ba306e852b949b1ad56343a Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Wed, 22 Oct 2025 12:32:29 -0700
Subject: [PATCH 3/4] [ADT] Move llvm::identity into IndexedMap (NFC)

This patch moves llvm::identity to IndexedMap for two reasons:

- llvm::identity is used only IndexedMap.
- llvm::identity is not suitable for general use as it is not quite
  the same as std::identity despite the comments in identity.h.

Also, this patch renames the class to IdentityIndex and places it in
the "detail" namespace.
---
 llvm/include/llvm/ADT/IndexedMap.h            | 35 +++++++++++--------
 llvm/include/llvm/ADT/identity.h              | 31 ----------------
 llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h |  1 -
 3 files changed, 20 insertions(+), 47 deletions(-)
 delete mode 100644 llvm/include/llvm/ADT/identity.h

diff --git a/llvm/include/llvm/ADT/IndexedMap.h b/llvm/include/llvm/ADT/IndexedMap.h
index e6b8c36ceed8a..fca7981270dbb 100644
--- a/llvm/include/llvm/ADT/IndexedMap.h
+++ b/llvm/include/llvm/ADT/IndexedMap.h
@@ -20,14 +20,25 @@
 #ifndef LLVM_ADT_INDEXEDMAP_H
 #define LLVM_ADT_INDEXEDMAP_H
 
-#include "llvm/ADT/STLForwardCompat.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include <cassert>
 
 namespace llvm {
 
-template <typename T, typename ToIndexT = llvm::identity_cxx20>
+namespace detail {
+template <class Ty> struct IdentityIndex {
+  using is_transparent = void;
+  using argument_type = Ty;
+
+  Ty &operator()(Ty &self) const { return self; }
+  const Ty &operator()(const Ty &self) const { return self; }
+};
+} // namespace detail
+
+template <typename T, typename ToIndexT = detail::IdentityIndex<unsigned>>
 class IndexedMap {
+  using IndexT = typename ToIndexT::argument_type;
   // Prefer SmallVector with zero inline storage over std::vector. IndexedMaps
   // can grow very large and SmallVector grows more efficiently as long as T
   // is trivially copyable.
@@ -42,17 +53,14 @@ class IndexedMap {
 
   explicit IndexedMap(const T &val) : nullVal_(val) {}
 
-  template <typename IndexT> typename StorageT::reference operator[](IndexT n) {
-    unsigned Index = toIndex_(n);
-    assert(Index < storage_.size() && "index out of bounds!");
-    return storage_[Index];
+  typename StorageT::reference operator[](IndexT n) {
+    assert(toIndex_(n) < storage_.size() && "index out of bounds!");
+    return storage_[toIndex_(n)];
   }
 
-  template <typename IndexT>
   typename StorageT::const_reference operator[](IndexT n) const {
-    unsigned Index = toIndex_(n);
-    assert(Index < storage_.size() && "index out of bounds!");
-    return storage_[Index];
+    assert(toIndex_(n) < storage_.size() && "index out of bounds!");
+    return storage_[toIndex_(n)];
   }
 
   void reserve(typename StorageT::size_type s) { storage_.reserve(s); }
@@ -61,16 +69,13 @@ class IndexedMap {
 
   void clear() { storage_.clear(); }
 
-  template <typename IndexT> void grow(IndexT n) {
+  void grow(IndexT n) {
     unsigned NewSize = toIndex_(n) + 1;
     if (NewSize > storage_.size())
       resize(NewSize);
   }
 
-  template <typename IndexT> bool inBounds(IndexT n) const {
-    unsigned Index = toIndex_(n);
-    return Index < storage_.size();
-  }
+  bool inBounds(IndexT n) const { return toIndex_(n) < storage_.size(); }
 
   typename StorageT::size_type size() const { return storage_.size(); }
 };
diff --git a/llvm/include/llvm/ADT/identity.h b/llvm/include/llvm/ADT/identity.h
deleted file mode 100644
index 88d033fc01141..0000000000000
--- a/llvm/include/llvm/ADT/identity.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//===- llvm/ADT/Identity.h - Provide std::identity from C++20 ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides an implementation of std::identity from C++20.
-//
-// No library is required when using these functions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ADT_IDENTITY_H
-#define LLVM_ADT_IDENTITY_H
-
-namespace llvm {
-
-// Similar to `std::identity` from C++20.
-template <class Ty> struct identity {
-  using is_transparent = void;
-  using argument_type = Ty;
-
-  Ty &operator()(Ty &self) const { return self; }
-  const Ty &operator()(const Ty &self) const { return self; }
-};
-
-} // namespace llvm
-
-#endif // LLVM_ADT_IDENTITY_H
diff --git a/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h b/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h
index 4eacbdca163d9..26d708060ed6d 100644
--- a/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -18,7 +18,6 @@
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/SparseMultiSet.h"
-#include "llvm/ADT/identity.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/CodeGen/LiveRegUnits.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"

>From c8eeafb8e05bb2ce5cdd2d973091f3373111e886 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Wed, 22 Oct 2025 13:13:13 -0700
Subject: [PATCH 4/4] Address a comment.

---
 llvm/include/llvm/ADT/IndexedMap.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/include/llvm/ADT/IndexedMap.h b/llvm/include/llvm/ADT/IndexedMap.h
index fca7981270dbb..638fe14bfe797 100644
--- a/llvm/include/llvm/ADT/IndexedMap.h
+++ b/llvm/include/llvm/ADT/IndexedMap.h
@@ -28,7 +28,6 @@ namespace llvm {
 
 namespace detail {
 template <class Ty> struct IdentityIndex {
-  using is_transparent = void;
   using argument_type = Ty;
 
   Ty &operator()(Ty &self) const { return self; }



More information about the llvm-commits mailing list