This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
2.95: Fixes for problems caused by sjlj eh patches
- To: <gcc-patches at gcc dot gnu dot org>
- Subject: 2.95: Fixes for problems caused by sjlj eh patches
- From: Bernd Schmidt <bernds at redhat dot com>
- Date: Wed, 28 Mar 2001 09:54:44 +0100 (BST)
The sjlj eh patches broke HPUX support with the native assembler. The problem
is that references to code labels are put into the constant pool, but the code
labels can be optimized away, leaving undefined references. To fix this, this
patch sets LABEL_PRESERVE_P when we put a label into the constant pool.
This, in turn, breaks AIX, where we have to put the labels at the head of
case vectors into the constant pool. Lots of code suddenly fails to remove
unused case vectors. This patch fixes these, and also moves
delete_barrier_successors, so that the JUMP_LABEL and LABEL_NUSES fields are
set up properly for the calls to delete_insn.
Verified with a bootstrap and testsuite run by David Edelsohn (thanks!)
Bernd
* flow.c (propagate_block): When trying to delete a case vector, cope
if its label has LABEL_PRESERVE_P set.
* jump.c (jump_optimize_1): Move call to delete_barrier_successors to
a point where JUMP_LABELS and LABEL_NUSES are set up properly.
(delete_barrier_successors): If deleting a table jump, delete the case
vector as well.
* varasm.c (force_const_mem): If we have a label, set LABEL_PRESERVE_P
so it won't get deleted.
Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.120.4.7
diff -u -p -r1.120.4.7 flow.c
--- flow.c 2001/01/25 14:03:08 1.120.4.7
+++ flow.c 2001/03/27 13:45:32
@@ -2744,15 +2744,23 @@ propagate_block (old, first, last, final
{
if (REG_NOTE_KIND (inote) == REG_LABEL)
{
+ int n_forced;
rtx label = XEXP (inote, 0);
rtx next;
LABEL_NUSES (label)--;
+ /* The label may be forced if it has been put in the
+ constant pool. We can't delete it in this case, but
+ we still must discard a jump table following it. */
+ n_forced = 0;
+ if (LABEL_PRESERVE_P (label))
+ n_forced++;
+
/* If this label was attached to an ADDR_VEC, it's
safe to delete the ADDR_VEC. In fact, it's pretty much
mandatory to delete it, because the ADDR_VEC may
be referencing labels that no longer exist. */
- if (LABEL_NUSES (label) == 0
+ if (LABEL_NUSES (label) == n_forced
&& (next = next_nonnote_insn (label)) != NULL
&& GET_CODE (next) == JUMP_INSN
&& (GET_CODE (PATTERN (next)) == ADDR_VEC
Index: jump.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/jump.c,v
retrieving revision 1.59.4.5
diff -u -p -r1.59.4.5 jump.c
--- jump.c 1999/10/21 06:24:03 1.59.4.5
+++ jump.c 2001/03/27 13:45:34
@@ -200,8 +200,6 @@ jump_optimize_1 (f, cross_jump, noop_mov
if (flag_exceptions && cross_jump)
init_insn_eh_region (f, max_uid);
- delete_barrier_successors (f);
-
/* Leave some extra room for labels and duplicate exit test insns
we make. */
max_jump_chain = max_uid * 14 / 10;
@@ -224,6 +222,8 @@ jump_optimize_1 (f, cross_jump, noop_mov
for (insn = exception_handler_labels; insn; insn = XEXP (insn, 1))
LABEL_NUSES (XEXP (insn, 0))++;
+ delete_barrier_successors (f);
+
/* Quit now if we just wanted to rebuild the JUMP_LABEL and REG_LABEL
notes and recompute LABEL_NUSES. */
if (mark_labels_only)
@@ -2139,7 +2139,23 @@ delete_barrier_successors (f)
insn = NEXT_INSN (insn);
while (insn != 0 && GET_CODE (insn) != CODE_LABEL)
{
- if (GET_CODE (insn) == NOTE
+ if (GET_CODE (insn) == JUMP_INSN)
+ {
+ /* Detect when we're deleting a tablejump; get rid of
+ the jump table as well. */
+ rtx next1 = next_nonnote_insn (insn);
+ rtx next2 = next1 ? next_nonnote_insn (next1) : 0;
+ if (next2 && GET_CODE (next1) == CODE_LABEL
+ && (GET_CODE (PATTERN (next2)) == ADDR_VEC
+ || GET_CODE (PATTERN (next2)) == ADDR_DIFF_VEC))
+ {
+ delete_insn (insn);
+ insn = next2;
+ }
+ else
+ insn = delete_insn (insn);
+ }
+ else if (GET_CODE (insn) == NOTE
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)
insn = NEXT_INSN (insn);
else
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.59.4.7
diff -u -p -r1.59.4.7 varasm.c
--- varasm.c 2001/02/19 14:02:02 1.59.4.7
+++ varasm.c 2001/03/27 13:45:36
@@ -3495,6 +3495,9 @@ force_const_mem (mode, x)
pop_obstacks ();
}
+ if (GET_CODE (x) == LABEL_REF)
+ LABEL_PRESERVE_P (XEXP (x, 0)) = 1;
+
/* Allocate a pool constant descriptor, fill it in, and chain it in. */
pool = (struct pool_constant *) savealloc (sizeof (struct pool_constant));