[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