[llvm] [DAG] SDPatternMatch - add matchers for reassociatable binops (PR #119985)

Min-Yih Hsu via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 2 16:52:31 PST 2025


================
@@ -1072,6 +1072,97 @@ inline BinaryOpc_match<ValTy, AllOnes_match, true> m_Not(const ValTy &V) {
   return m_Xor(V, m_AllOnes());
 }
 
+template <typename... PatternTs> struct ReassociatableOpc_match {
+  unsigned Opcode;
+  std::tuple<PatternTs...> Patterns;
+
+  ReassociatableOpc_match(unsigned Opcode, const PatternTs &...Patterns)
+      : Opcode(Opcode), Patterns(Patterns...) {}
+
+  template <typename MatchContext>
+  bool match(const MatchContext &Ctx, SDValue N) {
+    SmallVector<SDValue> Leaves;
+    collectLeaves(N, Leaves);
+    if (Leaves.size() != std::tuple_size_v<std::tuple<PatternTs...>>) {
+      return false;
+    }
+
+    // J in Matches[I] iff sd_context_match(Leaves[I], Ctx,
+    // std::get<J>(Patterns)) == true
+    SmallVector<SmallVector<size_t>> Matches(Leaves.size());
+    for (size_t I = 0; I < Leaves.size(); I += 1) {
+      SmallVector<bool> MatchResults;
+      std::apply(
+          [&](auto &...P) {
+            (MatchResults.emplace_back(sd_context_match(Leaves[I], Ctx, P)),
+             ...);
+          },
+          Patterns);
+      for (size_t J = 0; J < MatchResults.size(); J += 1) {
+        if (MatchResults[J]) {
+          Matches[I].emplace_back(J);
+        }
+      }
+    }
+
+    SmallVector<bool> Used(std::tuple_size_v<std::tuple<PatternTs...>>, false);
+    return reassociatableMatchHelper(Matches, Used);
+  }
+
+  void collectLeaves(SDValue V, SmallVector<SDValue> &Leaves) {
+    if (V->getOpcode() == Opcode) {
+      for (size_t I = 0; I < V->getNumOperands(); I += 1) {
+        collectLeaves(V->getOperand(I), Leaves);
+      }
+    } else {
+      Leaves.emplace_back(V);
+    }
+  }
+
+  [[nodiscard]] inline bool
+  reassociatableMatchHelper(const SmallVector<SmallVector<size_t>> &Matches,
+                            SmallVector<bool> &Used, size_t Curr = 0) {
+    if (Curr == Matches.size()) {
+      return true;
+    }
+    for (auto Match : Matches[Curr]) {
+      if (Used[Match]) {
----------------
mshockwave wrote:

ditto: drop curly braces.

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


More information about the llvm-commits mailing list