public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: "juzhe.zhong@rivai.ai" <juzhe.zhong@rivai.ai>
To: "Robin Dapp" <rdapp.gcc@gmail.com>,
	 gcc-patches <gcc-patches@gcc.gnu.org>,
	 kito.cheng <kito.cheng@gmail.com>,
	 collison <collison@rivosinc.com>,  palmer <palmer@dabbelt.com>,
	 jeffreyalaw <jeffreyalaw@gmail.com>
Cc: "Robin Dapp" <rdapp.gcc@gmail.com>
Subject: Re: [PATCH v2] RISC-V: Add vectorized binops and insn_expander helpers.
Date: Thu, 11 May 2023 18:34:44 +0800	[thread overview]
Message-ID: <5A7C9C879E4A81C6+20230511183443765328217@rivai.ai> (raw)
In-Reply-To: <c510c333-a863-6aa0-5a40-5177d5b45094@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 10799 bytes --]

LGTM. You should commit it now. Then I can rebase vec_init patch.



juzhe.zhong@rivai.ai
 
From: Robin Dapp
Date: 2023-05-11 18:26
To: 钟居哲; gcc-patches; kito.cheng; Michael Collison; palmer; Jeff Law
CC: rdapp.gcc
Subject: [PATCH v2] RISC-V: Add vectorized binops and insn_expander helpers.
Changes from v1:
 
- Rebase against Juzhe's vec_series patch.
- Get rid of redundant scalar mode setting.
 
 
This patch adds basic binary integer operations support.  It is based
on Michael Collison's work and makes use of the existing helpers in
riscv-c.cc.  It introduces emit_nonvlmax_binop which, in turn, uses
emit_pred_binop.  Setting the destination as well as the mask and the
length are factored out into separate functions.
 
gcc/ChangeLog:
 
* config/riscv/autovec.md (<optab><mode>3): Add integer binops.
* config/riscv/riscv-protos.h (emit_nonvlmax_binop): Declare.
* config/riscv/riscv-v.cc (emit_pred_op): New function.
(set_expander_dest_and_mask): New function.
(emit_pred_binop): New function.
(emit_nonvlmax_binop): New function.
 
