Commit 72d6aeec by Richard Sandiford Committed by Richard Sandiford

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
parent 756b23a8
2019-11-06 Richard Sandiford <richard.sandiford@arm.com>
* 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.
2019-11-06 Vineet Gupta <vgupta@synopsys.com> 2019-11-06 Vineet Gupta <vgupta@synopsys.com>
* config/arc/arc-c.c (arc_cpu_cpp_builtins) : Add * config/arc/arc-c.c (arc_cpu_cpp_builtins) : Add
...@@ -2382,16 +2382,13 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared) ...@@ -2382,16 +2382,13 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared)
poly_uint64 lowest_th = 0; poly_uint64 lowest_th = 0;
unsigned vectorized_loops = 0; unsigned vectorized_loops = 0;
/* Only vectorize epilogues if PARAM_VECT_EPILOGUES_NOMASK is enabled, this bool vect_epilogues = false;
is not a simd loop and it is the most inner loop. */ opt_result res = opt_result::success ();
bool vect_epilogues unsigned HOST_WIDE_INT simdlen = loop->simdlen;
= !loop->simdlen && loop->inner == NULL
&& PARAM_VALUE (PARAM_VECT_EPILOGUES_NOMASK);
while (1) while (1)
{ {
/* Check the CFG characteristics of the loop (nesting, entry/exit). */ /* Check the CFG characteristics of the loop (nesting, entry/exit). */
opt_loop_vec_info loop_vinfo opt_loop_vec_info loop_vinfo = vect_analyze_loop_form (loop, shared);
= vect_analyze_loop_form (loop, shared);
if (!loop_vinfo) if (!loop_vinfo)
{ {
if (dump_enabled_p ()) if (dump_enabled_p ())
...@@ -2404,43 +2401,39 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared) ...@@ -2404,43 +2401,39 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared)
bool fatal = false; bool fatal = false;
if (vect_epilogues && first_loop_vinfo) if (vect_epilogues)
LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo) = first_loop_vinfo; 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) if (next_size == 0)
autodetected_vector_size = loop_vinfo->vector_size; autodetected_vector_size = loop_vinfo->vector_size;
loop->aux = NULL;
if (res) if (res)
{ {
LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1; LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
vectorized_loops++; vectorized_loops++;
if ((loop->simdlen /* Once we hit the desired simdlen for the first time,
&& maybe_ne (LOOP_VINFO_VECT_FACTOR (loop_vinfo), discard any previous attempts. */
(unsigned HOST_WIDE_INT) loop->simdlen)) if (simdlen
|| vect_epilogues) && known_eq (LOOP_VINFO_VECT_FACTOR (loop_vinfo), simdlen))
{ {
delete first_loop_vinfo;
first_loop_vinfo = opt_loop_vec_info::success (NULL);
LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo) = NULL;
simdlen = 0;
}
if (first_loop_vinfo == NULL) if (first_loop_vinfo == NULL)
{ {
first_loop_vinfo = loop_vinfo; first_loop_vinfo = loop_vinfo;
lowest_th lowest_th = LOOP_VINFO_VERSIONING_THRESHOLD (first_loop_vinfo);
= LOOP_VINFO_VERSIONING_THRESHOLD (first_loop_vinfo);
loop->aux = NULL;
} }
else else if (vect_epilogues)
{
/* 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.safe_push (loop_vinfo);
first_loop_vinfo->epilogue_vinfos.reserve (1); poly_uint64 th = LOOP_VINFO_VERSIONING_THRESHOLD (loop_vinfo);
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) gcc_assert (!LOOP_REQUIRES_VERSIONING (loop_vinfo)
|| maybe_ne (lowest_th, 0U)); || maybe_ne (lowest_th, 0U));
/* Keep track of the known smallest versioning /* Keep track of the known smallest versioning
...@@ -2450,21 +2443,28 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared) ...@@ -2450,21 +2443,28 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared)
} }
else else
delete loop_vinfo; 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 else
{ {
delete first_loop_vinfo;
return loop_vinfo;
}
}
else
delete loop_vinfo; delete loop_vinfo;
if (fatal) if (fatal)
{ {
gcc_checking_assert (first_loop_vinfo == NULL); gcc_checking_assert (first_loop_vinfo == NULL);
return opt_loop_vec_info::propagate_failure (res); break;
}
} }
if (next_size < vector_sizes.length () if (next_size < vector_sizes.length ()
...@@ -2473,7 +2473,20 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared) ...@@ -2473,7 +2473,20 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared)
if (next_size == vector_sizes.length () if (next_size == vector_sizes.length ()
|| known_eq (autodetected_vector_size, 0U)) || known_eq (autodetected_vector_size, 0U))
break;
/* Try the next biggest vector size. */
next_vector_size = vector_sizes[next_size++];
if (dump_enabled_p ())
{ {
dump_printf_loc (MSG_NOTE, vect_location,
"***** Re-trying analysis with "
"vector size ");
dump_dec (MSG_NOTE, next_vector_size);
dump_printf (MSG_NOTE, "\n");
}
}
if (first_loop_vinfo) if (first_loop_vinfo)
{ {
loop->aux = (loop_vec_info) first_loop_vinfo; loop->aux = (loop_vec_info) first_loop_vinfo;
...@@ -2485,24 +2498,10 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared) ...@@ -2485,24 +2498,10 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared)
dump_printf (MSG_NOTE, "\n"); dump_printf (MSG_NOTE, "\n");
} }
LOOP_VINFO_VERSIONING_THRESHOLD (first_loop_vinfo) = lowest_th; LOOP_VINFO_VERSIONING_THRESHOLD (first_loop_vinfo) = lowest_th;
return first_loop_vinfo; return first_loop_vinfo;
} }
else
return opt_loop_vec_info::propagate_failure (res);
}
/* Try the next biggest vector size. */ return opt_loop_vec_info::propagate_failure (res);
next_vector_size = vector_sizes[next_size++];
if (dump_enabled_p ())
{
dump_printf_loc (MSG_NOTE, vect_location,
"***** Re-trying analysis with "
"vector size ");
dump_dec (MSG_NOTE, next_vector_size);
dump_printf (MSG_NOTE, "\n");
}
}
} }
/* Return true if there is an in-order reduction function for CODE, storing /* Return true if there is an in-order reduction function for CODE, storing
......
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