+2019-10-21 Richard Sandiford <richard.sandiford@arm.com>
+
+ * tree-vectorizer.h (vec_info::vector_size): New member variable.
+ (vect_update_max_nunits): Update comment.
+ (current_vector_size): Delete.
+ * tree-vect-stmts.c (current_vector_size): Likewise.
+ (get_vectype_for_scalar_type): Use vec_info::vector_size instead
+ of current_vector_size.
+ (get_mask_type_for_scalar_type): Likewise.
+ * tree-vectorizer.c (try_vectorize_loop_1): Likewise.
+ * tree-vect-loop.c (vect_update_vf_for_slp): Likewise.
+ (vect_analyze_loop, vect_halve_mask_nunits): Likewise.
+ (vect_double_mask_nunits, vect_transform_loop): Likewise.
+ * tree-vect-slp.c (can_duplicate_and_interleave_p): Likewise.
+ (vect_make_slp_decision, vect_slp_bb_region): Likewise.
+
2019-10-21 Richard Sandiford <richard.sandiford@arm.com>
* tree-vectorizer.h (vect_double_mask_nunits): Take a vec_info.
dump_printf_loc (MSG_NOTE, vect_location,
"Loop contains SLP and non-SLP stmts\n");
/* Both the vectorization factor and unroll factor have the form
- current_vector_size * X for some rational X, so they must have
+ loop_vinfo->vector_size * X for some rational X, so they must have
a common multiple. */
vectorization_factor
= force_common_multiple (vectorization_factor,
auto_vector_sizes vector_sizes;
/* Autodetect first vector size we try. */
- current_vector_size = 0;
targetm.vectorize.autovectorize_vector_sizes (&vector_sizes,
loop->simdlen != 0);
unsigned int next_size = 0;
unsigned n_stmts = 0;
poly_uint64 autodetected_vector_size = 0;
opt_loop_vec_info first_loop_vinfo = opt_loop_vec_info::success (NULL);
- poly_uint64 first_vector_size = 0;
+ poly_uint64 next_vector_size = 0;
while (1)
{
/* Check the CFG characteristics of the loop (nesting, entry/exit). */
gcc_checking_assert (first_loop_vinfo == NULL);
return loop_vinfo;
}
+ loop_vinfo->vector_size = next_vector_size;
bool fatal = false;
if (first_loop_vinfo == NULL)
{
first_loop_vinfo = loop_vinfo;
- first_vector_size = current_vector_size;
loop->aux = NULL;
}
else
delete loop_vinfo;
if (next_size == 0)
- autodetected_vector_size = current_vector_size;
+ autodetected_vector_size = loop_vinfo->vector_size;
if (next_size < vector_sizes.length ()
&& known_eq (vector_sizes[next_size], autodetected_vector_size))
}
if (next_size == vector_sizes.length ()
- || known_eq (current_vector_size, 0U))
+ || known_eq (loop_vinfo->vector_size, 0U))
{
if (first_loop_vinfo)
{
- current_vector_size = first_vector_size;
loop->aux = (loop_vec_info) first_loop_vinfo;
if (dump_enabled_p ())
{
dump_printf_loc (MSG_NOTE, vect_location,
"***** Choosing vector size ");
- dump_dec (MSG_NOTE, current_vector_size);
+ dump_dec (MSG_NOTE, first_loop_vinfo->vector_size);
dump_printf (MSG_NOTE, "\n");
}
return first_loop_vinfo;
}
/* Try the next biggest vector size. */
- current_vector_size = vector_sizes[next_size++];
+ next_vector_size = vector_sizes[next_size++];
if (dump_enabled_p ())
{
dump_printf_loc (MSG_NOTE, vect_location,
"***** Re-trying analysis with "
"vector size ");
- dump_dec (MSG_NOTE, current_vector_size);
+ dump_dec (MSG_NOTE, next_vector_size);
dump_printf (MSG_NOTE, "\n");
}
}
/* Return a mask type with half the number of elements as TYPE. */
tree
-vect_halve_mask_nunits (vec_info *, tree type)
+vect_halve_mask_nunits (vec_info *vinfo, tree type)
{
poly_uint64 nunits = exact_div (TYPE_VECTOR_SUBPARTS (type), 2);
- return build_truth_vector_type (nunits, current_vector_size);
+ return build_truth_vector_type (nunits, vinfo->vector_size);
}
/* Return a mask type with twice as many elements as TYPE. */
tree
-vect_double_mask_nunits (vec_info *, tree type)
+vect_double_mask_nunits (vec_info *vinfo, tree type)
{
poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (type) * 2;
- return build_truth_vector_type (nunits, current_vector_size);
+ return build_truth_vector_type (nunits, vinfo->vector_size);
}
/* Record that a fully-masked version of LOOP_VINFO would need MASKS to
{
dump_printf_loc (MSG_NOTE, vect_location,
"LOOP EPILOGUE VECTORIZED (VS=");
- dump_dec (MSG_NOTE, current_vector_size);
+ dump_dec (MSG_NOTE, loop_vinfo->vector_size);
dump_printf (MSG_NOTE, ")\n");
}
}
unsigned int ratio;
while (next_size < vector_sizes.length ()
- && !(constant_multiple_p (current_vector_size,
+ && !(constant_multiple_p (loop_vinfo->vector_size,
vector_sizes[next_size], &ratio)
&& eiters >= lowest_vf / ratio))
next_size += 1;
}
else
while (next_size < vector_sizes.length ()
- && maybe_lt (current_vector_size, vector_sizes[next_size]))
+ && maybe_lt (loop_vinfo->vector_size, vector_sizes[next_size]))
next_size += 1;
if (next_size == vector_sizes.length ())
(if nonnull). */
bool
-can_duplicate_and_interleave_p (vec_info *, unsigned int count,
+can_duplicate_and_interleave_p (vec_info *vinfo, unsigned int count,
machine_mode elt_mode,
unsigned int *nvectors_out,
tree *vector_type_out,
{
scalar_int_mode int_mode;
poly_int64 elt_bits = elt_bytes * BITS_PER_UNIT;
- if (multiple_p (current_vector_size, elt_bytes, &nelts)
+ if (multiple_p (vinfo->vector_size, elt_bytes, &nelts)
&& int_mode_for_size (elt_bits, 0).exists (&int_mode))
{
tree int_type = build_nonstandard_integer_type
}
if ((dt == vect_constant_def
|| dt == vect_external_def)
- && !current_vector_size.is_constant ()
+ && !vinfo->vector_size.is_constant ()
&& (TREE_CODE (type) == BOOLEAN_TYPE
|| !can_duplicate_and_interleave_p (vinfo, stmts.length (),
TYPE_MODE (type))))
FOR_EACH_VEC_ELT (slp_instances, i, instance)
{
/* FORNOW: SLP if you can. */
- /* All unroll factors have the form current_vector_size * X for some
+ /* All unroll factors have the form vinfo->vector_size * X for some
rational X, so they must have a common multiple. */
unrolling_factor
= force_common_multiple (unrolling_factor,
auto_vector_sizes vector_sizes;
/* Autodetect first vector size we try. */
- current_vector_size = 0;
+ poly_uint64 next_vector_size = 0;
targetm.vectorize.autovectorize_vector_sizes (&vector_sizes, false);
unsigned int next_size = 0;
bb_vinfo->shared->save_datarefs ();
else
bb_vinfo->shared->check_datarefs ();
+ bb_vinfo->vector_size = next_vector_size;
if (vect_slp_analyze_bb_1 (bb_vinfo, n_stmts, fatal)
&& dbg_cnt (vect_slp))
unsigned HOST_WIDE_INT bytes;
if (dump_enabled_p ())
{
- if (current_vector_size.is_constant (&bytes))
+ if (bb_vinfo->vector_size.is_constant (&bytes))
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
"basic block part vectorized using %wu byte "
"vectors\n", bytes);
vectorized = true;
}
- delete bb_vinfo;
if (next_size == 0)
- autodetected_vector_size = current_vector_size;
+ autodetected_vector_size = bb_vinfo->vector_size;
+
+ delete bb_vinfo;
if (next_size < vector_sizes.length ()
&& known_eq (vector_sizes[next_size], autodetected_vector_size))
if (vectorized
|| next_size == vector_sizes.length ()
- || known_eq (current_vector_size, 0U)
+ || known_eq (bb_vinfo->vector_size, 0U)
/* If vect_slp_analyze_bb_1 signaled that analysis for all
vector sizes will fail do not bother iterating. */
|| fatal)
return vectorized;
/* Try the next biggest vector size. */
- current_vector_size = vector_sizes[next_size++];
+ next_vector_size = vector_sizes[next_size++];
if (dump_enabled_p ())
{
dump_printf_loc (MSG_NOTE, vect_location,
"***** Re-trying analysis with "
"vector size ");
- dump_dec (MSG_NOTE, current_vector_size);
+ dump_dec (MSG_NOTE, next_vector_size);
dump_printf (MSG_NOTE, "\n");
}
}
return vectype;
}
-poly_uint64 current_vector_size;
-
/* Function get_vectype_for_scalar_type.
Returns the vector type corresponding to SCALAR_TYPE as supported
by the target. */
tree
-get_vectype_for_scalar_type (vec_info *, tree scalar_type)
+get_vectype_for_scalar_type (vec_info *vinfo, tree scalar_type)
{
tree vectype;
vectype = get_vectype_for_scalar_type_and_size (scalar_type,
- current_vector_size);
+ vinfo->vector_size);
if (vectype
- && known_eq (current_vector_size, 0U))
- current_vector_size = GET_MODE_SIZE (TYPE_MODE (vectype));
+ && known_eq (vinfo->vector_size, 0U))
+ vinfo->vector_size = GET_MODE_SIZE (TYPE_MODE (vectype));
return vectype;
}
return NULL;
return build_truth_vector_type (TYPE_VECTOR_SUBPARTS (vectype),
- current_vector_size);
+ vinfo->vector_size);
}
/* Function get_same_sized_vectype
unsigned HOST_WIDE_INT bytes;
if (dump_enabled_p ())
{
- if (current_vector_size.is_constant (&bytes))
+ if (loop_vinfo->vector_size.is_constant (&bytes))
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
"loop vectorized using %wu byte vectors\n", bytes);
else
/* Cost data used by the target cost model. */
void *target_cost_data;
+ /* The vector size for this loop in bytes, or 0 if we haven't picked
+ a size yet. */
+ poly_uint64 vector_size;
+
private:
stmt_vec_info new_stmt_vec_info (gimple *stmt);
void set_vinfo_for_stmt (gimple *, stmt_vec_info);
static inline void
vect_update_max_nunits (poly_uint64 *max_nunits, poly_uint64 nunits)
{
- /* All unit counts have the form current_vector_size * X for some
+ /* All unit counts have the form vec_info::vector_size * X for some
rational X, so two unit sizes must have a common multiple.
Everything is a multiple of the initial value of 1. */
*max_nunits = force_common_multiple (*max_nunits, nunits);
extern bool vect_can_advance_ivs_p (loop_vec_info);
/* In tree-vect-stmts.c. */
-extern poly_uint64 current_vector_size;
extern tree get_vectype_for_scalar_type (vec_info *, tree);
extern tree get_vectype_for_scalar_type_and_size (tree, poly_uint64);
extern tree get_mask_type_for_scalar_type (vec_info *, tree);