From: Pan Li <[email protected]>
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 <[email protected]>
---
gcc/config/riscv/riscv-v.cc | 92 ++++++++++++++++++++-----------------
1 file changed, 50 insertions(+), 42 deletions(-)
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index aae2d274336..1eb14a24e3d 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))
--
2.43.0