aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2017-09-14 16:30:36 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2017-09-14 16:30:36 +0000
commit4eb17cb6e4ad3f2c838e3875183c802a13cf506f (patch)
treebe4373fc3725870e0d59bf2eddb56c9874962e4d
parentf3e1d2c38677ff8e9ed21ceb9e49e5cbfc30e60c (diff)
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@252764 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/tree-vect-data-refs.c9
-rw-r--r--gcc/tree-vect-loop.c15
-rw-r--r--gcc/tree-vect-stmts.c29
-rw-r--r--gcc/tree-vectorizer.h14
5 files changed, 65 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 12863fa0ed9..8c30dea3a10 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -2,6 +2,28 @@
Alan Hayward <alan.hayward@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
of vect_init_vector.
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 0b3b968c172..a6969791bb2 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -1181,10 +1181,13 @@ vect_get_data_access_cost (struct data_reference *dr,
{
gimple *stmt = DR_STMT (dr);
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);
- int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
- int ncopies = MAX (1, vf / nunits); /* TODO: Handle SLP properly */
+ int ncopies;
+
+ 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))
vect_get_load_cost (dr, ncopies, true, inside_cost, outside_cost,
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 6746696343b..af730139612 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -5683,8 +5683,7 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node)
ncopies = 1;
else
- ncopies = (LOOP_VINFO_VECT_FACTOR (loop_vinfo)
- / TYPE_VECTOR_SUBPARTS (vectype_in));
+ ncopies = vect_get_num_copies (loop_vinfo, vectype_in);
use_operand_p use_p;
gimple *use_stmt;
@@ -5980,8 +5979,7 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node)
ncopies = 1;
else
- ncopies = (LOOP_VINFO_VECT_FACTOR (loop_vinfo)
- / TYPE_VECTOR_SUBPARTS (vectype_in));
+ ncopies = vect_get_num_copies (loop_vinfo, vectype_in);
gcc_assert (ncopies >= 1);
@@ -6550,7 +6548,7 @@ vectorizable_induction (gimple *phi,
if (slp_node)
ncopies = 1;
else
- ncopies = vf / nunits;
+ ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
/* FORNOW. These restrictions should be relaxed. */
@@ -7013,12 +7011,17 @@ vectorizable_live_operation (gimple *stmt,
tree lhs, lhs_type, bitsize, vec_bitsize;
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
- int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
+ int ncopies;
gimple *use_stmt;
auto_vec<tree> vec_oprnds;
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)
return false;
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 0cee0d48792..4244e28110f 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -2038,7 +2038,7 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node != NULL)
return false;
- ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
+ ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
mask = gimple_call_arg (stmt, 2);
@@ -2472,7 +2472,7 @@ vectorizable_bswap (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node)
ncopies = 1;
else
- ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
+ ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
@@ -2805,9 +2805,9 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt,
if (slp_node)
ncopies = 1;
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
- 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
needs to be generated. */
@@ -4204,9 +4204,9 @@ vectorizable_conversion (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node)
ncopies = 1;
else if (modifier == NARROW)
- ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_out;
+ ncopies = vect_get_num_copies (loop_vinfo, vectype_out);
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
needs to be generated. */
@@ -4690,7 +4690,7 @@ vectorizable_assignment (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node)
ncopies = 1;
else
- ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
+ ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
@@ -4948,7 +4948,7 @@ vectorizable_shift (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node)
ncopies = 1;
else
- ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in;
+ ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
@@ -5379,7 +5379,7 @@ vectorizable_operation (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node)
ncopies = 1;
else
- ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in;
+ ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
@@ -5718,7 +5718,7 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
if (slp)
ncopies = 1;
else
- ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
+ ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
@@ -6713,7 +6713,7 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
if (slp)
ncopies = 1;
else
- ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
+ ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
@@ -7926,13 +7926,12 @@ vectorizable_condition (gimple *stmt, gimple_stmt_iterator *gsi,
return false;
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
- int nunits = TYPE_VECTOR_SUBPARTS (vectype);
tree vectype1 = NULL_TREE, vectype2 = NULL_TREE;
if (slp_node)
ncopies = 1;
else
- ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
+ ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
if (reduc_index && ncopies > 1)
@@ -8269,7 +8268,7 @@ vectorizable_comparison (gimple *stmt, gimple_stmt_iterator *gsi,
if (slp_node)
ncopies = 1;
else
- ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
+ ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
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,
need extra handling, except for vectorizable reductions. */
if (STMT_VINFO_LIVE_P (stmt_info)
&& 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)
{
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 7ed00782148..6efcd51c0a1 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -1076,6 +1076,20 @@ unlimited_cost_model (loop_p loop)
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 */
extern source_location vect_location;