[llvm] [PatternMatchHelpers] Avoid std::apply for compile time (PR #191413)

via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 10 06:09:11 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-support

Author: Ramkumar Ramachandra (artagnon)

<details>
<summary>Changes</summary>

Squelch the stage-2 compile time regression introduced by the variadic m_Combine(And|Or) matchers, by replacing the std::apply on a std::tuple with a more lightweight solution.

-- 8< --
Compile time improvement: https://llvm-compile-time-tracker.com/compare_clang.php?from=6e0a76b1966bf54d873cebed5c6e241faf461171&to=865fe215938e31448ce114fa7b44c1b56f7fac1c&stat=instructions%3Au&sortBy=relative-difference

We recover about half the regression: 0.07% out of 0.14% -- if a higher compile-time improvement is desired, I'm open to ideas.

---
Full diff: https://github.com/llvm/llvm-project/pull/191413.diff


1 Files Affected:

- (modified) llvm/include/llvm/Support/PatternMatchHelpers.h (+30-6) 


``````````diff
diff --git a/llvm/include/llvm/Support/PatternMatchHelpers.h b/llvm/include/llvm/Support/PatternMatchHelpers.h
index e351f96b10545..16f44fa0c9b8e 100644
--- a/llvm/include/llvm/Support/PatternMatchHelpers.h
+++ b/llvm/include/llvm/Support/PatternMatchHelpers.h
@@ -16,23 +16,47 @@
 
 #include "llvm/Support/Casting.h"
 #include <tuple>
+#include <type_traits>
+#include <utility>
 
 namespace llvm::PatternMatchHelpers {
+// A naive std::apply would cost more in compile-time.
+template <typename TupleT, typename IndicesT> class PatternStorage;
+
+template <typename TupleT, size_t... Indices>
+class PatternStorage<TupleT, std::index_sequence<Indices...>> {
+  TupleT Patterns;
+
+public:
+  template <typename... Ty>
+  constexpr PatternStorage(Ty &&...Ps) : Patterns(std::forward<Ty>(Ps)...) {}
+  template <typename ITy> bool combineAnd(ITy *V) const {
+    return (std::get<Indices>(Patterns).match(V) && ...);
+  }
+  template <typename ITy> bool combineOr(ITy *V) const {
+    return (std::get<Indices>(Patterns).match(V) || ...);
+  }
+};
+
 /// Matching or combinator.
 template <typename... Ty> struct match_combine_or { // NOLINT
-  std::tuple<Ty...> Ps;
-  match_combine_or(const Ty &...Ps) : Ps(Ps...) {}
+  PatternStorage<std::tuple<std::decay_t<Ty>...>,
+                 std::index_sequence_for<Ty...>>
+      Storage;
+  match_combine_or(const Ty &...Ps) : Storage(Ps...) {}
   template <typename ITy> bool match(ITy *V) const {
-    return std::apply([V](auto &&...Ps) { return (Ps.match(V) || ...); }, Ps);
+    return Storage.combineOr(V);
   }
 };
 
 /// Matching and combinator.
 template <typename... Ty> struct match_combine_and { // NOLINT
-  std::tuple<Ty...> Ps;
-  match_combine_and(const Ty &...Ps) : Ps(Ps...) {}
+  PatternStorage<std::tuple<std::decay_t<Ty>...>,
+                 std::index_sequence_for<Ty...>>
+      Storage;
+  match_combine_and(const Ty &...Ps) : Storage(Ps...) {}
   template <typename ITy> bool match(ITy *V) const {
-    return std::apply([V](auto &&...Ps) { return (Ps.match(V) && ...); }, Ps);
+    return Storage.combineAnd(V);
   }
 };
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/191413


More information about the llvm-commits mailing list