This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Problem: delete_dead_jumptables and constant pool references
- To: gcc at gcc dot gnu dot org
- Subject: Problem: delete_dead_jumptables and constant pool references
- From: Ulrich Weigand <weigand at immd1 dot informatik dot uni-erlangen dot de>
- Date: Mon, 13 Aug 2001 23:40:13 +0200 (MET DST)
- Cc: uweigand at de dot ibm dot com, hpenner at de dot ibm dot com
Hello,
I'm experiencing problems with the s390 port on mainline that
appear to be caused by frontend code.
The symptom is that dead jumptables are sometimes not deleted,
which causes references to labels that have already been deleted
to stay in the code, causing subsequent link failures.
Now, I'm not very familiar with the flow.c code, but it appears
that the routine delete_dead_jumptables () should have deleted
those tables. However, it doesn't on s390, because jump tables
are referenced from the constant pool and hence never have a
LABEL_NUSES of zero. (Even after the insn loading the label
from the pool was deleted, the pool entry itself is never removed
until shortly before outputting the pool.)
However, in the routine propagate_block_delete_insn (), there
is similar code dealing with dead jumptables. There, an explicit
check is made whether the table is referenced only from the
constant pool.
I've simply added an equivalent check to delete_dead_jumptables (),
and now my test case compiles correctly. (See patch below.)
Is this the correct approach to fix the problem?
Bye,
Ulrich
Index: gcc/flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.462
diff -c -p -r1.462 flow.c
*** flow.c 2001/08/10 16:19:07 1.462
--- flow.c 2001/08/13 21:28:05
*************** delete_dead_jumptables ()
*** 4675,4681 ****
{
next = NEXT_INSN (insn);
if (GET_CODE (insn) == CODE_LABEL
! && LABEL_NUSES (insn) == 0
&& GET_CODE (next) == JUMP_INSN
&& (GET_CODE (PATTERN (next)) == ADDR_VEC
|| GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
--- 4675,4681 ----
{
next = NEXT_INSN (insn);
if (GET_CODE (insn) == CODE_LABEL
! && LABEL_NUSES (insn) == LABEL_PRESERVE_P (insn)
&& GET_CODE (next) == JUMP_INSN
&& (GET_CODE (PATTERN (next)) == ADDR_VEC
|| GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
*************** delete_dead_jumptables ()
*** 4683,4689 ****
if (rtl_dump_file)
fprintf (rtl_dump_file, "Dead jumptable %i removed\n", INSN_UID (insn));
flow_delete_insn (NEXT_INSN (insn));
! flow_delete_insn (insn);
next = NEXT_INSN (next);
}
}
--- 4683,4695 ----
if (rtl_dump_file)
fprintf (rtl_dump_file, "Dead jumptable %i removed\n", INSN_UID (insn));
flow_delete_insn (NEXT_INSN (insn));
!
! /* The label may be forced if it has been put in the constant
! pool. If that is the only use we must discard the table
! jump following it, but not the label itself. */
! if (!LABEL_PRESERVE_P (insn))
! flow_delete_insn (insn);
!
next = NEXT_INSN (next);
}
}
--
Dr. Ulrich Weigand
weigand@informatik.uni-erlangen.de