+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.
}
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;
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 ()
scalar_type);
if (vectype && vinfo->vector_mode == VOIDmode)
vinfo->vector_mode = TYPE_MODE (vectype);
+
+ if (vectype)
+ vinfo->used_vector_modes.add (TYPE_MODE (vectype));
+
return vectype;
}
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:
/* 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 *);
/* 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. */
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);