This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]