From: Richard Sandiford Date: Thu, 14 Nov 2019 14:55:12 +0000 (+0000) Subject: Pass the data vector mode to get_mask_mode X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=10116ec1c147a76522cafba6b6a5b4ed1cb37b77;p=gcc.git Pass the data vector mode to get_mask_mode This patch passes the data vector mode to get_mask_mode, rather than its size and nunits. This is a bit simpler and allows targets to distinguish between modes that happen to have the same size and number of elements. 2019-11-14 Richard Sandiford gcc/ * target.def (get_mask_mode): Take a vector mode itself as argument, instead of properties about the vector mode. * doc/tm.texi: Regenerate. * targhooks.h (default_get_mask_mode): Update to reflect new get_mode_mask interface. * targhooks.c (default_get_mask_mode): Likewise. Use related_int_vector_mode. * optabs-query.c (can_vec_mask_load_store_p): Update call to get_mask_mode. * tree-vect-stmts.c (check_load_store_masking): Likewise, checking first that the original mode really is a vector. * tree.c (build_truth_vector_type_for): Likewise. * config/aarch64/aarch64.c (aarch64_get_mask_mode): Update for new get_mode_mask interface. (aarch64_expand_sve_vcond): Update call accordingly. * config/gcn/gcn.c (gcn_vectorize_get_mask_mode): Update for new get_mode_mask interface. * config/i386/i386.c (ix86_get_mask_mode): Likewise. From-SVN: r278233 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2b307b70e63..48f5f37ee0d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2019-11-14 Richard Sandiford + + * target.def (get_mask_mode): Take a vector mode itself as argument, + instead of properties about the vector mode. + * doc/tm.texi: Regenerate. + * targhooks.h (default_get_mask_mode): Update to reflect new + get_mode_mask interface. + * targhooks.c (default_get_mask_mode): Likewise. Use + related_int_vector_mode. + * optabs-query.c (can_vec_mask_load_store_p): Update call + to get_mask_mode. + * tree-vect-stmts.c (check_load_store_masking): Likewise, checking + first that the original mode really is a vector. + * tree.c (build_truth_vector_type_for): Likewise. + * config/aarch64/aarch64.c (aarch64_get_mask_mode): Update for new + get_mode_mask interface. + (aarch64_expand_sve_vcond): Update call accordingly. + * config/gcn/gcn.c (gcn_vectorize_get_mask_mode): Update for new + get_mode_mask interface. + * config/i386/i386.c (ix86_get_mask_mode): Likewise. + 2019-11-14 Richard Sandiford * tree.h (build_truth_vector_type): Delete. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index b6c8d7701b2..0870d2c069f 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -1776,17 +1776,13 @@ aarch64_sve_pred_mode (unsigned int elem_nbytes) /* Implement TARGET_VECTORIZE_GET_MASK_MODE. */ static opt_machine_mode -aarch64_get_mask_mode (poly_uint64 nunits, poly_uint64 nbytes) +aarch64_get_mask_mode (machine_mode mode) { - if (TARGET_SVE && known_eq (nbytes, BYTES_PER_SVE_VECTOR)) - { - unsigned int elem_nbytes = vector_element_size (nbytes, nunits); - machine_mode pred_mode; - if (aarch64_sve_pred_mode (elem_nbytes).exists (&pred_mode)) - return pred_mode; - } + unsigned int vec_flags = aarch64_classify_vector_mode (mode); + if (vec_flags & VEC_SVE_DATA) + return aarch64_sve_pred_mode (GET_MODE_UNIT_SIZE (mode)); - return default_get_mask_mode (nunits, nbytes); + return default_get_mask_mode (mode); } /* Return the SVE vector mode that has NUNITS elements of mode INNER_MODE. */ @@ -19434,9 +19430,7 @@ void aarch64_expand_sve_vcond (machine_mode data_mode, machine_mode cmp_mode, rtx *ops) { - machine_mode pred_mode - = aarch64_get_mask_mode (GET_MODE_NUNITS (cmp_mode), - GET_MODE_SIZE (cmp_mode)).require (); + machine_mode pred_mode = aarch64_get_mask_mode (cmp_mode).require (); rtx pred = gen_reg_rtx (pred_mode); if (FLOAT_MODE_P (cmp_mode)) { diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c index 1a69737f693..20534a2fbe6 100644 --- a/gcc/config/gcn/gcn.c +++ b/gcc/config/gcn/gcn.c @@ -3816,8 +3816,7 @@ gcn_expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, a vector. */ opt_machine_mode -gcn_vectorize_get_mask_mode (poly_uint64 ARG_UNUSED (nunits), - poly_uint64 ARG_UNUSED (length)) +gcn_vectorize_get_mask_mode (machine_mode) { /* GCN uses a DImode bit-mask. */ return DImode; diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index ce446b248a8..69c827882c3 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -21419,8 +21419,10 @@ ix86_autovectorize_vector_sizes (vector_sizes *sizes, bool all) /* Implemenation of targetm.vectorize.get_mask_mode. */ static opt_machine_mode -ix86_get_mask_mode (poly_uint64 nunits, poly_uint64 vector_size) +ix86_get_mask_mode (machine_mode data_mode) { + unsigned vector_size = GET_MODE_SIZE (data_mode); + unsigned nunits = GET_MODE_NUNITS (data_mode); unsigned elem_size = vector_size / nunits; /* Scalar mask case. */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 5586e2edae2..3da1d65607a 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -6045,16 +6045,16 @@ requested mode, returning a mode with the same size as @var{vector_mode} when @var{nunits} is zero. This is the correct behavior for most targets. @end deftypefn -@deftypefn {Target Hook} opt_machine_mode TARGET_VECTORIZE_GET_MASK_MODE (poly_uint64 @var{nunits}, poly_uint64 @var{length}) -A vector mask is a value that holds one boolean result for every element -in a vector. This hook returns the machine mode that should be used to -represent such a mask when the vector in question is @var{length} bytes -long and contains @var{nunits} elements. The hook returns an empty -@code{opt_machine_mode} if no such mode exists. - -The default implementation returns the mode of an integer vector that -is @var{length} bytes long and that contains @var{nunits} elements, -if such a mode exists. +@deftypefn {Target Hook} opt_machine_mode TARGET_VECTORIZE_GET_MASK_MODE (machine_mode @var{mode}) +Return the mode to use for a vector mask that holds one boolean +result for each element of vector mode @var{mode}. The returned mask mode +can be a vector of integers (class @code{MODE_VECTOR_INT}), a vector of +booleans (class @code{MODE_VECTOR_BOOL}) or a scalar integer (class +@code{MODE_INT}). Return an empty @code{opt_machine_mode} if no such +mask mode exists. + +The default implementation returns a @code{MODE_VECTOR_INT} with the +same size and number of elements as @var{mode}, if such a mode exists. @end deftypefn @deftypefn {Target Hook} bool TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE (unsigned @var{ifn}) diff --git a/gcc/optabs-query.c b/gcc/optabs-query.c index e610e969b78..d59e116118d 100644 --- a/gcc/optabs-query.c +++ b/gcc/optabs-query.c @@ -585,8 +585,7 @@ can_vec_mask_load_store_p (machine_mode mode, if (!VECTOR_MODE_P (vmode)) return false; - if ((targetm.vectorize.get_mask_mode - (GET_MODE_NUNITS (vmode), GET_MODE_SIZE (vmode)).exists (&mask_mode)) + if (targetm.vectorize.get_mask_mode (vmode).exists (&mask_mode) && convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing) return true; @@ -600,7 +599,7 @@ can_vec_mask_load_store_p (machine_mode mode, continue; if (mode_for_vector (smode, nunits).exists (&vmode) && VECTOR_MODE_P (vmode) - && targetm.vectorize.get_mask_mode (nunits, cur).exists (&mask_mode) + && targetm.vectorize.get_mask_mode (vmode).exists (&mask_mode) && convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing) return true; } diff --git a/gcc/target.def b/gcc/target.def index 569aaa5da8e..51bc9a7d95b 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -1954,17 +1954,17 @@ when @var{nunits} is zero. This is the correct behavior for most targets.", /* Function to get a target mode for a vector mask. */ DEFHOOK (get_mask_mode, - "A vector mask is a value that holds one boolean result for every element\n\ -in a vector. This hook returns the machine mode that should be used to\n\ -represent such a mask when the vector in question is @var{length} bytes\n\ -long and contains @var{nunits} elements. The hook returns an empty\n\ -@code{opt_machine_mode} if no such mode exists.\n\ -\n\ -The default implementation returns the mode of an integer vector that\n\ -is @var{length} bytes long and that contains @var{nunits} elements,\n\ -if such a mode exists.", + "Return the mode to use for a vector mask that holds one boolean\n\ +result for each element of vector mode @var{mode}. The returned mask mode\n\ +can be a vector of integers (class @code{MODE_VECTOR_INT}), a vector of\n\ +booleans (class @code{MODE_VECTOR_BOOL}) or a scalar integer (class\n\ +@code{MODE_INT}). Return an empty @code{opt_machine_mode} if no such\n\ +mask mode exists.\n\ +\n\ +The default implementation returns a @code{MODE_VECTOR_INT} with the\n\ +same size and number of elements as @var{mode}, if such a mode exists.", opt_machine_mode, - (poly_uint64 nunits, poly_uint64 length), + (machine_mode mode), default_get_mask_mode) /* Function to say whether a masked operation is expensive when the diff --git a/gcc/targhooks.c b/gcc/targhooks.c index dcecd81e54d..f6c7a0c8676 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1328,21 +1328,9 @@ default_vectorize_related_mode (machine_mode vector_mode, /* By default a vector of integers is used as a mask. */ opt_machine_mode -default_get_mask_mode (poly_uint64 nunits, poly_uint64 vector_size) +default_get_mask_mode (machine_mode mode) { - unsigned int elem_size = vector_element_size (vector_size, nunits); - scalar_int_mode elem_mode - = smallest_int_mode_for_size (elem_size * BITS_PER_UNIT); - machine_mode vector_mode; - - gcc_assert (known_eq (elem_size * nunits, vector_size)); - - if (mode_for_vector (elem_mode, nunits).exists (&vector_mode) - && VECTOR_MODE_P (vector_mode) - && targetm.vector_mode_supported_p (vector_mode)) - return vector_mode; - - return opt_machine_mode (); + return related_int_vector_mode (mode); } /* By default consider masked stores to be expensive. */ diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 12e6ad49cf0..57b83a3e8a8 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -117,7 +117,7 @@ extern void default_autovectorize_vector_sizes (vector_sizes *, bool); extern opt_machine_mode default_vectorize_related_mode (machine_mode, scalar_mode, poly_uint64); -extern opt_machine_mode default_get_mask_mode (poly_uint64, poly_uint64); +extern opt_machine_mode default_get_mask_mode (machine_mode); extern bool default_empty_mask_is_expensive (unsigned); extern void *default_init_cost (class loop *); extern unsigned default_add_stmt_cost (void *, int, enum vect_cost_for_stmt, diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 19984b5ad22..71c635c57b9 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -1943,9 +1943,8 @@ check_load_store_masking (loop_vec_info loop_vinfo, tree vectype, } machine_mode mask_mode; - if (!(targetm.vectorize.get_mask_mode - (GET_MODE_NUNITS (vecmode), - GET_MODE_SIZE (vecmode)).exists (&mask_mode)) + if (!VECTOR_MODE_P (vecmode) + || !targetm.vectorize.get_mask_mode (vecmode).exists (&mask_mode) || !can_vec_mask_load_store_p (vecmode, mask_mode, is_load)) { if (dump_enabled_p ()) diff --git a/gcc/tree.c b/gcc/tree.c index 61b95c993c9..4db3fa8ee6c 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -10894,15 +10894,15 @@ build_truth_vector_type_for_mode (poly_uint64 nunits, machine_mode mask_mode) static tree build_truth_vector_type_for (tree vectype) { + machine_mode vector_mode = TYPE_MODE (vectype); poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); - poly_uint64 vector_size = tree_to_poly_uint64 (TYPE_SIZE_UNIT (vectype)); machine_mode mask_mode; - if (targetm.vectorize.get_mask_mode (nunits, - vector_size).exists (&mask_mode)) + if (VECTOR_MODE_P (vector_mode) + && targetm.vectorize.get_mask_mode (vector_mode).exists (&mask_mode)) return build_truth_vector_type_for_mode (nunits, mask_mode); - poly_uint64 vsize = vector_size * BITS_PER_UNIT; + poly_uint64 vsize = tree_to_poly_uint64 (TYPE_SIZE (vectype)); unsigned HOST_WIDE_INT esize = vector_element_size (vsize, nunits); tree bool_type = build_nonstandard_boolean_type (esize);