+2019-11-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * 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 <richard.sandiford@arm.com>
* tree.h (build_truth_vector_type): Delete.
/* 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. */
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))
{
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;
/* 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. */
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})
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;
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;
}
/* 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
/* 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. */
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,
}
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 ())
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);