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

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;

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