Stabilization on the ARM: an unrolling bug

Michael Hayes m.hayes@elec.canterbury.ac.nz
Sat Jan 9 15:18:00 GMT 1999


Richard Earnshaw writes:
 > Unfortunately, the stage1 compiler now aborts while compiling 
 > _bb_exit_func in libgcc2.c (the last_loop_insn is a line note if compiled 
 > with -O2 -g0, and a LOOP_END note if just compiled with -O2).

This patch supercedes the previous patch I sent.  It should fix the
unrolling problems if the loop has multiple back edges.

Michael.

Sun Jan  10 12:16:42 1999  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>

	* unroll.c (loop_iterations): Return 0 if the last loop insn
	is not a jump insn or if the loop has multiple back edges.

Index: unroll.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/unroll.c,v
retrieving revision 1.41
diff -c -3 -p -r1.41 unroll.c
*** unroll.c	1999/01/06 19:45:50	1.41
--- unroll.c	1999/01/09 22:52:15
*************** loop_iterations (loop_start, loop_end, l
*** 3477,3498 ****
    loop_info->unroll_number = 1;
    loop_info->vtop = 0;
  
-   /* First find the iteration variable.  If the last insn is a conditional
-      branch, and the insn before tests a register value, make that the
-      iteration variable.  */
-   
    /* We used to use prev_nonnote_insn here, but that fails because it might
       accidentally get the branch for a contained loop if the branch for this
       loop was deleted.  We can only trust branches immediately before the
       loop_end.  */
    last_loop_insn = PREV_INSN (loop_end);
  
    comparison = get_condition_for_loop (last_loop_insn);
    if (comparison == 0)
      {
        if (loop_dump_stream)
  	fprintf (loop_dump_stream,
! 		 "Loop iterations: No final conditional branch found.\n");
        return 0;
      }
  
--- 3477,3519 ----
    loop_info->unroll_number = 1;
    loop_info->vtop = 0;
  
    /* We used to use prev_nonnote_insn here, but that fails because it might
       accidentally get the branch for a contained loop if the branch for this
       loop was deleted.  We can only trust branches immediately before the
       loop_end.  */
    last_loop_insn = PREV_INSN (loop_end);
  
+   /* ??? We should probably try harder to find the jump insn
+      at the end of the loop.  The following code assumes that 
+      the last loop insn is a jump to the top of the loop.  */
+   if (GET_CODE (last_loop_insn) != JUMP_INSN)
+     {
+       if (loop_dump_stream)
+ 	fprintf (loop_dump_stream,
+ 		 "Loop iterations: No final conditional branch found.\n");
+       return 0;
+     }
+ 
+   /* If there is a more than a single jump to the top of the loop
+      we cannot (easily) determine the iteration count.  */
+   if (LABEL_NUSES (JUMP_LABEL (last_loop_insn)) > 1)
+     {
+       if (loop_dump_stream)
+ 	fprintf (loop_dump_stream,
+ 		 "Loop iterations: Loop has multiple back edges.\n");
+       return 0;
+     }
+ 
+   /* Find the iteration variable.  If the last insn is a conditional
+      branch, and the insn before tests a register value, make that the
+      iteration variable.  */
+   
    comparison = get_condition_for_loop (last_loop_insn);
    if (comparison == 0)
      {
        if (loop_dump_stream)
  	fprintf (loop_dump_stream,
! 		 "Loop iterations: No final comparison found.\n");
        return 0;
      }
  



More information about the Gcc-patches mailing list