aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPan Li <pan2.li@intel.com>2025-04-16 11:16:21 +0800
committerPan Li <pan2.li@intel.com>2025-04-27 10:08:56 +0800
commite6e42a709f3cd87e7a5efca72267cab57e0385cb (patch)
tree0d6a5a4d3386ec56737de7ca90ae4636c0033a4c /gcc
parentd85444a3b00c9a6fce56459af5ec081439a9aaa0 (diff)
downloadgcc-e6e42a709f3cd87e7a5efca72267cab57e0385cb.zip
gcc-e6e42a709f3cd87e7a5efca72267cab57e0385cb.tar.gz
gcc-e6e42a709f3cd87e7a5efca72267cab57e0385cb.tar.bz2
RISC-V: Extract vec_duplicate for expand_const_vector [NFC]
Consider the expand_const_vector is quit long (about 500 lines) and complicated, we would like to extract the different case into different functions. For example, the const vec_duplicate will be extracted into expand_const_vec_duplicate. The below test suites are passed for this patch. * The rv64gcv fully regression test. gcc/ChangeLog: * config/riscv/riscv-v.cc (expand_const_vector): Extract const vec_duplicate into separated function. (expand_const_vec_duplicate): Add new func to take care of the const vec_duplicate. Signed-off-by: Pan Li <pan2.li@intel.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/riscv/riscv-v.cc92
1 files changed, 50 insertions, 42 deletions
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index aae2d27..1eb14a24 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -1171,61 +1171,69 @@ expand_vector_init_trailing_same_elem (rtx target,
}
static void
-expand_const_vector (rtx target, rtx src)
+expand_const_vec_duplicate (rtx target, rtx src, rtx elt)
{
machine_mode mode = GET_MODE (target);
rtx result = register_operand (target, mode) ? target : gen_reg_rtx (mode);
- rtx elt;
- if (const_vec_duplicate_p (src, &elt))
+
+ if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
+ {
+ gcc_assert (rtx_equal_p (elt, const0_rtx)
+ || rtx_equal_p (elt, const1_rtx));
+
+ rtx ops[] = {result, src};
+ emit_vlmax_insn (code_for_pred_mov (mode), UNARY_MASK_OP, ops);
+ }
+ else if (valid_vec_immediate_p (src))
{
- if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
- {
- gcc_assert (rtx_equal_p (elt, const0_rtx)
- || rtx_equal_p (elt, const1_rtx));
- rtx ops[] = {result, src};
- emit_vlmax_insn (code_for_pred_mov (mode), UNARY_MASK_OP, ops);
- }
/* Element in range -16 ~ 15 integer or 0.0 floating-point,
we use vmv.v.i instruction. */
- else if (valid_vec_immediate_p (src))
+ rtx ops[] = {result, src};
+ emit_vlmax_insn (code_for_pred_mov (mode), UNARY_OP, ops);
+ }
+ else
+ {
+ /* Emit vec_duplicate<mode> split pattern before RA so that
+ we could have a better optimization opportunity in LICM
+ which will hoist vmv.v.x outside the loop and in fwprop && combine
+ which will transform 'vv' into 'vx' instruction.
+
+ The reason we don't emit vec_duplicate<mode> split pattern during
+ RA since the split stage after RA is a too late stage to generate
+ RVV instruction which need an additional register (We can't
+ allocate a new register after RA) for VL operand of vsetvl
+ instruction (vsetvl a5, zero). */
+ if (lra_in_progress)
{
- rtx ops[] = {result, src};
- emit_vlmax_insn (code_for_pred_mov (mode), UNARY_OP, ops);
+ rtx ops[] = {result, elt};
+ emit_vlmax_insn (code_for_pred_broadcast (mode), UNARY_OP, ops);
}
else
{
- /* Emit vec_duplicate<mode> split pattern before RA so that
- we could have a better optimization opportunity in LICM
- which will hoist vmv.v.x outside the loop and in fwprop && combine
- which will transform 'vv' into 'vx' instruction.
-
- The reason we don't emit vec_duplicate<mode> split pattern during
- RA since the split stage after RA is a too late stage to generate
- RVV instruction which need an additional register (We can't
- allocate a new register after RA) for VL operand of vsetvl
- instruction (vsetvl a5, zero). */
- if (lra_in_progress)
- {
- rtx ops[] = {result, elt};
- emit_vlmax_insn (code_for_pred_broadcast (mode), UNARY_OP, ops);
- }
- else
- {
- struct expand_operand ops[2];
- enum insn_code icode = optab_handler (vec_duplicate_optab, mode);
- gcc_assert (icode != CODE_FOR_nothing);
- create_output_operand (&ops[0], result, mode);
- create_input_operand (&ops[1], elt, GET_MODE_INNER (mode));
- expand_insn (icode, 2, ops);
- result = ops[0].value;
- }
+ struct expand_operand ops[2];
+ enum insn_code icode = optab_handler (vec_duplicate_optab, mode);
+ gcc_assert (icode != CODE_FOR_nothing);
+ create_output_operand (&ops[0], result, mode);
+ create_input_operand (&ops[1], elt, GET_MODE_INNER (mode));
+ expand_insn (icode, 2, ops);
+ result = ops[0].value;
}
-
- if (result != target)
- emit_move_insn (target, result);
- return;
}
+ if (result != target)
+ emit_move_insn (target, result);
+}
+
+static void
+expand_const_vector (rtx target, rtx src)
+{
+ machine_mode mode = GET_MODE (target);
+ rtx result = register_operand (target, mode) ? target : gen_reg_rtx (mode);
+ rtx elt;
+
+ if (const_vec_duplicate_p (src, &elt))
+ return expand_const_vec_duplicate (target, src, elt);
+
/* Support scalable const series vector. */
rtx base, step;
if (const_vec_series_p (src, &base, &step))