diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-09-14 16:30:36 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-09-14 16:30:36 +0000 |
commit | 4eb17cb6e4ad3f2c838e3875183c802a13cf506f (patch) | |
tree | be4373fc3725870e0d59bf2eddb56c9874962e4d | |
parent | f3e1d2c38677ff8e9ed21ceb9e49e5cbfc30e60c (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/ChangeLog | 22 | ||||
-rw-r--r-- | gcc/tree-vect-data-refs.c | 9 | ||||
-rw-r--r-- | gcc/tree-vect-loop.c | 15 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.c | 29 | ||||
-rw-r--r-- | gcc/tree-vectorizer.h | 14 |
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; |