[clang-tools-extra] cea0eea - [llvm] Split out DenseMapInfo<variant> specialization

Elliot Goodrich via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 21 22:52:18 PDT 2023


Author: Elliot Goodrich
Date: 2023-06-22T06:50:54+01:00
New Revision: cea0eea28e71204bf8543ca94dbf185cbf597ca5

URL: https://github.com/llvm/llvm-project/commit/cea0eea28e71204bf8543ca94dbf185cbf597ca5
DIFF: https://github.com/llvm/llvm-project/commit/cea0eea28e71204bf8543ca94dbf185cbf597ca5.diff

LOG: [llvm] Split out DenseMapInfo<variant> specialization

Remove the `DenseMapInfo<std::variant<Ts...>>` variant out from
`llvm/ADT/DenseMapInfo.h` into a separate header
`llvm/ADT/DenseMapInfoVariant.h`

This allows us to remove the `<variant>` include, which is being
transitively and unncessary included in all translation units that
include `llvm/ADT/DenseMap.h`.

There have been similar changes to move out specializations for

    * `APInt.h` fd7e309e02fd226b0390888388ed732608e52c73 and
    * `StringRef.h`/`ArrayRef.h`
      983565a6fe4a9f40c7caf82b65c650c20dbcc104

to reduce the compilation time. As we are unable to move the
specialization into `<variant>`, we create a separate
`DenseMapInfoVariant.h` header that can be used by anyone who needs this
specialization.

This reduces the total number of preprocessing tokens across the LLVM
source files in lib from (roughly) 1,964,876,961 to 1,936,551,496 - a
reduction of ~1.44%. This should result in a small improvement in
compilation time.

Differential Revision: https://reviews.llvm.org/D150997

Added: 
    llvm/include/llvm/ADT/DenseMapInfoVariant.h

Modified: 
    clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h
    flang/include/flang/Optimizer/HLFIR/HLFIROps.h
    llvm/include/llvm/ADT/DenseMapInfo.h
    llvm/include/llvm/CodeGen/CallingConvLower.h
    llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
    llvm/include/llvm/Object/DXContainer.h
    llvm/include/llvm/Transforms/Scalar/SROA.h
    llvm/unittests/ADT/DenseMapTest.cpp
    mlir/include/mlir/IR/AsmState.h
    mlir/include/mlir/Transforms/SROA.h

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h
index 0f7fd1cfafa6b..48b018b382ba5 100644
--- a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h
+++ b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h
@@ -26,10 +26,12 @@
 #include "clang/Tooling/Inclusions/StandardLibrary.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseMapInfoVariant.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include <memory>
 #include <utility>
