On Tue, Nov 5, 2019 at 9:25 PM Richard Sandiford
<richard.sandif...@arm.com> 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  <richard.sandif...@arm.com>
>
> 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 ()

Reply via email to