Commit e8f142e2 by Richard Sandiford Committed by Richard Sandiford

Add a vect_get_num_copies helper routine

This patch adds a vectoriser helper routine to calculate how
many copies of a vector statement we need.  At present this
is always:

  LOOP_VINFO_VECT_FACTOR (loop_vinfo) / TYPE_VECTOR_SUBPARTS (vectype)

but later patches add other cases.  Another benefit of using
a helper routine is that it can assert that the division is
exact (which it must be).

2017-09-14  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* tree-vectorizer.h (vect_get_num_copies): New function.
	* tree-vect-data-refs.c (vect_get_data_access_cost): Use it.
	* tree-vect-loop.c (vectorizable_reduction): Likewise.
	(vectorizable_induction): Likewise.
	(vectorizable_live_operation): Likewise.
	* tree-vect-stmts.c (vectorizable_mask_load_store): Likewise.
	(vectorizable_bswap): Likewise.
	(vectorizable_call): Likewise.
	(vectorizable_conversion): Likewise.
	(vectorizable_assignment): Likewise.
	(vectorizable_shift): Likewise.
	(vectorizable_operation): Likewise.
	(vectorizable_store): Likewise.
	(vectorizable_load): Likewise.
	(vectorizable_condition): Likewise.
	(vectorizable_comparison): Likewise.
	(vect_analyze_stmt): Pass the slp node to vectorizable_live_operation.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r252764
