This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Loop optimization bug with Ada front end on PPC (and probably Alpha)
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;
>