aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-loop.c
diff options
context:
space:
mode:
authorRobin Dapp <rdapp@linux.ibm.com>2022-01-13 09:51:07 +0100
committerRobin Dapp <rdapp@linux.ibm.com>2022-01-13 20:05:18 +0100
commitb0e5163960eceab701a1a25dfa049e394fe5b3de (patch)
tree6f06da924ca25a3ea73e937f55eda28cbcdd51f7 /gcc/tree-vect-loop.c
parent69561fc781aca3dea3aa4d5d562ef5a502965924 (diff)
downloadgcc-b0e5163960eceab701a1a25dfa049e394fe5b3de.zip
gcc-b0e5163960eceab701a1a25dfa049e394fe5b3de.tar.gz
gcc-b0e5163960eceab701a1a25dfa049e394fe5b3de.tar.bz2
vect: Add bias parameter for partial vectorization
This introduces a bias parameter for the len_load/len_store ifns as well as optabs that is meant to distinguish between Power and s390 variants. PowerPC's instructions require a bias of 0, while in s390's case vll/vstl do not support lengths of zero bytes and a bias of -1 must be used. gcc/ChangeLog: * internal-fn.c (expand_partial_load_optab_fn): Add bias. (expand_partial_store_optab_fn): Likewise. (internal_len_load_store_bias): New function. * internal-fn.h (VECT_PARTIAL_BIAS_UNSUPPORTED): New define. (internal_len_load_store_bias): New function. * tree-vect-loop-manip.c (vect_set_loop_controls_directly): Set bias. (vect_set_loop_condition_partial_vectors): Add header_seq parameter. * tree-vect-loop.c (vect_verify_loop_lens): Verify bias. (vect_estimate_min_profitable_iters): Account for bias. (vect_get_loop_len): Add bias-adjusted length. * tree-vect-stmts.c (vectorizable_store): Use. (vectorizable_load): Use. * tree-vectorizer.h (struct rgroup_controls): Add bias-adjusted length. (LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS): New macro. * config/rs6000/vsx.md: Use const0 bias predicate. * doc/md.texi: Document bias value.
Diffstat (limited to 'gcc/tree-vect-loop.c')
-rw-r--r--gcc/tree-vect-loop.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index ba67de4..8748b1a 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -1165,6 +1165,31 @@ vect_verify_loop_lens (loop_vec_info loop_vinfo)
if (LOOP_VINFO_LENS (loop_vinfo).is_empty ())
return false;
+ machine_mode len_load_mode = get_len_load_store_mode
+ (loop_vinfo->vector_mode, true).require ();
+ machine_mode len_store_mode = get_len_load_store_mode
+ (loop_vinfo->vector_mode, false).require ();
+
+ signed char partial_load_bias = internal_len_load_store_bias
+ (IFN_LEN_LOAD, len_load_mode);
+
+ signed char partial_store_bias = internal_len_load_store_bias
+ (IFN_LEN_STORE, len_store_mode);
+
+ gcc_assert (partial_load_bias == partial_store_bias);
+
+ if (partial_load_bias == VECT_PARTIAL_BIAS_UNSUPPORTED)
+ return false;
+
+ /* If the backend requires a bias of -1 for LEN_LOAD, we must not emit
+ len_loads with a length of zero. In order to avoid that we prohibit
+ more than one loop length here. */
+ if (partial_load_bias == -1
+ && LOOP_VINFO_LENS (loop_vinfo).length () > 1)
+ return false;
+
+ LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo) = partial_load_bias;
+
unsigned int max_nitems_per_iter = 1;
unsigned int i;
rgroup_controls *rgl;
@@ -4076,6 +4101,8 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo,
here. */
bool niters_known_p = LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo);
+ signed char partial_load_store_bias
+ = LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo);
bool need_iterate_p
= (!LOOP_VINFO_EPILOGUE_P (loop_vinfo)
&& !vect_known_niters_smaller_than_vf (loop_vinfo));
@@ -4108,6 +4135,11 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo,
for each since start index is zero. */
prologue_stmts += num_vectors;
+ /* If we have a non-zero partial load bias, we need one PLUS
+ to adjust the load length. */
+ if (partial_load_store_bias != 0)
+ body_stmts += 1;
+
/* Each may need two MINs and one MINUS to update lengths in body
for next iteration. */
if (need_iterate_p)
@@ -9158,6 +9190,8 @@ vect_get_loop_len (loop_vec_info loop_vinfo, vec_loop_lens *lens,
unsigned int nvectors, unsigned int index)
{
rgroup_controls *rgl = &(*lens)[nvectors - 1];
+ bool use_bias_adjusted_len =
+ LOOP_VINFO_PARTIAL_LOAD_STORE_BIAS (loop_vinfo) != 0;
/* Populate the rgroup's len array, if this is the first time we've
used it. */
@@ -9168,15 +9202,28 @@ vect_get_loop_len (loop_vec_info loop_vinfo, vec_loop_lens *lens,
{
tree len_type = LOOP_VINFO_RGROUP_COMPARE_TYPE (loop_vinfo);
gcc_assert (len_type != NULL_TREE);
+
tree len = make_temp_ssa_name (len_type, NULL, "loop_len");
/* Provide a dummy definition until the real one is available. */
SSA_NAME_DEF_STMT (len) = gimple_build_nop ();
rgl->controls[i] = len;
+
+ if (use_bias_adjusted_len)
+ {
+ gcc_assert (i == 0);
+ tree adjusted_len =
+ make_temp_ssa_name (len_type, NULL, "adjusted_loop_len");
+ SSA_NAME_DEF_STMT (adjusted_len) = gimple_build_nop ();
+ rgl->bias_adjusted_ctrl = adjusted_len;
+ }
}
}
- return rgl->controls[index];
+ if (use_bias_adjusted_len)
+ return rgl->bias_adjusted_ctrl;
+ else
+ return rgl->controls[index];
}
/* Scale profiling counters by estimation for LOOP which is vectorized