diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2019-11-06 12:29:27 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2019-11-06 12:29:27 +0000 |
commit | 72d6aeecd95ec49fff1d258e4631167a03351cbb (patch) | |
tree | 8b8727a7b29d7018382a537635114d75a45e8c4a /gcc/tree-vect-loop.c | |
parent | 756b23a81c539aec9f8108cb8d6a6313aef02a99 (diff) | |
download | gcc-72d6aeecd95ec49fff1d258e4631167a03351cbb.zip gcc-72d6aeecd95ec49fff1d258e4631167a03351cbb.tar.gz gcc-72d6aeecd95ec49fff1d258e4631167a03351cbb.tar.bz2 |
Restructure vect_analyze_loop
Once vect_analyze_loop has found a valid loop_vec_info X, we carry
on searching for alternatives if (1) X doesn't satisfy simdlen or
(2) we want to vectorize the epilogue of X. I have a patch that
optionally adds a third reason: we want to see if there are cheaper
alternatives to X.
This patch restructures vect_analyze_loop so that it's easier
to add more reasons for continuing. There's supposed to be no
behavioural change.
If we wanted to, we could allow vectorisation of epilogues once
loop->simdlen has been reached by changing "loop->simdlen" to
"simdlen" in the new vect_epilogues condition. That should be
a separate change though.
2019-11-06 Richard Sandiford <richard.sandiford@arm.com>
gcc/
* tree-vect-loop.c (vect_analyze_loop): Break out of the main
loop when we've finished, rather than returning directly from
the loop. Use a local variable to track whether we're still
searching for the preferred simdlen. Make vect_epilogues
record whether the next iteration should try to treat the
loop as an epilogue.
From-SVN: r277879
Diffstat (limited to 'gcc/tree-vect-loop.c')
-rw-r--r-- | gcc/tree-vect-loop.c | 137 |
1 files changed, 68 insertions, 69 deletions
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index a63f8d5..f804904 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -2382,16 +2382,13 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared) poly_uint64 lowest_th = 0; unsigned vectorized_loops = 0; - /* Only vectorize epilogues if PARAM_VECT_EPILOGUES_NOMASK is enabled, this - is not a simd loop and it is the most inner loop. */ - bool vect_epilogues - = !loop->simdlen && loop->inner == NULL - && PARAM_VALUE (PARAM_VECT_EPILOGUES_NOMASK); + bool vect_epilogues = false; + opt_result res = opt_result::success (); + unsigned HOST_WIDE_INT simdlen = loop->simdlen; while (1) { /* Check the CFG characteristics of the loop (nesting, entry/exit). */ - opt_loop_vec_info loop_vinfo - = vect_analyze_loop_form (loop, shared); + opt_loop_vec_info loop_vinfo = vect_analyze_loop_form (loop, shared); if (!loop_vinfo) { if (dump_enabled_p ()) @@ -2404,67 +2401,70 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared) bool fatal = false; - if (vect_epilogues && first_loop_vinfo) + if (vect_epilogues) LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo) = first_loop_vinfo; - opt_result res = vect_analyze_loop_2 (loop_vinfo, fatal, &n_stmts); + res = vect_analyze_loop_2 (loop_vinfo, fatal, &n_stmts); if (next_size == 0) autodetected_vector_size = loop_vinfo->vector_size; + loop->aux = NULL; if (res) { LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1; vectorized_loops++; - if ((loop->simdlen - && maybe_ne (LOOP_VINFO_VECT_FACTOR (loop_vinfo), - (unsigned HOST_WIDE_INT) loop->simdlen)) - || vect_epilogues) + /* Once we hit the desired simdlen for the first time, + discard any previous attempts. */ + if (simdlen + && known_eq (LOOP_VINFO_VECT_FACTOR (loop_vinfo), simdlen)) { - if (first_loop_vinfo == NULL) - { - first_loop_vinfo = loop_vinfo; - lowest_th - = LOOP_VINFO_VERSIONING_THRESHOLD (first_loop_vinfo); - loop->aux = NULL; - } - else - { - /* Keep track of vector sizes that we know we can vectorize - the epilogue with. Only vectorize first epilogue. */ - if (vect_epilogues - && first_loop_vinfo->epilogue_vinfos.is_empty ()) - { - loop->aux = NULL; - first_loop_vinfo->epilogue_vinfos.reserve (1); - first_loop_vinfo->epilogue_vinfos.quick_push (loop_vinfo); - LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo) = first_loop_vinfo; - poly_uint64 th - = LOOP_VINFO_VERSIONING_THRESHOLD (loop_vinfo); - gcc_assert (!LOOP_REQUIRES_VERSIONING (loop_vinfo) - || maybe_ne (lowest_th, 0U)); - /* Keep track of the known smallest versioning - threshold. */ - if (ordered_p (lowest_th, th)) - lowest_th = ordered_min (lowest_th, th); - } - else - delete loop_vinfo; - } + delete first_loop_vinfo; + first_loop_vinfo = opt_loop_vec_info::success (NULL); + LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo) = NULL; + simdlen = 0; } - else + + if (first_loop_vinfo == NULL) { - delete first_loop_vinfo; - return loop_vinfo; + first_loop_vinfo = loop_vinfo; + lowest_th = LOOP_VINFO_VERSIONING_THRESHOLD (first_loop_vinfo); + } + else if (vect_epilogues) + { + first_loop_vinfo->epilogue_vinfos.safe_push (loop_vinfo); + poly_uint64 th = LOOP_VINFO_VERSIONING_THRESHOLD (loop_vinfo); + gcc_assert (!LOOP_REQUIRES_VERSIONING (loop_vinfo) + || maybe_ne (lowest_th, 0U)); + /* Keep track of the known smallest versioning + threshold. */ + if (ordered_p (lowest_th, th)) + lowest_th = ordered_min (lowest_th, th); } + else + delete loop_vinfo; + + /* Only vectorize epilogues if PARAM_VECT_EPILOGUES_NOMASK is + enabled, this is not a simd loop and it is the innermost loop. */ + vect_epilogues = (!loop->simdlen + && loop->inner == NULL + && PARAM_VALUE (PARAM_VECT_EPILOGUES_NOMASK) + /* For now only allow one epilogue loop. */ + && first_loop_vinfo->epilogue_vinfos.is_empty ()); + + /* Commit to first_loop_vinfo if we have no reason to try + alternatives. */ + if (!simdlen && !vect_epilogues) + break; } else - delete loop_vinfo; - - if (fatal) { - gcc_checking_assert (first_loop_vinfo == NULL); - return opt_loop_vec_info::propagate_failure (res); + delete loop_vinfo; + if (fatal) + { + gcc_checking_assert (first_loop_vinfo == NULL); + break; + } } if (next_size < vector_sizes.length () @@ -2473,24 +2473,7 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared) if (next_size == vector_sizes.length () || known_eq (autodetected_vector_size, 0U)) - { - if (first_loop_vinfo) - { - 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, first_loop_vinfo->vector_size); - dump_printf (MSG_NOTE, "\n"); - } - LOOP_VINFO_VERSIONING_THRESHOLD (first_loop_vinfo) = lowest_th; - - return first_loop_vinfo; - } - else - return opt_loop_vec_info::propagate_failure (res); - } + break; /* Try the next biggest vector size. */ next_vector_size = vector_sizes[next_size++]; @@ -2503,6 +2486,22 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared) dump_printf (MSG_NOTE, "\n"); } } + + if (first_loop_vinfo) + { + 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, first_loop_vinfo->vector_size); + dump_printf (MSG_NOTE, "\n"); + } + LOOP_VINFO_VERSIONING_THRESHOLD (first_loop_vinfo) = lowest_th; + return first_loop_vinfo; + } + + return opt_loop_vec_info::propagate_failure (res); } /* Return true if there is an in-order reduction function for CODE, storing |