From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4242 invoked by alias); 26 Nov 2001 04:27:22 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 4220 invoked from network); 26 Nov 2001 04:27:20 -0000 Received: from unknown (HELO wf-rch.cirr.com) (24.7.109.109) by sourceware.cygnus.com with SMTP; 26 Nov 2001 04:27:20 -0000 Received: from acm.org (laptop [10.0.0.3]) by wf-rch.cirr.com (8.11.2/8.11.2/SuSE Linux 8.11.1-0.5) with ESMTP id fAQ4RGl08997; Sun, 25 Nov 2001 22:27:16 -0600 Message-ID: <3C01C4F3.2020403@acm.org> Date: Fri, 16 Nov 2001 03:42:00 -0000 From: Corey Minyard User-Agent: Mozilla/5.0 (X11; U; Linux ppc; en-US; rv:0.9.5+) Gecko/20011012 X-Accept-Language: en-us MIME-Version: 1.0 To: Richard Henderson CC: gcc@gcc.gnu.org Subject: Re: Loop optimization bug with Ada front end on PPC (and probably Alpha) References: <3BFCA770.5070304@acm.org> <20011124124100.A2485@redhat.com> <3C0179C5.2090002@acm.org> <20011125175500.A11474@redhat.com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-SW-Source: 2001-11/txt/msg00719.txt.bz2 That patch looks a lot better than mine :-). However, I'm getting a segv compiling unwind-dw2-fde.c. I put a print in (I can't use gdb 5.0 with the output of gcc 3.0 on Linux PowerPC), and it's dying in the line: && INSN_IN_RANGE_P (JUMP_LABEL (insn), loop->top, loop->cont) It looks like loop->top is alway NULL. I'm working with a slightly old CVS, maybe I should update, or is this a real problem? -Corey Richard Henderson wrote: >The problem is not limited to doloop -- the unroller ought >to hit this problem as well. I'm testing the following. > > > >r~ > > > >Index: loop.c >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/loop.c,v >retrieving revision 1.369 >diff -c -p -d -r1.369 loop.c >*** loop.c 2001/11/15 23:44:56 1.369 >--- loop.c 2001/11/26 01:52:34 >*************** typedef struct loop_replace_args >*** 282,293 **** > rtx insn; > } loop_replace_args; > >- /* Nonzero iff INSN is between START and END, inclusive. */ >- #define INSN_IN_RANGE_P(INSN, START, END) \ >- (INSN_UID (INSN) < max_uid_for_loop \ >- && INSN_LUID (INSN) >= INSN_LUID (START) \ >- && INSN_LUID (INSN) <= INSN_LUID (END)) >- > /* Indirect_jump_in_function is computed once per function. */ > static int indirect_jump_in_function; > static int indirect_jump_in_function_p PARAMS ((rtx)); >--- 282,287 ---- >Index: loop.h >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/loop.h,v >retrieving revision 1.56 >diff -c -p -d -r1.56 loop.h >*** loop.h 2001/10/29 22:13:40 1.56 >--- loop.h 2001/11/26 01:52:34 >*************** Software Foundation, 59 Temple Place - S >*** 50,55 **** >--- 50,60 ---- > #define REGNO_FIRST_LUID(REGNO) uid_luid[REGNO_FIRST_UID (REGNO)] > #define REGNO_LAST_LUID(REGNO) uid_luid[REGNO_LAST_UID (REGNO)] > >+ /* Nonzero iff INSN is between START and END, inclusive. */ >+ #define INSN_IN_RANGE_P(INSN, START, END) \ >+ (INSN_UID (INSN) < max_uid_for_loop \ >+ && INSN_LUID (INSN) >= INSN_LUID (START) \ >+ && INSN_LUID (INSN) <= INSN_LUID (END)) > > /* A "basic induction variable" or biv is a pseudo reg that is set > (within this loop) only by incrementing or decrementing it. */ >Index: unroll.c >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/unroll.c,v >retrieving revision 1.147 >diff -c -p -d -r1.147 unroll.c >*** unroll.c 2001/11/21 00:50:56 1.147 >--- unroll.c 2001/11/26 01:52:34 >*************** loop_iterations (loop) >*** 3480,3485 **** >--- 3480,3486 ---- > int unsigned_p, compare_dir, final_larger; > rtx last_loop_insn; > rtx reg_term; >+ rtx insn; > struct iv_class *bl; > > loop_info->n_iterations = 0; >*************** loop_iterations (loop) >*** 3705,3710 **** >--- 3706,3762 ---- > > if (initial_value == 0) > return 0; >+ >+ /* Some code transformations can result in code akin to >+ >+ LOOP_BEG >+ goto start; >+ top: >+ i++; >+ start: >+ ... >+ LOOP_CONT >+ if (i < n) goto top; >+ LOOP_END >+ >+ In this situation, we skip the increment the first time through >+ the loop, which results in an incorrect estimate of the number >+ of iterations. As we did for GIVs above, adjust the initial value >+ to compensate. */ >+ >+ off_by_one = 0; >+ for (insn = loop->start; insn != loop->top; insn = NEXT_INSN (insn)) >+ if (GET_CODE (insn) == JUMP_INSN) >+ { >+ if (any_uncondjump_p (insn) >+ && JUMP_LABEL (insn) >+ && INSN_IN_RANGE_P (JUMP_LABEL (insn), loop->top, loop->cont)) >+ { >+ if (reg_set_between_p (bl->biv->src_reg, insn, JUMP_LABEL (insn))) >+ off_by_one = 1; >+ break; >+ } >+ /* No idea what's going on. */ >+ if (loop_dump_stream) >+ fprintf (loop_dump_stream, >+ "Loop iterations: Confused by jump before loop top.\n"); >+ return 0; >+ } >+ >+ if (off_by_one) >+ { >+ if (loop_dump_stream) >+ fprintf (loop_dump_stream, >+ "Loop iterations: Basic induction var skips initial incr.\n"); >+ if (GET_CODE (increment) != CONST_INT) >+ { >+ if (loop_dump_stream) >+ fprintf (loop_dump_stream, >+ "Loop iterations: Can't adjust with non-constant incr.\n"); >+ return 0; >+ } >+ initial_value = plus_constant (initial_value, -INTVAL (increment)); >+ } > > unsigned_p = 0; > off_by_one = 0; > From mboxrd@z Thu Jan 1 00:00:00 1970 From: Corey Minyard To: Richard Henderson Cc: gcc@gcc.gnu.org Subject: Re: Loop optimization bug with Ada front end on PPC (and probably Alpha) Date: Sun, 25 Nov 2001 20:27:00 -0000 Message-ID: <3C01C4F3.2020403@acm.org> References: <3BFCA770.5070304@acm.org> <20011124124100.A2485@redhat.com> <3C0179C5.2090002@acm.org> <20011125175500.A11474@redhat.com> X-SW-Source: 2001-11/msg01223.html Message-ID: <20011125202700.jamJQYhOgOxswuevWTkbnP9TVaCDi13BP173H702Jbw@z> That patch looks a lot better than mine :-). However, I'm getting a segv compiling unwind-dw2-fde.c. I put a print in (I can't use gdb 5.0 with the output of gcc 3.0 on Linux PowerPC), and it's dying in the line: && INSN_IN_RANGE_P (JUMP_LABEL (insn), loop->top, loop->cont) It looks like loop->top is alway NULL. I'm working with a slightly old CVS, maybe I should update, or is this a real problem? -Corey Richard Henderson wrote: >The problem is not limited to doloop -- the unroller ought >to hit this problem as well. I'm testing the following. > > > >r~ > > > >Index: loop.c >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/loop.c,v >retrieving revision 1.369 >diff -c -p -d -r1.369 loop.c >*** loop.c 2001/11/15 23:44:56 1.369 >--- loop.c 2001/11/26 01:52:34 >*************** typedef struct loop_replace_args >*** 282,293 **** > rtx insn; > } loop_replace_args; > >- /* Nonzero iff INSN is between START and END, inclusive. */ >- #define INSN_IN_RANGE_P(INSN, START, END) \ >- (INSN_UID (INSN) < max_uid_for_loop \ >- && INSN_LUID (INSN) >= INSN_LUID (START) \ >- && INSN_LUID (INSN) <= INSN_LUID (END)) >- > /* Indirect_jump_in_function is computed once per function. */ > static int indirect_jump_in_function; > static int indirect_jump_in_function_p PARAMS ((rtx)); >--- 282,287 ---- >Index: loop.h >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/loop.h,v >retrieving revision 1.56 >diff -c -p -d -r1.56 loop.h >*** loop.h 2001/10/29 22:13:40 1.56 >--- loop.h 2001/11/26 01:52:34 >*************** Software Foundation, 59 Temple Place - S >*** 50,55 **** >--- 50,60 ---- > #define REGNO_FIRST_LUID(REGNO) uid_luid[REGNO_FIRST_UID (REGNO)] > #define REGNO_LAST_LUID(REGNO) uid_luid[REGNO_LAST_UID (REGNO)] > >+ /* Nonzero iff INSN is between START and END, inclusive. */ >+ #define INSN_IN_RANGE_P(INSN, START, END) \ >+ (INSN_UID (INSN) < max_uid_for_loop \ >+ && INSN_LUID (INSN) >= INSN_LUID (START) \ >+ && INSN_LUID (INSN) <= INSN_LUID (END)) > > /* A "basic induction variable" or biv is a pseudo reg that is set > (within this loop) only by incrementing or decrementing it. */ >Index: unroll.c >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/unroll.c,v >retrieving revision 1.147 >diff -c -p -d -r1.147 unroll.c >*** unroll.c 2001/11/21 00:50:56 1.147 >--- unroll.c 2001/11/26 01:52:34 >*************** loop_iterations (loop) >*** 3480,3485 **** >--- 3480,3486 ---- > int unsigned_p, compare_dir, final_larger; > rtx last_loop_insn; > rtx reg_term; >+ rtx insn; > struct iv_class *bl; > > loop_info->n_iterations = 0; >*************** loop_iterations (loop) >*** 3705,3710 **** >--- 3706,3762 ---- > > if (initial_value == 0) > return 0; >+ >+ /* Some code transformations can result in code akin to >+ >+ LOOP_BEG >+ goto start; >+ top: >+ i++; >+ start: >+ ... >+ LOOP_CONT >+ if (i < n) goto top; >+ LOOP_END >+ >+ In this situation, we skip the increment the first time through >+ the loop, which results in an incorrect estimate of the number >+ of iterations. As we did for GIVs above, adjust the initial value >+ to compensate. */ >+ >+ off_by_one = 0; >+ for (insn = loop->start; insn != loop->top; insn = NEXT_INSN (insn)) >+ if (GET_CODE (insn) == JUMP_INSN) >+ { >+ if (any_uncondjump_p (insn) >+ && JUMP_LABEL (insn) >+ && INSN_IN_RANGE_P (JUMP_LABEL (insn), loop->top, loop->cont)) >+ { >+ if (reg_set_between_p (bl->biv->src_reg, insn, JUMP_LABEL (insn))) >+ off_by_one = 1; >+ break; >+ } >+ /* No idea what's going on. */ >+ if (loop_dump_stream) >+ fprintf (loop_dump_stream, >+ "Loop iterations: Confused by jump before loop top.\n"); >+ return 0; >+ } >+ >+ if (off_by_one) >+ { >+ if (loop_dump_stream) >+ fprintf (loop_dump_stream, >+ "Loop iterations: Basic induction var skips initial incr.\n"); >+ if (GET_CODE (increment) != CONST_INT) >+ { >+ if (loop_dump_stream) >+ fprintf (loop_dump_stream, >+ "Loop iterations: Can't adjust with non-constant incr.\n"); >+ return 0; >+ } >+ initial_value = plus_constant (initial_value, -INTVAL (increment)); >+ } > > unsigned_p = 0; > off_by_one = 0; >