This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[6/9] Make mode_for_vector return an opt_mode
- From: Richard Sandiford <richard dot sandiford at linaro dot org>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 04 Sep 2017 12:39:23 +0100
- Subject: [6/9] Make mode_for_vector return an opt_mode
- Authentication-results: sourceware.org; auth=none
- References: <87tw0iiu51.fsf@linaro.org>
...following on from the mode_for_size change. The patch also removes
machmode.h versions of the stor-layout.c comments, since the comments
in the .c file are more complete.
2017-09-04 Richard Sandiford <richard.sandiford@linaro.org>
gcc/
* machmode.h (mode_for_vector): Return an opt_mode.
* stor-layout.c (mode_for_vector): Likewise.
(mode_for_int_vector): Update accordingly.
(layout_type): Likewise.
* config/i386/i386.c (emit_memmov): Likewise.
(ix86_expand_set_or_movmem): Likewise.
(ix86_expand_vector_init): Likewise.
(ix86_get_mask_mode): Likewise.
* config/powerpcspe/powerpcspe.c (rs6000_expand_vec_perm_const_1):
Likewise.
* config/rs6000/rs6000.c (rs6000_expand_vec_perm_const_1): Likewise.
* expmed.c (extract_bit_field_1): Likewise.
* expr.c (expand_expr_real_2): Likewise.
* optabs-query.c (can_vec_perm_p): Likewise.
(can_vec_mask_load_store_p): Likewise.
* optabs.c (expand_vec_perm): Likewise.
* targhooks.c (default_get_mask_mode): Likewise.
* tree-vect-stmts.c (vectorizable_store): Likewise.
(vectorizable_load): Likewise.
(get_vectype_for_scalar_type_and_size): Likewise.
Index: gcc/machmode.h
===================================================================
--- gcc/machmode.h 2017-09-04 12:18:53.153306182 +0100
+++ gcc/machmode.h 2017-09-04 12:18:55.821333642 +0100
@@ -682,8 +682,6 @@ decimal_float_mode_for_size (unsigned in
(mode_for_size (size, MODE_DECIMAL_FLOAT, 0));
}
-/* Similar to mode_for_size, but find the smallest mode for a given width. */
-
extern machine_mode smallest_mode_for_size (unsigned int, enum mode_class);
/* Find the narrowest integer mode that contains at least SIZE bits.
@@ -695,17 +693,9 @@ smallest_int_mode_for_size (unsigned int
return as_a <scalar_int_mode> (smallest_mode_for_size (size, MODE_INT));
}
-/* Return an integer mode of exactly the same size as the input mode. */
-
extern opt_scalar_int_mode int_mode_for_mode (machine_mode);
-
extern machine_mode bitwise_mode_for_mode (machine_mode);
-
-/* Return a mode that is suitable for representing a vector,
- or BLKmode on failure. */
-
-extern machine_mode mode_for_vector (scalar_mode, unsigned);
-
+extern opt_machine_mode mode_for_vector (scalar_mode, unsigned);
extern opt_machine_mode mode_for_int_vector (unsigned int, unsigned int);
/* Return the integer vector equivalent of MODE, if one exists. In other
Index: gcc/stor-layout.c
===================================================================
--- gcc/stor-layout.c 2017-09-04 12:18:53.153306182 +0100
+++ gcc/stor-layout.c 2017-09-04 12:18:55.824344959 +0100
@@ -471,11 +471,11 @@ bitwise_type_for_mode (machine_mode mode
return inner_type;
}
-/* Find a mode that is suitable for representing a vector with
- NUNITS elements of mode INNERMODE. Returns BLKmode if there
- is no suitable mode. */
+/* Find a mode that is suitable for representing a vector with NUNITS
+ elements of mode INNERMODE, if one exists. The returned mode can be
+ either an integer mode or a vector mode. */
-machine_mode
+opt_machine_mode
mode_for_vector (scalar_mode innermode, unsigned nunits)
{
machine_mode mode;
@@ -499,22 +499,18 @@ mode_for_vector (scalar_mode innermode,
FOR_EACH_MODE_FROM (mode, mode)
if (GET_MODE_NUNITS (mode) == nunits
&& GET_MODE_INNER (mode) == innermode)
- break;
+ return mode;
/* For integers, try mapping it to a same-sized scalar mode. */
- if (mode == VOIDmode
- && GET_MODE_CLASS (innermode) == MODE_INT)
+ if (GET_MODE_CLASS (innermode) == MODE_INT)
{
unsigned int nbits = nunits * GET_MODE_BITSIZE (innermode);
- mode = int_mode_for_size (nbits, 0).else_blk ();
+ if (int_mode_for_size (nbits, 0).exists (&mode)
+ && have_regs_of_mode[mode])
+ return mode;
}
- if (mode == VOIDmode
- || (GET_MODE_CLASS (mode) == MODE_INT
- && !have_regs_of_mode[mode]))
- return BLKmode;
-
- return mode;
+ return opt_machine_mode ();
}
/* Return the mode for a vector that has NUNITS integer elements of
@@ -525,12 +521,10 @@ mode_for_vector (scalar_mode innermode,
mode_for_int_vector (unsigned int int_bits, unsigned int nunits)
{
scalar_int_mode int_mode;
- if (int_mode_for_size (int_bits, 0).exists (&int_mode))
- {
- machine_mode vec_mode = mode_for_vector (int_mode, nunits);
- if (vec_mode != BLKmode)
- return vec_mode;
- }
+ machine_mode vec_mode;
+ if (int_mode_for_size (int_bits, 0).exists (&int_mode)
+ && mode_for_vector (int_mode, nunits).exists (&vec_mode))
+ return vec_mode;
return opt_machine_mode ();
}
@@ -2264,7 +2258,7 @@ layout_type (tree type)
if (TYPE_MODE (type) == VOIDmode)
SET_TYPE_MODE (type,
mode_for_vector (SCALAR_TYPE_MODE (innertype),
- nunits));
+ nunits).else_blk ());
TYPE_SATURATING (type) = TYPE_SATURATING (TREE_TYPE (type));
TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c 2017-09-04 12:18:44.903326171 +0100
+++ gcc/config/i386/i386.c 2017-09-04 12:18:55.808284598 +0100
@@ -27420,9 +27420,8 @@ emit_memmov (rtx destmem, rtx *srcmem, r
if (GET_MODE_SIZE (move_mode) > GET_MODE_SIZE (word_mode))
{
int nunits = GET_MODE_SIZE (move_mode) / GET_MODE_SIZE (word_mode);
- move_mode = mode_for_vector (word_mode, nunits);
- code = optab_handler (mov_optab, move_mode);
- if (code == CODE_FOR_nothing)
+ if (!mode_for_vector (word_mode, nunits).exists (&move_mode)
+ || (code = optab_handler (mov_optab, move_mode)) == CODE_FOR_nothing)
{
move_mode = word_mode;
piece_size = GET_MODE_SIZE (move_mode);
@@ -28654,8 +28653,8 @@ ix86_expand_set_or_movmem (rtx dst, rtx
if (GET_MODE_SIZE (move_mode) > GET_MODE_SIZE (word_mode))
{
int nunits = GET_MODE_SIZE (move_mode) / GET_MODE_SIZE (word_mode);
- move_mode = mode_for_vector (word_mode, nunits);
- if (optab_handler (mov_optab, move_mode) == CODE_FOR_nothing)
+ if (!mode_for_vector (word_mode, nunits).exists (&move_mode)
+ || optab_handler (mov_optab, move_mode) == CODE_FOR_nothing)
move_mode = word_mode;
}
gcc_assert (optab_handler (mov_optab, move_mode) != CODE_FOR_nothing);
@@ -44497,11 +44496,9 @@ ix86_expand_vector_init (bool mmx_ok, rt
rtx ops[2] = { XVECEXP (vals, 0, 0), XVECEXP (vals, 0, 1) };
if (inner_mode == QImode || inner_mode == HImode)
{
- mode = mode_for_vector (SImode,
- n_elts * GET_MODE_SIZE (inner_mode) / 4);
- inner_mode
- = mode_for_vector (SImode,
- n_elts * GET_MODE_SIZE (inner_mode) / 8);
+ unsigned int n_bits = n_elts * GET_MODE_SIZE (inner_mode);
+ mode = mode_for_vector (SImode, n_bits / 4).require ();
+ inner_mode = mode_for_vector (SImode, n_bits / 8).require ();
ops[0] = gen_lowpart (inner_mode, ops[0]);
ops[1] = gen_lowpart (inner_mode, ops[1]);
subtarget = gen_reg_rtx (mode);
@@ -51619,7 +51616,7 @@ ix86_get_mask_mode (unsigned nunits, uns
gcc_assert (elem_size * nunits == vector_size);
- return mode_for_vector (elem_mode, nunits);
+ return mode_for_vector (elem_mode, nunits).else_blk ();
}
Index: gcc/config/powerpcspe/powerpcspe.c
===================================================================
--- gcc/config/powerpcspe/powerpcspe.c 2017-09-04 12:18:53.148287319 +0100
+++ gcc/config/powerpcspe/powerpcspe.c 2017-09-04 12:18:55.812299689 +0100
@@ -38679,7 +38679,7 @@ rs6000_expand_vec_perm_const_1 (rtx targ
vmode = GET_MODE (target);
gcc_assert (GET_MODE_NUNITS (vmode) == 2);
- dmode = mode_for_vector (GET_MODE_INNER (vmode), 4);
+ dmode = mode_for_vector (GET_MODE_INNER (vmode), 4).require ();
x = gen_rtx_VEC_CONCAT (dmode, op0, op1);
v = gen_rtvec (2, GEN_INT (perm0), GEN_INT (perm1));
x = gen_rtx_VEC_SELECT (vmode, x, gen_rtx_PARALLEL (VOIDmode, v));
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c 2017-09-04 12:18:53.151298637 +0100
+++ gcc/config/rs6000/rs6000.c 2017-09-04 12:18:55.815311006 +0100
@@ -35525,7 +35525,7 @@ rs6000_expand_vec_perm_const_1 (rtx targ
vmode = GET_MODE (target);
gcc_assert (GET_MODE_NUNITS (vmode) == 2);
- dmode = mode_for_vector (GET_MODE_INNER (vmode), 4);
+ dmode = mode_for_vector (GET_MODE_INNER (vmode), 4).require ();
x = gen_rtx_VEC_CONCAT (dmode, op0, op1);
v = gen_rtvec (2, GEN_INT (perm0), GEN_INT (perm1));
x = gen_rtx_VEC_SELECT (vmode, x, gen_rtx_PARALLEL (VOIDmode, v));
Index: gcc/expmed.c
===================================================================
--- gcc/expmed.c 2017-09-04 12:18:50.673054653 +0100
+++ gcc/expmed.c 2017-09-04 12:18:55.817318551 +0100
@@ -1578,10 +1578,11 @@ extract_bit_field_1 (rtx str_rtx, unsign
machine_mode new_mode = GET_MODE (op0);
if (GET_MODE_INNER (new_mode) != GET_MODE_INNER (tmode))
{
- new_mode = mode_for_vector (GET_MODE_INNER (tmode),
- GET_MODE_BITSIZE (GET_MODE (op0))
- / GET_MODE_UNIT_BITSIZE (tmode));
- if (!VECTOR_MODE_P (new_mode)
+ scalar_mode inner_mode = GET_MODE_INNER (tmode);
+ unsigned int nunits = (GET_MODE_BITSIZE (GET_MODE (op0))
+ / GET_MODE_UNIT_BITSIZE (tmode));
+ if (!mode_for_vector (inner_mode, nunits).exists (&new_mode)
+ || !VECTOR_MODE_P (new_mode)
|| GET_MODE_SIZE (new_mode) != GET_MODE_SIZE (GET_MODE (op0))
|| GET_MODE_INNER (new_mode) != GET_MODE_INNER (tmode)
|| !targetm.vector_mode_supported_p (new_mode))
Index: gcc/expr.c
===================================================================
--- gcc/expr.c 2017-09-04 12:18:44.938520082 +0100
+++ gcc/expr.c 2017-09-04 12:18:55.820329869 +0100
@@ -9445,7 +9445,7 @@ #define REDUCE_BIT_FIELD(expr) (reduce_b
tree sel_type = TREE_TYPE (treeop2);
machine_mode vmode
= mode_for_vector (SCALAR_TYPE_MODE (TREE_TYPE (sel_type)),
- TYPE_VECTOR_SUBPARTS (sel_type));
+ TYPE_VECTOR_SUBPARTS (sel_type)).require ();
gcc_assert (GET_MODE_CLASS (vmode) == MODE_VECTOR_INT);
op2 = simplify_subreg (vmode, op2, TYPE_MODE (sel_type), 0);
gcc_assert (op2 && GET_CODE (op2) == CONST_VECTOR);
Index: gcc/optabs-query.c
===================================================================
--- gcc/optabs-query.c 2017-08-30 12:20:31.700622400 +0100
+++ gcc/optabs-query.c 2017-09-04 12:18:55.821333642 +0100
@@ -376,10 +376,9 @@ can_vec_perm_p (machine_mode mode, bool
return true;
/* We allow fallback to a QI vector mode, and adjust the mask. */
- if (GET_MODE_INNER (mode) == QImode)
- return false;
- qimode = mode_for_vector (QImode, GET_MODE_SIZE (mode));
- if (!VECTOR_MODE_P (qimode))
+ if (GET_MODE_INNER (mode) == QImode
+ || !mode_for_vector (QImode, GET_MODE_SIZE (mode)).exists (&qimode)
+ || !VECTOR_MODE_P (qimode))
return false;
/* ??? For completeness, we ought to check the QImode version of
@@ -547,12 +546,14 @@ can_vec_mask_load_store_p (machine_mode
vector_sizes &= ~cur;
if (cur <= GET_MODE_SIZE (smode))
continue;
- vmode = mode_for_vector (smode, cur / GET_MODE_SIZE (smode));
- mask_mode = targetm.vectorize.get_mask_mode (GET_MODE_NUNITS (vmode),
- cur);
- if (VECTOR_MODE_P (vmode)
- && convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing)
- return true;
+ unsigned int nunits = cur / GET_MODE_SIZE (smode);
+ if (mode_for_vector (smode, nunits).exists (&vmode)
+ && VECTOR_MODE_P (vmode))
+ {
+ mask_mode = targetm.vectorize.get_mask_mode (nunits, cur);
+ if (convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing)
+ return true;
+ }
}
return false;
}
Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c 2017-09-04 11:48:08.609549644 +0100
+++ gcc/optabs.c 2017-09-04 12:18:55.823341187 +0100
@@ -5434,13 +5434,10 @@ expand_vec_perm (machine_mode mode, rtx
/* Set QIMODE to a different vector mode with byte elements.
If no such mode, or if MODE already has byte elements, use VOIDmode. */
- qimode = VOIDmode;
- if (GET_MODE_INNER (mode) != QImode)
- {
- qimode = mode_for_vector (QImode, w);
- if (!VECTOR_MODE_P (qimode))
- qimode = VOIDmode;
- }
+ if (GET_MODE_INNER (mode) == QImode
+ || !mode_for_vector (QImode, w).exists (&qimode)
+ || !VECTOR_MODE_P (qimode))
+ qimode = VOIDmode;
/* If the input is a constant, expand it specially. */
gcc_assert (GET_MODE_CLASS (GET_MODE (sel)) == MODE_VECTOR_INT);
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c 2017-09-04 11:50:24.568774867 +0100
+++ gcc/targhooks.c 2017-09-04 12:18:55.825348732 +0100
@@ -1210,8 +1210,8 @@ default_get_mask_mode (unsigned nunits,
gcc_assert (elem_size * nunits == vector_size);
- vector_mode = mode_for_vector (elem_mode, nunits);
- if (!VECTOR_MODE_P (vector_mode)
+ if (!mode_for_vector (elem_mode, nunits).exists (&vector_mode)
+ || !VECTOR_MODE_P (vector_mode)
|| !targetm.vector_mode_supported_p (vector_mode))
vector_mode = BLKmode;
Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c 2017-08-31 07:32:43.676061469 +0100
+++ gcc/tree-vect-stmts.c 2017-09-04 12:18:55.828360049 +0100
@@ -6032,8 +6032,9 @@ vectorizable_store (gimple *stmt, gimple
/* First check if vec_extract optab doesn't support extraction
of vector elts directly. */
scalar_mode elmode = SCALAR_TYPE_MODE (elem_type);
- machine_mode vmode = mode_for_vector (elmode, group_size);
- if (! VECTOR_MODE_P (vmode)
+ machine_mode vmode;
+ if (!mode_for_vector (elmode, group_size).exists (&vmode)
+ || !VECTOR_MODE_P (vmode)
|| (convert_optab_handler (vec_extract_optab,
TYPE_MODE (vectype), vmode)
== CODE_FOR_nothing))
@@ -6046,11 +6047,12 @@ vectorizable_store (gimple *stmt, gimple
unsigned lsize
= group_size * GET_MODE_BITSIZE (elmode);
elmode = int_mode_for_size (lsize, 0).require ();
- vmode = mode_for_vector (elmode, nunits / group_size);
/* If we can't construct such a vector fall back to
element extracts from the original vector type and
element size stores. */
- if (VECTOR_MODE_P (vmode)
+ if (mode_for_vector (elmode,
+ nunits / group_size).exists (&vmode)
+ && VECTOR_MODE_P (vmode)
&& (convert_optab_handler (vec_extract_optab,
vmode, elmode)
!= CODE_FOR_nothing))
@@ -7070,8 +7072,9 @@ vectorizable_load (gimple *stmt, gimple_
/* First check if vec_init optab supports construction from
vector elts directly. */
scalar_mode elmode = SCALAR_TYPE_MODE (TREE_TYPE (vectype));
- machine_mode vmode = mode_for_vector (elmode, group_size);
- if (VECTOR_MODE_P (vmode)
+ machine_mode vmode;
+ if (mode_for_vector (elmode, group_size).exists (&vmode)
+ && VECTOR_MODE_P (vmode)
&& (convert_optab_handler (vec_init_optab,
TYPE_MODE (vectype), vmode)
!= CODE_FOR_nothing))
@@ -7092,10 +7095,11 @@ vectorizable_load (gimple *stmt, gimple_
unsigned lsize
= group_size * TYPE_PRECISION (TREE_TYPE (vectype));
elmode = int_mode_for_size (lsize, 0).require ();
- vmode = mode_for_vector (elmode, nunits / group_size);
/* If we can't construct such a vector fall back to
element loads of the original vector type. */
- if (VECTOR_MODE_P (vmode)
+ if (mode_for_vector (elmode,
+ nunits / group_size).exists (&vmode)
+ && VECTOR_MODE_P (vmode)
&& (convert_optab_handler (vec_init_optab, vmode, elmode)
!= CODE_FOR_nothing))
{
@@ -9098,8 +9102,8 @@ get_vectype_for_scalar_type_and_size (tr
lookup a vector mode of the specified size. */
if (size == 0)
simd_mode = targetm.vectorize.preferred_simd_mode (inner_mode);
- else
- simd_mode = mode_for_vector (inner_mode, size / nbytes);
+ else if (!mode_for_vector (inner_mode, size / nbytes).exists (&simd_mode))
+ return NULL_TREE;
nunits = GET_MODE_SIZE (simd_mode) / nbytes;
/* NOTE: nunits == 1 is allowed to support single element vector types. */
if (nunits < 1)