On Tue, Nov 5, 2019 at 9:25 PM Richard Sandiford
<[email protected]> wrote:
>
> Patch 12/n makes the AArch64 port add four entries to
> autovectorize_vector_modes. Each entry describes a different
> vector mode assignment for vector code that mixes 8-bit, 16-bit,
> 32-bit and 64-bit elements. But if (as usual) the vector code has
> fewer element sizes than that, we could end up trying the same
> combination of vector modes multiple times. This patch adds a
> check to prevent that.
>
> As before: each patch tested individually on aarch64-linux-gnu and the
> series as a whole on x86_64-linux-gnu.
>
>
> 2019-11-04 Richard Sandiford <[email protected]>
>
> gcc/
> * tree-vectorizer.h (vec_info::mode_set): New typedef.
> (vec_info::used_vector_mode): New member variable.
> (vect_chooses_same_modes_p): Declare.
> * tree-vect-stmts.c (get_vectype_for_scalar_type): Record each
> chosen vector mode in vec_info::used_vector_mode.
> (vect_chooses_same_modes_p): New function.
> * tree-vect-loop.c (vect_analyze_loop): Use it to avoid trying
> the same vector statements multiple times.
> * tree-vect-slp.c (vect_slp_bb_region): Likewise.
>
> Index: gcc/tree-vectorizer.h
> ===================================================================
> --- gcc/tree-vectorizer.h 2019-11-05 10:48:11.246092351 +0000
> +++ gcc/tree-vectorizer.h 2019-11-05 10:57:41.662071145 +0000
> @@ -298,6 +298,7 @@ typedef std::pair<tree, tree> vec_object
> /* Vectorizer state common between loop and basic-block vectorization. */
> class vec_info {
> public:
> + typedef hash_set<int_hash<machine_mode, E_VOIDmode, E_BLKmode> > mode_set;
> enum vec_kind { bb, loop };
>
> vec_info (vec_kind, void *, vec_info_shared *);
> @@ -335,6 +336,9 @@ typedef std::pair<tree, tree> vec_object
> /* Cost data used by the target cost model. */
> void *target_cost_data;
>
> + /* The set of vector modes used in the vectorized region. */
> + mode_set used_vector_modes;
> +
> /* The argument we should pass to related_vector_mode when looking up
> the vector mode for a scalar mode, or VOIDmode if we haven't yet
> made any decisions about which vector modes to use. */
> @@ -1615,6 +1619,7 @@ extern tree get_related_vectype_for_scal
> extern tree get_vectype_for_scalar_type (vec_info *, tree);
> extern tree get_mask_type_for_scalar_type (vec_info *, tree);
> extern tree get_same_sized_vectype (tree, tree);
> +extern bool vect_chooses_same_modes_p (vec_info *, machine_mode);
> extern bool vect_get_loop_mask_type (loop_vec_info);
> extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *,
> stmt_vec_info * = NULL, gimple ** = NULL);
> Index: gcc/tree-vect-stmts.c
> ===================================================================
> --- gcc/tree-vect-stmts.c 2019-11-05 10:48:11.242092379 +0000
> +++ gcc/tree-vect-stmts.c 2019-11-05 10:57:41.662071145 +0000
> @@ -11235,6 +11235,10 @@ get_vectype_for_scalar_type (vec_info *v
> scalar_type);
> if (vectype && vinfo->vector_mode == VOIDmode)
> vinfo->vector_mode = TYPE_MODE (vectype);
> +
> + if (vectype)
> + vinfo->used_vector_modes.add (TYPE_MODE (vectype));
> +
Do we actually end up _using_ all types returned by this function?
Otherwise OK.
Richard.
> return vectype;
> }
>
> @@ -11274,6 +11278,20 @@ get_same_sized_vectype (tree scalar_type
> scalar_type, nunits);
> }
>
> +/* Return true if replacing LOOP_VINFO->vector_mode with VECTOR_MODE
> + would not change the chosen vector modes. */
> +
> +bool
> +vect_chooses_same_modes_p (vec_info *vinfo, machine_mode vector_mode)
> +{
> + for (vec_info::mode_set::iterator i = vinfo->used_vector_modes.begin ();
> + i != vinfo->used_vector_modes.end (); ++i)
> + if (!VECTOR_MODE_P (*i)
> + || related_vector_mode (vector_mode, GET_MODE_INNER (*i), 0) != *i)
> + return false;
> + return true;
> +}
> +
> /* Function vect_is_simple_use.
>
> Input:
> Index: gcc/tree-vect-loop.c
> ===================================================================
> --- gcc/tree-vect-loop.c 2019-11-05 10:48:11.238092407 +0000
> +++ gcc/tree-vect-loop.c 2019-11-05 10:57:41.658071173 +0000
> @@ -2430,6 +2430,19 @@ vect_analyze_loop (class loop *loop, vec
> }
>
> loop->aux = NULL;
> +
> + if (!fatal)
> + while (mode_i < vector_modes.length ()
> + && vect_chooses_same_modes_p (loop_vinfo,
> vector_modes[mode_i]))
> + {
> + if (dump_enabled_p ())
> + dump_printf_loc (MSG_NOTE, vect_location,
> + "***** The result for vector mode %s would"
> + " be the same\n",
> + GET_MODE_NAME (vector_modes[mode_i]));
> + mode_i += 1;
> + }
> +
> if (res)
> {
> LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
> Index: gcc/tree-vect-slp.c
> ===================================================================
> --- gcc/tree-vect-slp.c 2019-11-05 10:48:11.242092379 +0000
> +++ gcc/tree-vect-slp.c 2019-11-05 10:57:41.662071145 +0000
> @@ -3238,6 +3238,18 @@ vect_slp_bb_region (gimple_stmt_iterator
> if (mode_i == 0)
> autodetected_vector_mode = bb_vinfo->vector_mode;
>
> + if (!fatal)
> + while (mode_i < vector_modes.length ()
> + && vect_chooses_same_modes_p (bb_vinfo, vector_modes[mode_i]))
> + {
> + if (dump_enabled_p ())
> + dump_printf_loc (MSG_NOTE, vect_location,
> + "***** The result for vector mode %s would"
> + " be the same\n",
> + GET_MODE_NAME (vector_modes[mode_i]));
> + mode_i += 1;
> + }
> +
> delete bb_vinfo;
>
> if (mode_i < vector_modes.length ()