parent dccf43ae
...@@ -2,6 +2,28 @@ ...@@ -2,6 +2,28 @@
Alan Hayward <alan.hayward@arm.com> Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com> David Sherwood <david.sherwood@arm.com>
* tree-vectorizer.h (vect_get_num_copies): New function.
* tree-vect-data-refs.c (vect_get_data_access_cost): Use it.
* tree-vect-loop.c (vectorizable_reduction): Likewise.
(vectorizable_induction): Likewise.
(vectorizable_live_operation): Likewise.
* tree-vect-stmts.c (vectorizable_mask_load_store): Likewise.
(vectorizable_bswap): Likewise.
(vectorizable_call): Likewise.
(vectorizable_conversion): Likewise.
(vectorizable_assignment): Likewise.
(vectorizable_shift): Likewise.
(vectorizable_operation): Likewise.
(vectorizable_store): Likewise.
(vectorizable_load): Likewise.
(vectorizable_condition): Likewise.
(vectorizable_comparison): Likewise.
(vect_analyze_stmt): Pass the slp node to vectorizable_live_operation.
2017-09-14 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* tree-vect-loop.c (vectorizable_induction): Use gimple_build instead * tree-vect-loop.c (vectorizable_induction): Use gimple_build instead
of vect_init_vector. of vect_init_vector.
......
...@@ -1181,10 +1181,13 @@ vect_get_data_access_cost (struct data_reference *dr, ...@@ -1181,10 +1181,13 @@ vect_get_data_access_cost (struct data_reference *dr,
{ {
gimple *stmt = DR_STMT (dr); gimple *stmt = DR_STMT (dr);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt); stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
int nunits = TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info));
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); int ncopies;
int ncopies = MAX (1, vf / nunits); /* TODO: Handle SLP properly */
if (PURE_SLP_STMT (stmt_info))
ncopies = 1;
else
ncopies = vect_get_num_copies (loop_vinfo, STMT_VINFO_VECTYPE (stmt_info));
if (DR_IS_READ (dr)) if (DR_IS_READ (dr))
vect_get_load_cost (dr, ncopies, true, inside_cost, outside_cost, vect_get_load_cost (dr, ncopies, true, inside_cost, outside_cost,
......
...@@ -5683,8 +5683,7 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi, ...@@ -5683,8 +5683,7 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node) if (slp_node)
ncopies = 1; ncopies = 1;
else else
ncopies = (LOOP_VINFO_VECT_FACTOR (loop_vinfo) ncopies = vect_get_num_copies (loop_vinfo, vectype_in);
/ TYPE_VECTOR_SUBPARTS (vectype_in));
use_operand_p use_p; use_operand_p use_p;
gimple *use_stmt; gimple *use_stmt;
...@@ -5980,8 +5979,7 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi, ...@@ -5980,8 +5979,7 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node) if (slp_node)
ncopies = 1; ncopies = 1;
else else
ncopies = (LOOP_VINFO_VECT_FACTOR (loop_vinfo) ncopies = vect_get_num_copies (loop_vinfo, vectype_in);
/ TYPE_VECTOR_SUBPARTS (vectype_in));
gcc_assert (ncopies >= 1); gcc_assert (ncopies >= 1);
...@@ -6550,7 +6548,7 @@ vectorizable_induction (gimple *phi, ...@@ -6550,7 +6548,7 @@ vectorizable_induction (gimple *phi,
if (slp_node) if (slp_node)
ncopies = 1; ncopies = 1;
else else
ncopies = vf / nunits; ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1); gcc_assert (ncopies >= 1);
/* FORNOW. These restrictions should be relaxed. */ /* FORNOW. These restrictions should be relaxed. */
...@@ -7013,12 +7011,17 @@ vectorizable_live_operation (gimple *stmt, ...@@ -7013,12 +7011,17 @@ vectorizable_live_operation (gimple *stmt,
tree lhs, lhs_type, bitsize, vec_bitsize; tree lhs, lhs_type, bitsize, vec_bitsize;
tree vectype = STMT_VINFO_VECTYPE (stmt_info); tree vectype = STMT_VINFO_VECTYPE (stmt_info);
int nunits = TYPE_VECTOR_SUBPARTS (vectype); int nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits; int ncopies;
gimple *use_stmt; gimple *use_stmt;
auto_vec<tree> vec_oprnds; auto_vec<tree> vec_oprnds;
gcc_assert (STMT_VINFO_LIVE_P (stmt_info)); gcc_assert (STMT_VINFO_LIVE_P (stmt_info));
if (slp_node)
ncopies = 1;
else
ncopies = vect_get_num_copies (loop_vinfo, vectype);
if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def) if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def)
return false; return false;
......
...@@ -2038,7 +2038,7 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi, ...@@ -2038,7 +2038,7 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node != NULL) if (slp_node != NULL)
return false; return false;
ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits; ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1); gcc_assert (ncopies >= 1);
mask = gimple_call_arg (stmt, 2); mask = gimple_call_arg (stmt, 2);
...@@ -2472,7 +2472,7 @@ vectorizable_bswap (gimple *stmt, gimple_stmt_iterator *gsi, ...@@ -2472,7 +2472,7 @@ vectorizable_bswap (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node) if (slp_node)
ncopies = 1; ncopies = 1;
else else
ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits; ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1); gcc_assert (ncopies >= 1);
...@@ -2805,9 +2805,9 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt, ...@@ -2805,9 +2805,9 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt,
if (slp_node) if (slp_node)
ncopies = 1; ncopies = 1;
else if (modifier == NARROW && ifn == IFN_LAST) else if (modifier == NARROW && ifn == IFN_LAST)
ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_out; ncopies = vect_get_num_copies (loop_vinfo, vectype_out);
else else
ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in; ncopies = vect_get_num_copies (loop_vinfo, vectype_in);
/* Sanity check: make sure that at least one copy of the vectorized stmt /* Sanity check: make sure that at least one copy of the vectorized stmt
needs to be generated. */ needs to be generated. */
...@@ -4204,9 +4204,9 @@ vectorizable_conversion (gimple *stmt, gimple_stmt_iterator *gsi, ...@@ -4204,9 +4204,9 @@ vectorizable_conversion (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node) if (slp_node)
ncopies = 1; ncopies = 1;
else if (modifier == NARROW) else if (modifier == NARROW)
ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_out; ncopies = vect_get_num_copies (loop_vinfo, vectype_out);
else else
ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in; ncopies = vect_get_num_copies (loop_vinfo, vectype_in);
/* Sanity check: make sure that at least one copy of the vectorized stmt /* Sanity check: make sure that at least one copy of the vectorized stmt
needs to be generated. */ needs to be generated. */
...@@ -4690,7 +4690,7 @@ vectorizable_assignment (gimple *stmt, gimple_stmt_iterator *gsi, ...@@ -4690,7 +4690,7 @@ vectorizable_assignment (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node) if (slp_node)
ncopies = 1; ncopies = 1;
else else
ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits; ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1); gcc_assert (ncopies >= 1);
...@@ -4948,7 +4948,7 @@ vectorizable_shift (gimple *stmt, gimple_stmt_iterator *gsi, ...@@ -4948,7 +4948,7 @@ vectorizable_shift (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node) if (slp_node)
ncopies = 1; ncopies = 1;
else else
ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in; ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1); gcc_assert (ncopies >= 1);
...@@ -5379,7 +5379,7 @@ vectorizable_operation (gimple *stmt, gimple_stmt_iterator *gsi, ...@@ -5379,7 +5379,7 @@ vectorizable_operation (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node) if (slp_node)
ncopies = 1; ncopies = 1;
else else
ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in; ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1); gcc_assert (ncopies >= 1);
...@@ -5718,7 +5718,7 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, ...@@ -5718,7 +5718,7 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
if (slp) if (slp)
ncopies = 1; ncopies = 1;
else else
ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits; ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1); gcc_assert (ncopies >= 1);
...@@ -6713,7 +6713,7 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, ...@@ -6713,7 +6713,7 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
if (slp) if (slp)
ncopies = 1; ncopies = 1;
else else
ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits; ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1); gcc_assert (ncopies >= 1);
...@@ -7926,13 +7926,12 @@ vectorizable_condition (gimple *stmt, gimple_stmt_iterator *gsi, ...@@ -7926,13 +7926,12 @@ vectorizable_condition (gimple *stmt, gimple_stmt_iterator *gsi,
return false; return false;
tree vectype = STMT_VINFO_VECTYPE (stmt_info); tree vectype = STMT_VINFO_VECTYPE (stmt_info);
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
tree vectype1 = NULL_TREE, vectype2 = NULL_TREE; tree vectype1 = NULL_TREE, vectype2 = NULL_TREE;
if (slp_node) if (slp_node)
ncopies = 1; ncopies = 1;
else else
ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits; ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1); gcc_assert (ncopies >= 1);
if (reduc_index && ncopies > 1) if (reduc_index && ncopies > 1)
...@@ -8269,7 +8268,7 @@ vectorizable_comparison (gimple *stmt, gimple_stmt_iterator *gsi, ...@@ -8269,7 +8268,7 @@ vectorizable_comparison (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node) if (slp_node)
ncopies = 1; ncopies = 1;
else else
ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits; ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1); gcc_assert (ncopies >= 1);
if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
...@@ -8700,7 +8699,7 @@ vect_analyze_stmt (gimple *stmt, bool *need_to_vectorize, slp_tree node, ...@@ -8700,7 +8699,7 @@ vect_analyze_stmt (gimple *stmt, bool *need_to_vectorize, slp_tree node,
need extra handling, except for vectorizable reductions. */ need extra handling, except for vectorizable reductions. */
if (STMT_VINFO_LIVE_P (stmt_info) if (STMT_VINFO_LIVE_P (stmt_info)
&& STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type) && STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type)
ok = vectorizable_live_operation (stmt, NULL, NULL, -1, NULL); ok = vectorizable_live_operation (stmt, NULL, node, -1, NULL);
if (!ok) if (!ok)
{ {
......
...@@ -1076,6 +1076,20 @@ unlimited_cost_model (loop_p loop) ...@@ -1076,6 +1076,20 @@ unlimited_cost_model (loop_p loop)
return (flag_vect_cost_model == VECT_COST_MODEL_UNLIMITED); return (flag_vect_cost_model == VECT_COST_MODEL_UNLIMITED);
} }
/* Return the number of copies needed for loop vectorization when
a statement operates on vectors of type VECTYPE. This is the
vectorization factor divided by the number of elements in
VECTYPE and is always known at compile time. */
static inline unsigned int
vect_get_num_copies (loop_vec_info loop_vinfo, tree vectype)
{
gcc_checking_assert (LOOP_VINFO_VECT_FACTOR (loop_vinfo)
% TYPE_VECTOR_SUBPARTS (vectype) == 0);
return (LOOP_VINFO_VECT_FACTOR (loop_vinfo)
/ TYPE_VECTOR_SUBPARTS (vectype));
}
/* Source location */ /* Source location */
extern source_location vect_location; extern source_location vect_location;
......
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