This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Unrolling/peeling of constant rolling loops
Hello,
> I just figured out that for the testcase
>
> void foo(int *bar)
> {
> int i=0;
> for (; i<2; ++i)
> bar[i] = 0;
> }
>
> we do not unroll the loop completely with -O2 (I was aware of that).
> I thought we do so for -fpeel-loops - and in fact we do, but only
> at the RTL level. To achieve the same at the tree level I need
> to specify -funroll-loops, which in turn causes unrolling of
> not constant rolling loops.
>
> Can we somehow teach the tree-optimizers to unroll the loop in the
> testcase without affecting not constant rolling loops and maybe
> even at plain -O2 (and possibly -Os)?
this is definitely possible (and very likely profitable). A patch like
the following would make sense (not tested, perhaps the constants need
to be changed -- at least at -O2 it would be probably good to be a bit
more aggresive).
Also having separate flag to control complete loop unrolling would be
nice.
Zdenek
Index: tree-ssa-loop-ivcanon.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-ivcanon.c,v
retrieving revision 2.5
diff -c -3 -p -r2.5 tree-ssa-loop-ivcanon.c
*** tree-ssa-loop-ivcanon.c 1 Oct 2004 18:26:31 -0000 2.5
--- tree-ssa-loop-ivcanon.c 6 Dec 2004 14:02:12 -0000
*************** try_unroll_loop_completely (struct loops
*** 128,134 ****
edge exit, tree niter,
bool completely_unroll)
{
! unsigned HOST_WIDE_INT n_unroll, ninsns, max_unroll;
tree old_cond, cond, dont_exit, do_exit;
if (loop->inner)
--- 128,134 ----
edge exit, tree niter,
bool completely_unroll)
{
! unsigned HOST_WIDE_INT n_unroll, ninsns, max_unroll, reduced_ninsns;
tree old_cond, cond, dont_exit, do_exit;
if (loop->inner)
*************** try_unroll_loop_completely (struct loops
*** 144,154 ****
if (n_unroll)
{
- if (!completely_unroll)
- return false;
-
ninsns = tree_num_loop_insns (loop);
if (n_unroll * ninsns
> (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS))
return false;
--- 144,163 ----
if (n_unroll)
{
ninsns = tree_num_loop_insns (loop);
+ /* When we unroll the loop, increment of the induction variable and
+ the exit condition can very likely be completely eliminated. */
+ reduced_ninsns = ninsns - 2;
+ if (reduced_ninsns <= 0)
+ reduced_ninsns = 1;
+
+ if (!completely_unroll
+ /* Unless we are instructed to completely unroll the loops,
+ only unroll if it does not increase code size. */
+ && (reduced_ninsns * (n_unroll + 1) <= ninsns))
+ return false;
+
if (n_unroll * ninsns
> (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS))
return false;