Commit a55d8232 by Richard Sandiford Committed by Richard Sandiford

Avoid retrying with the same vector modes

A later patch 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.

2019-11-14  Richard Sandiford  <richard.sandiford@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.

From-SVN: r278242
parent df7c2283
2019-11-14 Richard Sandiford <richard.sandiford@arm.com> 2019-11-14 Richard Sandiford <richard.sandiford@arm.com>
* 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.
2019-11-14 Richard Sandiford <richard.sandiford@arm.com>
* machmode.h (opt_machine_mode::operator==): New function. * machmode.h (opt_machine_mode::operator==): New function.
(opt_machine_mode::operator!=): Likewise. (opt_machine_mode::operator!=): Likewise.
* tree-vectorizer.h (vec_info::vector_mode): Update comment. * tree-vectorizer.h (vec_info::vector_mode): Update comment.
...@@ -2448,6 +2448,19 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared) ...@@ -2448,6 +2448,19 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared)
} }
loop->aux = NULL; 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) if (res)
{ {
LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1; LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
......
...@@ -3239,6 +3239,18 @@ vect_slp_bb_region (gimple_stmt_iterator region_begin, ...@@ -3239,6 +3239,18 @@ vect_slp_bb_region (gimple_stmt_iterator region_begin,
if (mode_i == 0) if (mode_i == 0)
autodetected_vector_mode = bb_vinfo->vector_mode; 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; delete bb_vinfo;
if (mode_i < vector_modes.length () if (mode_i < vector_modes.length ()
......
...@@ -11263,6 +11263,10 @@ get_vectype_for_scalar_type (vec_info *vinfo, tree scalar_type) ...@@ -11263,6 +11263,10 @@ get_vectype_for_scalar_type (vec_info *vinfo, tree scalar_type)
scalar_type); scalar_type);
if (vectype && vinfo->vector_mode == VOIDmode) if (vectype && vinfo->vector_mode == VOIDmode)
vinfo->vector_mode = TYPE_MODE (vectype); vinfo->vector_mode = TYPE_MODE (vectype);
if (vectype)
vinfo->used_vector_modes.add (TYPE_MODE (vectype));
return vectype; return vectype;
} }
...@@ -11302,6 +11306,20 @@ get_same_sized_vectype (tree scalar_type, tree vector_type) ...@@ -11302,6 +11306,20 @@ get_same_sized_vectype (tree scalar_type, tree vector_type)
scalar_type, nunits); 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. /* Function vect_is_simple_use.
Input: Input:
......
...@@ -298,6 +298,7 @@ public: ...@@ -298,6 +298,7 @@ public:
/* Vectorizer state common between loop and basic-block vectorization. */ /* Vectorizer state common between loop and basic-block vectorization. */
class vec_info { class vec_info {
public: public:
typedef hash_set<int_hash<machine_mode, E_VOIDmode, E_BLKmode> > mode_set;
enum vec_kind { bb, loop }; enum vec_kind { bb, loop };
vec_info (vec_kind, void *, vec_info_shared *); vec_info (vec_kind, void *, vec_info_shared *);
...@@ -335,6 +336,9 @@ public: ...@@ -335,6 +336,9 @@ public:
/* Cost data used by the target cost model. */ /* Cost data used by the target cost model. */
void *target_cost_data; 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 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 the vector mode for a scalar mode, or VOIDmode if we haven't yet
made any decisions about which vector modes to use. */ made any decisions about which vector modes to use. */
...@@ -1630,6 +1634,7 @@ extern tree get_related_vectype_for_scalar_type (machine_mode, tree, ...@@ -1630,6 +1634,7 @@ extern tree get_related_vectype_for_scalar_type (machine_mode, tree,
extern tree get_vectype_for_scalar_type (vec_info *, tree); extern tree get_vectype_for_scalar_type (vec_info *, tree);
extern tree get_mask_type_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 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_get_loop_mask_type (loop_vec_info);
extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *, extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *,
stmt_vec_info * = NULL, gimple ** = NULL); stmt_vec_info * = NULL, gimple ** = NULL);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment