This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [6/9] Make mode_for_vector return an opt_mode
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Richard Sandiford <richard dot sandiford at linaro dot org>
- Date: Tue, 5 Sep 2017 13:37:06 +0200
- Subject: Re: [6/9] Make mode_for_vector return an opt_mode
- Authentication-results: sourceware.org; auth=none
- References: <87tw0iiu51.fsf@linaro.org> <873782itg4.fsf@linaro.org>
On Mon, Sep 4, 2017 at 1:39 PM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> ...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.
Ok.
Richard.
> 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)