egcs CVS 19980618, mips-sgi-irix6.2 bootstrap failure

Jim Wilson wilson@cygnus.com
Fri Jun 19 20:38:00 GMT 1998


There are two bugs here.

Loop unrolling doesn't correctly handle non-jump instructions that reference
a label.  This only happens if you load the address of a label into a pseudo,
which the setjmp EH code does do.  Unroll should be looking for REG_LABEL
notes on insns and handling the labels that they point to.

The second bug is that gcse can create such instructions, but it does not
add REG_LABEL notes to them.  We must have the REG_LABEL notes, because the
immediately following loop pass requires them.  Either we can modify gcse
to add REG_LABEL notes, or we can run jump in between gcse and loop.  I
wrote a patch to do the former.

Fri Jun 19 16:41:26 1998  Jim Wilson  <wilson@cygnus.com>

	* gcse.c (add_label_notes): New function.
	(pre_insert_insn): Call it.
	* unroll.c (unroll_loop): Look for insns with a REG_LABEL note, and
	pass the label to set_label_in_map.
	
Index: gcse.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/gcse.c,v
retrieving revision 1.5
diff -p -r1.5 gcse.c
*** gcse.c	1998/06/08 18:30:17	1.5
--- gcse.c	1998/06/19 23:41:16
*************** static void pre_insert_copies         PR
*** 641,646 ****
--- 641,648 ----
  static int pre_delete                 PROTO ((void));
  static int pre_gcse                   PROTO ((void));
  static int one_pre_gcse_pass          PROTO ((rtx, int));
+ 
+ static void add_label_notes	      PROTO ((rtx, rtx));
  
  /* Entry point for global common subexpression elimination.
     F is the first instruction in the function.  */
*************** pre_insert_insn (expr, bb)
*** 4354,4359 ****
--- 4356,4362 ----
  #endif
        /* FIXME: What if something in cc0/jump uses value set in new insn?  */
        new_insn = emit_insn_before (pat, insn);
+       add_label_notes (SET_SRC (pat), new_insn);
        if (BLOCK_HEAD (bb) == insn)
  	BLOCK_HEAD (bb) = new_insn;
        /* Keep block number table up to date.  */
*************** pre_insert_insn (expr, bb)
*** 4364,4369 ****
--- 4367,4373 ----
    else
      {
        new_insn = emit_insn_after (pat, insn);
+       add_label_notes (SET_SRC (pat), new_insn);
        BLOCK_END (bb) = new_insn;
        /* Keep block number table up to date.  */
        set_block_num (new_insn, bb);
*************** one_pre_gcse_pass (f, pass)
*** 4694,4697 ****
--- 4698,4748 ----
      }
  
    return changed;
+ }
+ 
+ /* If X contains any LABEL_REF's, add REG_LABEL notes for them to INSN.
+    We have to add REG_LABEL notes, because the following loop optimization
+    pass requires them.  */
+ 
+ /* ??? This is very similar to the loop.c add_label_notes function.  We
+    could probably share code here.  */
+ 
+ /* ??? If there was a jump optimization pass after gcse and before loop,
+    then we would not need to do this here, because jump would add the
+    necessary REG_LABEL notes.  */
+ 
+ static void
+ add_label_notes (x, insn)
+      rtx x;
+      rtx insn;
+ {
+   enum rtx_code code = GET_CODE (x);
+   int i, j;
+   char *fmt;
+ 
+   if (code == LABEL_REF && !LABEL_REF_NONLOCAL_P (x))
+     {
+       rtx next = next_real_insn (XEXP (x, 0));
+ 
+       /* Don't record labels that refer to dispatch tables.
+ 	 This is not necessary, since the tablejump references the same label.
+ 	 And if we did record them, flow.c would make worse code.  */
+       if (next == 0
+ 	  || ! (GET_CODE (next) == JUMP_INSN
+ 		&& (GET_CODE (PATTERN (next)) == ADDR_VEC
+ 		    || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC)))
+ 	REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL, XEXP (x, 0),
+ 					      REG_NOTES (insn));
+       return;
+     }
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     {
+       if (fmt[i] == 'e')
+ 	add_label_notes (XEXP (x, i), insn);
+       else if (fmt[i] == 'E')
+ 	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ 	  add_label_notes (XVECEXP (x, i, j), insn);
+     }
  }
Index: unroll.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/unroll.c,v
retrieving revision 1.24
diff -p -r1.24 unroll.c
*** unroll.c	1998/06/10 09:49:30	1.24
--- unroll.c	1998/06/19 23:41:16
*************** unroll_loop (loop_end, insn_count, loop_
*** 687,692 ****
--- 687,694 ----
  
    for (insn = copy_start; insn != loop_end; insn = NEXT_INSN (insn))
      {
+       rtx note;
+ 
        if (GET_CODE (insn) == CODE_LABEL)
  	local_label[CODE_LABEL_NUMBER (insn)] = 1;
        else if (GET_CODE (insn) == JUMP_INSN)
*************** unroll_loop (loop_end, insn_count, loop_
*** 712,717 ****
--- 714,722 ----
  		}
  	    }
  	}
+       else if (note = find_reg_note (insn, REG_LABEL, NULL_RTX))
+ 	set_label_in_map (map, CODE_LABEL_NUMBER (XEXP (note, 0)),
+ 			  XEXP (note, 0));
      }
  
    /* Allocate space for the insn map.  */



More information about the Gcc-bugs mailing list