Co-authored-by: Michael Collison <collison@rivosinc.com>
---
gcc/config/riscv/autovec.md     |  37 ++++++++
gcc/config/riscv/riscv-protos.h |   2 +
gcc/config/riscv/riscv-v.cc     | 148 ++++++++++++++++++--------------
3 files changed, 123 insertions(+), 64 deletions(-)
 
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 99dc4f046b0..e249f4be704 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -82,3 +82,40 @@ (define_expand "@vec_series<mode>"
     DONE;
   }
)
+
+;; ========================================================================
+;; == Vector operations
+;; =========================================================================
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] Binary operations
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vadd.vv/vsub.vv/...
+;; - vadd.vi/vsub.vi/...
+;; -------------------------------------------------------------------------
+
+(define_expand "<optab><mode>3"
+  [(set (match_operand:VI 0 "register_operand")
+    (any_int_binop:VI
+     (match_operand:VI 1 "<binop_rhs1_predicate>")
+     (match_operand:VI 2 "<binop_rhs2_predicate>")))]
+  "TARGET_VECTOR"
+{
+  if (!register_operand (operands[2], <MODE>mode))
+    {
+      rtx cst;
+      gcc_assert (const_vec_duplicate_p(operands[2], &cst));
+      riscv_vector::emit_nonvlmax_binop (code_for_pred_scalar
+ (<CODE>, <MODE>mode),
+ operands[0], operands[1], cst,
+ NULL, <VM>mode,
+ <VEL>mode);
+    }
+  else
+    riscv_vector::emit_nonvlmax_binop (code_for_pred
+        (<CODE>, <MODE>mode),
+        operands[0], operands[1], operands[2],
+        NULL, <VM>mode);
+  DONE;
+})
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index e8a728ae226..4d0589e502c 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -169,6 +169,8 @@ void emit_hard_vlmax_vsetvl (machine_mode, rtx);
void emit_vlmax_op (unsigned, rtx, rtx, machine_mode);
void emit_vlmax_op (unsigned, rtx, rtx, rtx, machine_mode);
void emit_nonvlmax_op (unsigned, rtx, rtx, rtx, machine_mode);
+void emit_nonvlmax_binop (unsigned, rtx, rtx, rtx, rtx, machine_mode,
+   machine_mode = VOIDmode);
enum vlmul_type get_vlmul (machine_mode);
unsigned int get_ratio (machine_mode);
unsigned int get_nf (machine_mode);
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 381e6601a17..8f46226d571 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -53,7 +53,7 @@ namespace riscv_vector {
template <int MAX_OPERANDS> class insn_expander
{
public:
-  insn_expander () : m_opno (0) {}
+  insn_expander () : m_opno (0), has_dest(false) {}
   void add_output_operand (rtx x, machine_mode mode)
   {
     create_output_operand (&m_ops[m_opno++], x, mode);
@@ -84,6 +84,44 @@ public:
     add_input_operand (gen_int_mode (type, Pmode), Pmode);
   }
+  void set_dest_and_mask (rtx mask, rtx dest, machine_mode mask_mode)
+  {
+    dest_mode = GET_MODE (dest);
+    has_dest = true;
+
+    add_output_operand (dest, dest_mode);
+
+    if (mask)
+      add_input_operand (mask, GET_MODE (mask));
+    else
+      add_all_one_mask_operand (mask_mode);
+
+    add_vundef_operand (dest_mode);
+  }
+
+  void set_len_and_policy (rtx len, bool vlmax_p)
+    {
+      gcc_assert (has_dest);
+      gcc_assert (len || vlmax_p);
+
+      if (len)
+ add_input_operand (len, Pmode);
+      else
+ {
+   rtx vlmax = gen_reg_rtx (Pmode);
+   emit_vlmax_vsetvl (dest_mode, vlmax);
+   add_input_operand (vlmax, Pmode);
+ }
+
+      if (GET_MODE_CLASS (dest_mode) != MODE_VECTOR_BOOL)
+ add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
+
+      if (vlmax_p)
+ add_avl_type_operand (avl_type::VLMAX);
+      else
+ add_avl_type_operand (avl_type::NONVLMAX);
+    }
+
   void expand (enum insn_code icode, bool temporary_volatile_p = false)
   {
     if (temporary_volatile_p)
@@ -97,6 +135,8 @@ public:
private:
   int m_opno;
+  bool has_dest;
+  machine_mode dest_mode;
   expand_operand m_ops[MAX_OPERANDS];
};
@@ -195,37 +235,41 @@ emit_pred_op (unsigned icode, rtx mask, rtx dest, rtx src, rtx len,
      machine_mode mask_mode, bool vlmax_p)
{
   insn_expander<8> e;
-  machine_mode mode = GET_MODE (dest);
+  e.set_dest_and_mask (mask, dest, mask_mode);
-  e.add_output_operand (dest, mode);
+  e.add_input_operand (src, GET_MODE (src));
-  if (mask)
-    e.add_input_operand (mask, GET_MODE (mask));
-  else
-    e.add_all_one_mask_operand (mask_mode);
+  e.set_len_and_policy (len, vlmax_p);
-  e.add_vundef_operand (mode);
+  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src));
+}
-  e.add_input_operand (src, GET_MODE (src));
+/* Emit an RVV binop.  If one of SRC1 and SRC2 is a scalar operand, its mode is
+   specified using SCALAR_MODE.  */
+static void
+emit_pred_binop (unsigned icode, rtx mask, rtx dest, rtx src1, rtx src2,
+ rtx len, machine_mode mask_mode, machine_mode scalar_mode,
+ bool vlmax_p)
+{
+  insn_expander<9> e;
+  e.set_dest_and_mask (mask, dest, mask_mode);
-  if (len)
-    e.add_input_operand (len, Pmode);
-  else
-    {
-      rtx vlmax = gen_reg_rtx (Pmode);
-      emit_vlmax_vsetvl (mode, vlmax);
-      e.add_input_operand (vlmax, Pmode);
-    }
+  gcc_assert (VECTOR_MODE_P (GET_MODE (src1))
+       || VECTOR_MODE_P (GET_MODE (src2)));
-  if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
-    e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
+  if (VECTOR_MODE_P (GET_MODE (src1)))
+    e.add_input_operand (src1, GET_MODE (src1));
+  else
+    e.add_input_operand (src1, scalar_mode);
-  if (vlmax_p)
-    e.add_avl_type_operand (avl_type::VLMAX);
+  if (VECTOR_MODE_P (GET_MODE (src2)))
+    e.add_input_operand (src2, GET_MODE (src2));
   else
-    e.add_avl_type_operand (avl_type::NONVLMAX);
+    e.add_input_operand (src2, scalar_mode);
-  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src));
+  e.set_len_and_policy (len, vlmax_p);
+
+  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src1) || MEM_P (src2));
}
void
@@ -248,49 +292,25 @@ emit_nonvlmax_op (unsigned icode, rtx dest, rtx src, rtx len,
   emit_pred_op (icode, NULL_RTX, dest, src, len, mask_mode, false);
}
-/* Emit binary operations.  */
-
-static void
-emit_binop (unsigned icode, rtx *ops, machine_mode mask_mode,
-     machine_mode scalar_mode)
+void
+emit_nonvlmax_binop (unsigned icode, rtx dest, rtx src1, rtx src2, rtx len,
+      machine_mode mask_mode, machine_mode scalar_mode)
{
-  insn_expander<9> e;
-  machine_mode mode = GET_MODE (ops[0]);
-  e.add_output_operand (ops[0], mode);
-  e.add_all_one_mask_operand (mask_mode);
-  e.add_vundef_operand (mode);
-  if (VECTOR_MODE_P (GET_MODE (ops[1])))
-    e.add_input_operand (ops[1], GET_MODE (ops[1]));
-  else
-    e.add_input_operand (ops[1], scalar_mode);
-  if (VECTOR_MODE_P (GET_MODE (ops[2])))
-    e.add_input_operand (ops[2], GET_MODE (ops[2]));
-  else
-    e.add_input_operand (ops[2], scalar_mode);
-  rtx vlmax = gen_reg_rtx (Pmode);
-  emit_vlmax_vsetvl (mode, vlmax);
-  e.add_input_operand (vlmax, Pmode);
-  e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
-  e.add_avl_type_operand (avl_type::VLMAX);
-  e.expand ((enum insn_code) icode, false);
+  emit_pred_binop (icode, NULL_RTX, dest, src1, src2, len, mask_mode,
+    scalar_mode, len ? false : true);
}
/* Emit vid.v instruction.  */
static void
-emit_index_op (rtx target, machine_mode mask_mode)
+emit_index_op (rtx dest, machine_mode mask_mode)
{
   insn_expander<7> e;
-  machine_mode mode = GET_MODE (target);
-  e.add_output_operand (target, mode);
-  e.add_all_one_mask_operand (mask_mode);
-  e.add_vundef_operand (mode);
-  rtx vlmax = gen_reg_rtx (Pmode);
-  emit_vlmax_vsetvl (mode, vlmax);
-  e.add_input_operand (vlmax, Pmode);
-  e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
-  e.add_avl_type_operand (avl_type::VLMAX);
-  e.expand (code_for_pred_series (mode), false);
+  e.set_dest_and_mask (NULL, dest, mask_mode);
+
+  e.set_len_and_policy (NULL, true);
+
+  e.expand (code_for_pred_series (GET_MODE (dest)), false);
}
/* Expand series const vector.  */
@@ -324,15 +344,15 @@ expand_vec_series (rtx dest, rtx base, rtx step)
  /* Emit logical left shift operation.  */
  int shift = exact_log2 (INTVAL (step));
  rtx shift_amount = gen_int_mode (shift, Pmode);
