From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30433 invoked by alias); 26 Jun 2002 08:36:03 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 30416 invoked by uid 71); 26 Jun 2002 08:36:02 -0000 Date: Wed, 26 Jun 2002 03:06:00 -0000 Message-ID: <20020626083602.30415.qmail@sources.redhat.com> To: nobody@gcc.gnu.org Cc: gcc-prs@gcc.gnu.org, From: Alan Modra Subject: Re: optimization/7120: Run once loop should *always* be unrolled Reply-To: Alan Modra X-SW-Source: 2002-06/txt/msg00628.txt.bz2 List-Id: The following reply was made to PR optimization/7120; it has been noted by GNATS. From: Alan Modra To: davem@gcc.gnu.org, gcc-bugs@gcc.gnu.org, nobody@gcc.gnu.org, rth@twiddle.net, rusty@rustcorp.com.au, gcc-gnats@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: Subject: Re: optimization/7120: Run once loop should *always* be unrolled Date: Wed, 26 Jun 2002 18:02:10 +0930 On Wed, Jun 26, 2002 at 01:17:00PM +0930, Alan Modra wrote: > Bah, that's too simplistic. Patch withdrawn. This one is better. Handles horrible loops like: extern int *arr; int i; i = 0; do { arr[i] = 0; i++; } while (i == 1); I'm also setting loop_info->final_value and loop_info->final_equiv_value as they were reset to zero earlier. bootstrapped and regression tested i686-linux. * unroll.c (loop_iterations): Handle EQ loops. Index: gcc/unroll.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/unroll.c,v retrieving revision 1.168 diff -u -p -r1.168 unroll.c --- gcc/unroll.c 15 Jun 2002 01:10:49 -0000 1.168 +++ gcc/unroll.c 26 Jun 2002 04:58:40 -0000 @@ -3941,12 +3941,6 @@ loop_iterations (loop) } return 0; } - else if (comparison_code == EQ) - { - if (loop_dump_stream) - fprintf (loop_dump_stream, "Loop iterations: EQ comparison loop.\n"); - return 0; - } else if (GET_CODE (final_value) != CONST_INT) { if (loop_dump_stream) @@ -3957,6 +3951,34 @@ loop_iterations (loop) fprintf (loop_dump_stream, ".\n"); } return 0; + } + else if (comparison_code == EQ) + { + if (loop_dump_stream) + fprintf (loop_dump_stream, "Loop iterations: EQ comparison loop.\n"); + + if (((INTVAL (initial_value) + INTVAL (increment)) + & (((unsigned HOST_WIDE_INT) 1 + << (GET_MODE_BITSIZE (GET_MODE (iteration_var)) - 1) + << 1) - 1)) == INTVAL (final_value)) + { + /* The iterator value once through the loop is equal to the + comparision value. Either we have an infinite loop, or + we'll loop twice. */ + if (INTVAL (increment) == 0) + return 0; + loop_info->n_iterations = 2; + } + else + loop_info->n_iterations = 1; + + loop_info->final_value + = plus_constant (loop_info->initial_value, + loop_info->n_iterations * INTVAL (increment)); + loop_info->final_equiv_value + = GEN_INT (INTVAL (initial_value) + + loop_info->n_iterations * INTVAL (increment)); + return loop_info->n_iterations; } /* Final_larger is 1 if final larger, 0 if they are equal, otherwise -1. */ -- Alan Modra IBM OzLabs - Linux Technology Centre