aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Collison <collison@rivosinc.com>2023-05-06 11:31:30 -0600
committerJeff Law <jlaw@ventanamicro>2023-05-06 11:31:30 -0600
commitbc73bf831ef512b6a1c07ae150a7cbf2daed9fd6 (patch)
tree9843d01825fe97449f080db1e8c0622156c2a1b8
parent6ad9e5e0c7b77938348eee0ede77cb5522a914ac (diff)
downloadgcc-bc73bf831ef512b6a1c07ae150a7cbf2daed9fd6.zip
gcc-bc73bf831ef512b6a1c07ae150a7cbf2daed9fd6.tar.gz
gcc-bc73bf831ef512b6a1c07ae150a7cbf2daed9fd6.tar.bz2
RISC-V:autovec: Add auto-vectorization support functions
* config/riscv/riscv-v.cc (autovec_use_vlmax_p): New function. (riscv_vector_preferred_simd_mode): Ditto. (get_mask_policy_no_pred): Ditto. (get_tail_policy_no_pred): Ditto. (riscv_vector_mask_mode_p): Ditto. (riscv_vector_get_mask_mode): Ditto.
-rw-r--r--gcc/config/riscv/riscv-v.cc101
1 files changed, 93 insertions, 8 deletions
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 1f887f7..6f8b4ab 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -39,9 +39,11 @@
#include "emit-rtl.h"
#include "tm_p.h"
#include "target.h"
+#include "targhooks.h"
#include "expr.h"
#include "optabs.h"
#include "tm-constrs.h"
+#include "riscv-vector-builtins.h"
#include "rtx-vector-builder.h"
#include "targhooks.h"
@@ -177,6 +179,55 @@ calculate_ratio (unsigned int sew, enum vlmul_type vlmul)
return ratio;
}
+/* SCALABLE means that the vector-length is agnostic (run-time invariant and
+ compile-time unknown). FIXED meands that the vector-length is specific
+ (compile-time known). Both RVV_SCALABLE and RVV_FIXED_VLMAX are doing
+ auto-vectorization using VLMAX vsetvl configuration. */
+static bool
+autovec_use_vlmax_p (void)
+{
+ return (riscv_autovec_preference == RVV_SCALABLE
+ || riscv_autovec_preference == RVV_FIXED_VLMAX);
+}
+
+/* Return the vectorization machine mode for RVV according to LMUL. */
+machine_mode
+riscv_vector_preferred_simd_mode (scalar_mode mode)
+{
+ /* We only enable auto-vectorization when TARGET_MIN_VLEN >= 128 &&
+ riscv_autovec_lmul < RVV_M2. Since GCC loop vectorizer report ICE
+ when we enable -march=rv64gc_zve32* and -march=rv32gc_zve64*.
+ in the 'can_duplicate_and_interleave_p' of tree-vect-slp.cc. Since we have
+ VNx1SImode in -march=*zve32* and VNx1DImode in -march=*zve64*, they are
+ enabled in targetm. vector_mode_supported_p and SLP vectorizer will try to
+ use them. Currently, we can support auto-vectorization in
+ -march=rv32_zve32x_zvl128b. Wheras, -march=rv32_zve32x_zvl32b or
+ -march=rv32_zve32x_zvl64b are disabled. */
+ if (autovec_use_vlmax_p ())
+ {
+ /* If TARGET_MIN_VLEN < 128, we don't allow LMUL < 2
+ auto-vectorization since Loop Vectorizer may use VNx1SImode or
+ VNx1DImode to vectorize which will create ICE in the
+ 'can_duplicate_and_interleave_p' of tree-vect-slp.cc. */
+ if (TARGET_MIN_VLEN < 128 && riscv_autovec_lmul < RVV_M2)
+ return word_mode;
+ /* We use LMUL = 1 as base bytesize which is BYTES_PER_RISCV_VECTOR and
+ riscv_autovec_lmul as multiply factor to calculate the the NUNITS to
+ get the auto-vectorization mode. */
+ poly_uint64 nunits;
+ poly_uint64 vector_size
+ = BYTES_PER_RISCV_VECTOR * ((int) riscv_autovec_lmul);
+ poly_uint64 scalar_size = GET_MODE_SIZE (mode);
+ gcc_assert (multiple_p (vector_size, scalar_size, &nunits));
+ machine_mode rvv_mode;
+ if (get_vector_mode (mode, nunits).exists (&rvv_mode))
+ return rvv_mode;
+ }
+ /* TODO: We will support minimum length VLS auto-vectorization in the future.
+ */
+ return word_mode;
+}
+
/* Emit an RVV unmask && vl mov from SRC to DEST. */
static void
emit_pred_op (unsigned icode, rtx mask, rtx dest, rtx src, rtx len,
@@ -466,6 +517,45 @@ get_avl_type_rtx (enum avl_type type)
return gen_int_mode (type, Pmode);
}
+/* Return the mask policy for no predication. */
+rtx
+get_mask_policy_no_pred (void)
+{
+ return get_mask_policy_for_pred (PRED_TYPE_none);
+}
+
+/* Return the tail policy for no predication. */
+rtx
+get_tail_policy_no_pred (void)
+{
+ return get_tail_policy_for_pred (PRED_TYPE_none);
+}
+
+/* Return true if it is a RVV mask mode. */
+bool
+riscv_vector_mask_mode_p (machine_mode mode)
+{
+ return (mode == VNx1BImode || mode == VNx2BImode || mode == VNx4BImode
+ || mode == VNx8BImode || mode == VNx16BImode || mode == VNx32BImode
+ || mode == VNx64BImode);
+}
+
+/* Return the appropriate mask mode for MODE. */
+
+opt_machine_mode
+riscv_vector_get_mask_mode (machine_mode mode)
+{
+ machine_mode mask_mode;
+ int nf = 1;
+
+ FOR_EACH_MODE_IN_CLASS (mask_mode, MODE_VECTOR_BOOL)
+ if (GET_MODE_INNER (mask_mode) == BImode
+ && known_eq (GET_MODE_NUNITS (mask_mode) * nf, GET_MODE_NUNITS (mode))
+ && riscv_vector_mask_mode_p (mask_mode))
+ return mask_mode;
+ return default_get_mask_mode (mode);
+}
+
/* Return the RVV vector mode that has NUNITS elements of mode INNER_MODE.
This function is not only used by builtins, but also will be used by
auto-vectorization in the future. */
@@ -948,14 +1038,9 @@ preferred_simd_mode (scalar_mode mode)
enabled in targetm. vector_mode_supported_p and SLP vectorizer will try to
use them. Currently, we can support auto-vectorization in
-march=rv32_zve32x_zvl128b. Wheras, -march=rv32_zve32x_zvl32b or
- -march=rv32_zve32x_zvl64b are disabled.
- */
+ -march=rv32_zve32x_zvl64b are disabled. */
if (autovec_use_vlmax_p ())
{
- /* If TARGET_MIN_VLEN < 128, we don't allow LMUL < 2
- auto-vectorization since Loop Vectorizer may use VNx1SImode or
- VNx1DImode to vectorize which will create ICE in the
- 'can_duplicate_and_interleave_p' of tree-vect-slp.cc. */
if (TARGET_MIN_VLEN < 128 && riscv_autovec_lmul < RVV_M2)
return word_mode;
/* We use LMUL = 1 as base bytesize which is BYTES_PER_RISCV_VECTOR and
@@ -970,8 +1055,8 @@ preferred_simd_mode (scalar_mode mode)
if (get_vector_mode (mode, nunits).exists (&rvv_mode))
return rvv_mode;
}
- /* TODO: We will support minimum length VLS auto-vectorization in the future.
- */
+ /* TODO: We will support minimum length VLS auto-vectorization in
+ the future. */
return word_mode;
}