+#include <variant>
 #include <vector>
 
 namespace llvm {

diff  --git a/flang/include/flang/Optimizer/HLFIR/HLFIROps.h b/flang/include/flang/Optimizer/HLFIR/HLFIROps.h
index 26bfc9a805dcc..ab426256c5aa5 100644
--- a/flang/include/flang/Optimizer/HLFIR/HLFIROps.h
+++ b/flang/include/flang/Optimizer/HLFIR/HLFIROps.h
@@ -19,6 +19,7 @@
 #include "mlir/IR/PatternMatch.h"
 #include "mlir/Interfaces/InferTypeOpInterface.h"
 #include "mlir/Interfaces/SideEffectInterfaces.h"
+#include <variant>
 
 #include "flang/Optimizer/HLFIR/HLFIROpInterfaces.h.inc"
 #define GET_OP_CLASSES

diff  --git a/llvm/include/llvm/ADT/DenseMapInfo.h b/llvm/include/llvm/ADT/DenseMapInfo.h
index 2c227be0082ab..5b7dce7b53c62 100644
--- a/llvm/include/llvm/ADT/DenseMapInfo.h
+++ b/llvm/include/llvm/ADT/DenseMapInfo.h
@@ -20,7 +20,6 @@
 #include <tuple>
 #include <type_traits>
 #include <utility>
-#include <variant>
 
 namespace llvm {
 
@@ -234,6 +233,14 @@ struct DenseMapInfo<std::pair<T, U>> {
                                     SecondInfo::getHashValue(PairVal.second));
   }
 
+  // Expose an additional function intended to be used by other
+  // specializations of DenseMapInfo without needing to know how
+  // to combine hash values manually
+  static unsigned getHashValuePiecewise(const T &First, const U &Second) {
+    return detail::combineHashValue(FirstInfo::getHashValue(First),
+                                    SecondInfo::getHashValue(Second));
+  }
+
   static bool isEqual(const Pair &LHS, const Pair &RHS) {
     return FirstInfo::isEqual(LHS.first, RHS.first) &&
            SecondInfo::isEqual(LHS.second, RHS.second);
@@ -290,52 +297,6 @@ template <typename... Ts> struct DenseMapInfo<std::tuple<Ts...>> {
   }
 };
 
-// Provide DenseMapInfo for variants whose all alternatives have DenseMapInfo.
-template <typename... Ts> struct DenseMapInfo<std::variant<Ts...>> {
-  using Variant = std::variant<Ts...>;
-  using FirstT = std::variant_alternative_t<0, Variant>;
-
-  static inline Variant getEmptyKey() {
-    return Variant(std::in_place_index<0>, DenseMapInfo<FirstT>::getEmptyKey());
-  }
-
-  static inline Variant getTombstoneKey() {
-    return Variant(std::in_place_index<0>,
-                   DenseMapInfo<FirstT>::getTombstoneKey());
-  }
-
-  static unsigned getHashValue(const Variant &Val) {
-    return std::visit(
-        [&Val](auto &&Alternative) {
-          using T = std::decay_t<decltype(Alternative)>;
-          // Include index in hash to make sure same value as 
diff erent
-          // alternatives don't collide.
-          return detail::combineHashValue(
-              DenseMapInfo<size_t>::getHashValue(Val.index()),
-              DenseMapInfo<T>::getHashValue(Alternative));
-        },
-        Val);
-  }
-
-  static bool isEqual(const Variant &LHS, const Variant &RHS) {
-    if (LHS.index() != RHS.index())
-      return false;
-    if (LHS.valueless_by_exception())
-      return true;
-    // We want to dispatch to DenseMapInfo<T>::isEqual(LHS.get(I), RHS.get(I))
-    // We know the types are the same, but std::visit(V, LHS, RHS) doesn't.
-    // We erase the type held in LHS to void*, and dispatch over RHS.
-    const void *ErasedLHS =
-        std::visit([](const auto &LHS) -> const void * { return &LHS; }, LHS);
-    return std::visit(
-        [&](const auto &RHS) -> bool {
-          using T = std::remove_cv_t<std::remove_reference_t<decltype(RHS)>>;
-          return DenseMapInfo<T>::isEqual(*static_cast<const T *>(ErasedLHS),
-                                          RHS);
-        },
-        RHS);
-  }
-};
 } // end namespace llvm
 
 #endif // LLVM_ADT_DENSEMAPINFO_H

