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)
Not all loops have loop->top set in this situation, because that's only
set in bottom entry loops, it seems.
I've made some small changes. Here's just the ones to unroll.c (I
didn't include the move of the macro from loop.c into loop.h).
I'm also thinking that it would be good enough to let the loop run to
loop->cont, and not use loop->top at all. It's bootstrapping right now,
so we'll see if this works. I tried on a small testcase, and it seemed
to work.
-Corey
Index: unroll.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/unroll.c,v
retrieving revision 1.146
diff -u -r1.146 unroll.c
--- unroll.c 2001/11/16 17:08:12 1.146
+++ unroll.c 2001/11/26 16:44:55
@@ -3479,6 +3479,8 @@
int unsigned_p, compare_dir, final_larger;
rtx last_loop_insn;
rtx reg_term;
+ rtx insn;
+ rtx end_loop_scan;
struct iv_class *bl;
loop_info->n_iterations = 0;
@@ -3704,6 +3706,62 @@
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;
+ if (loop->top)
+ end_loop_scan = loop->top;
+ else
+ end_loop_scan = loop->cont;
+
+ for (insn = loop->start; insn != end_loop_scan; 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), insn, loop->end))
+ {
+ 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;