-   rtx ops[3] = {step_adj, vid, shift_amount};
  insn_code icode = code_for_pred_scalar (ASHIFT, mode);
-   emit_binop (icode, ops, mask_mode, Pmode);
+   emit_nonvlmax_binop (icode, step_adj, vid, shift_amount,
+        NULL, mask_mode, Pmode);
}
       else
{
-   rtx ops[3] = {step_adj, vid, step};
  insn_code icode = code_for_pred_scalar (MULT, mode);
-   emit_binop (icode, ops, mask_mode, inner_mode);
+   emit_nonvlmax_binop (icode, step_adj, vid, step,
+        NULL, mask_mode, inner_mode);
}
     }
@@ -346,9 +366,9 @@ expand_vec_series (rtx dest, rtx base, rtx step)
   else
     {
       rtx result = gen_reg_rtx (mode);
-      rtx ops[3] = {result, step_adj, base};
       insn_code icode = code_for_pred_scalar (PLUS, mode);
-      emit_binop (icode, ops, mask_mode, inner_mode);
+      emit_nonvlmax_binop (icode, result, step_adj, base,
+    NULL, mask_mode, inner_mode);
       emit_move_insn (dest, result);
     }
}
-- 
2.40.0
 

  reply	other threads:[~2023-05-11 10:34 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-10 15:24 [PATCH] riscv: " Robin Dapp
2023-05-10 15:43 ` 钟居哲
2023-05-10 18:02   ` Robin Dapp
2023-05-10 22:55     ` 钟居哲
2023-05-11 10:26       ` [PATCH v2] RISC-V: " Robin Dapp
2023-05-11 10:34         ` juzhe.zhong [this message]
2023-05-11 10:36           ` Robin Dapp
2023-05-11 10:38             ` juzhe.zhong
2023-05-11 11:09               ` Kito Cheng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5A7C9C879E4A81C6+20230511183443765328217@rivai.ai \
    --to=juzhe.zhong@rivai.ai \
    --cc=collison@rivosinc.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jeffreyalaw@gmail.com \
    --cc=kito.cheng@gmail.com \
    --cc=palmer@dabbelt.com \
    --cc=rdapp.gcc@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).