diff  --git a/llvm/include/llvm/ADT/DenseMapInfoVariant.h b/llvm/include/llvm/ADT/DenseMapInfoVariant.h
new file mode 100644
index 0000000000000..a97f9b9566c81
--- /dev/null
+++ b/llvm/include/llvm/ADT/DenseMapInfoVariant.h
@@ -0,0 +1,71 @@
+//===- DenseMapInfoVariant.h - Type traits for DenseMap<variant> *- 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file defines DenseMapInfo traits for DenseMap<std::variant<Ts...>>.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DENSEMAPINFOVARIANT_H
+#define LLVM_ADT_DENSEMAPINFOVARIANT_H
+
+#include "llvm/ADT/DenseMapInfo.h"
+#include <utility>
+#include <variant>
+
+namespace llvm {
+
+// Provide DenseMapInfo for variants whose all alternatives have DenseMapInfo.
+template <typename... Ts> struct DenseMapInfo<std::variant<Ts...>> {
+  using Variant = std::variant<Ts...>;
+  using FirstT = std::variant_alternative_t<0, Variant>;
+
+  static inline Variant getEmptyKey() {
+    return Variant(std::in_place_index<0>, DenseMapInfo<FirstT>::getEmptyKey());
+  }
+
+  static inline Variant getTombstoneKey() {
+    return Variant(std::in_place_index<0>,
+                   DenseMapInfo<FirstT>::getTombstoneKey());
+  }
+
+  static unsigned getHashValue(const Variant &Val) {
+    return std::visit(
+        [&Val](auto &&Alternative) {
+          using T = std::decay_t<decltype(Alternative)>;
+          // Include index in hash to make sure same value as 
diff erent
+          // alternatives don't collide.
+          return DenseMapInfo<std::pair<size_t, T>>::getHashValuePiecewise(
+              Val.index(), Alternative);
+        },
+        Val);
+  }
+
+  static bool isEqual(const Variant &LHS, const Variant &RHS) {
+    if (LHS.index() != RHS.index())
+      return false;
+    if (LHS.valueless_by_exception())
+      return true;
+    // We want to dispatch to DenseMapInfo<T>::isEqual(LHS.get(I), RHS.get(I))
+    // We know the types are the same, but std::visit(V, LHS, RHS) doesn't.
+    // We erase the type held in LHS to void*, and dispatch over RHS.
+    const void *ErasedLHS =
+        std::visit([](const auto &LHS) -> const void * { return &LHS; }, LHS);
+    return std::visit(
+        [&](const auto &RHS) -> bool {
+          using T = std::remove_cv_t<std::remove_reference_t<decltype(RHS)>>;
+          return DenseMapInfo<T>::isEqual(*static_cast<const T *>(ErasedLHS),
+                                          RHS);
+        },
+        RHS);
+  }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ADT_DENSEMAPINFOVARIANT_H

diff  --git a/llvm/include/llvm/CodeGen/CallingConvLower.h b/llvm/include/llvm/CodeGen/CallingConvLower.h
index a99519252cf92..cb88482b94152 100644
--- a/llvm/include/llvm/CodeGen/CallingConvLower.h
+++ b/llvm/include/llvm/CodeGen/CallingConvLower.h
@@ -19,6 +19,8 @@
 #include "llvm/CodeGen/TargetCallingConv.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/Support/Alignment.h"
+#include <variant>
+#include <vector>
 
 namespace llvm {
 

diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
index 76600e22c3164..d1affd9d2eb3c 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
@@ -22,6 +22,7 @@
 #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ThreadPool.h"
+#include <variant>
 
 namespace llvm {
 namespace orc {

diff  --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index 9a496f68333d3..55371d14a3689 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -21,6 +21,7 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MemoryBufferRef.h"
 #include "llvm/TargetParser/Triple.h"
+#include <variant>
 
 namespace llvm {
 namespace object {

diff  --git a/llvm/include/llvm/Transforms/Scalar/SROA.h b/llvm/include/llvm/Transforms/Scalar/SROA.h
index 46489df4ec6e3..dcee490d46a27 100644
--- a/llvm/include/llvm/Transforms/Scalar/SROA.h
+++ b/llvm/include/llvm/Transforms/Scalar/SROA.h
@@ -21,6 +21,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/ValueHandle.h"
+#include <variant>
 #include <vector>
 
 namespace llvm {

diff  --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp
index ba5cd4c4fca4d..94764a83024c6 100644
--- a/llvm/unittests/ADT/DenseMapTest.cpp
+++ b/llvm/unittests/ADT/DenseMapTest.cpp
@@ -8,6 +8,7 @@
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/DenseMapInfoVariant.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include <map>

diff  --git a/mlir/include/mlir/IR/AsmState.h b/mlir/include/mlir/IR/AsmState.h
index 761c817f1e82b..2abeacb844328 100644
--- a/mlir/include/mlir/IR/AsmState.h
+++ b/mlir/include/mlir/IR/AsmState.h
@@ -20,6 +20,7 @@
 #include "llvm/ADT/StringMap.h"
 
 #include <memory>
+#include <variant>
 
 namespace mlir {
 class AsmResourcePrinter;

diff  --git a/mlir/include/mlir/Transforms/SROA.h b/mlir/include/mlir/Transforms/SROA.h
index 3a44dc032966b..0b3e72400c287 100644
--- a/mlir/include/mlir/Transforms/SROA.h
+++ b/mlir/include/mlir/Transforms/SROA.h
@@ -13,6 +13,7 @@
 #include "mlir/Interfaces/MemorySlotInterfaces.h"
 #include "mlir/Support/LogicalResult.h"
 #include "llvm/ADT/Statistic.h"
+#include <variant>
 
 namespace mlir {
 


        


More information about the cfe-commits mailing list