This is the mail archive of the gcc-patches@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]

[PATCH] Minor loop unrolling improvement


The following patch fixes PR optimization/6405, a regression from
GCC 2.95 (and I believe 3.0).  This PR was filed to note that a
recent loop unrolling bug-fix resulted in GCC unrolling fewer
loops than it did before.  Amongst those affected was the following
loop from the BENCH++ benchmark suite:

int main()
{
  int i = 1;
  for (;;)
  {
    foo ();
    i++;
    if (i > 25)
      break;
  }
}


Analysis of the problem reveals the cause to be that loop_iterations
now fails to determine the number of times the loop is executed.  This
in turn is caused by a spurious note between the latch condition and
the loop end note.

The current logic is that loop.c and unroll.c expect the conditional
branch to immediately preceed the NOTE_INSN_LOOP_END note, i.e. to be
PREV_INSN(loop->end).  The comment immediately following reads:

/* ??? We should probably try harder to find the jump insn
   at the end of the loop.  */

Trying only slightly harder, replacing PREV_INSN by prev_nonnote_insn,
fixes the problem, and the above loop is once again unrolled with the
options "-O2 -funroll-loops".  This change required a second tweak as
"strength_reduce" also assumed that the conditional branch of an loop
that had been unrolled was immediately prior to the NOTE_INSN_LOOP_END.

I'm also testing a patch to avoid the spurious NOTE, but I'm uncertain
how safe that fix will be.  Whereas this change (1) is completely safe,
(2) fixes the regression and (3) is better in the long-term to handle
any other notes (branch predictions or NOTE_INSN_DELETEDs etc...)


The following patch has been tested by "make bootstrap" and "make -k
check" on i686-pc-linux-gnu, all languages except Ada and treelang,
with no new regressions.

Ok for mainline and to close PR opt/6405?


2002-09-07  Roger Sayle  <roger@eyesopen.com>

	PR optimization/6405
	* unroll.c (loop_iterations): last_loop_insn should be the previous
	non-note instruction before loop->end.
	* loop.c (strength_reduce): The conditional jump is the last
	non-note instruction before loop->end (as above).


Index: unroll.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/unroll.c,v
retrieving revision 1.175
diff -c -3 -p -r1.175 unroll.c
*** unroll.c	21 Aug 2002 04:33:48 -0000	1.175
--- unroll.c	7 Sep 2002 18:05:11 -0000
*************** loop_iterations (loop)
*** 3273,3279 ****
       accidentally get the branch for a contained loop if the branch for this
       loop was deleted.  We can only trust branches immediately before the
       loop_end.  */
!   last_loop_insn = PREV_INSN (loop->end);

    /* ??? We should probably try harder to find the jump insn
       at the end of the loop.  The following code assumes that
--- 3273,3279 ----
       accidentally get the branch for a contained loop if the branch for this
       loop was deleted.  We can only trust branches immediately before the
       loop_end.  */
!   last_loop_insn = prev_nonnote_insn (loop->end);

    /* ??? We should probably try harder to find the jump insn
       at the end of the loop.  The following code assumes that
Index: loop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop.c,v
retrieving revision 1.418
diff -c -3 -p -r1.418 loop.c
*** loop.c	4 Sep 2002 23:38:18 -0000	1.418
--- loop.c	7 Sep 2002 18:05:14 -0000
*************** strength_reduce (loop, flags)
*** 5348,5354 ****
        unsigned HOST_WIDE_INT n
  	= loop_info->n_iterations / loop_info->unroll_number;
        if (n > 1)
! 	predict_insn (PREV_INSN (loop->end), PRED_LOOP_ITERATIONS,
  		      REG_BR_PROB_BASE - REG_BR_PROB_BASE / n);
      }

--- 5348,5354 ----
        unsigned HOST_WIDE_INT n
  	= loop_info->n_iterations / loop_info->unroll_number;
        if (n > 1)
! 	predict_insn (prev_nonnote_insn (loop->end), PRED_LOOP_ITERATIONS,
  		      REG_BR_PROB_BASE - REG_BR_PROB_BASE / n);
      }


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


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