diff options
author | Michael Collison <collison@rivosinc.com> | 2023-05-06 11:31:30 -0600 |
---|---|---|
committer | Jeff Law <jlaw@ventanamicro> | 2023-05-06 11:31:30 -0600 |
commit | bc73bf831ef512b6a1c07ae150a7cbf2daed9fd6 (patch) | |
tree | 9843d01825fe97449f080db1e8c0622156c2a1b8 | |
parent | 6ad9e5e0c7b77938348eee0ede77cb5522a914ac (diff) | |
download | gcc-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.cc | 101 |
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; } |