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