This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Use tablejump_p in cfgcleanup.c/merge_blocks_move_successor_nojumps()
> > http://gcc.gnu.org/ml/gcc-patches/2003-07/msg00800.html
> > (Fix latent bug in cfgcleanup.c)
>
> Please rewrite this section of code to use tablejump_p.
This patch uses tablejump_p in merge_blocks_move_successor_nojumps.
I have also updated tablejump_p () (mainline version written by me)
to be similar to the 3.3 branch version (written by Richard Henderson).
Bootstrapped/regtested i686.
OK for mainline?
Josef
2003-07-20 Josef Zlomek <zlomekj@suse.cz>
* cfgcleanup.c (merge_blocks_move_successor_nojumps): Use tablejump_p.
* rtlanal.c (tablejump_p): Use next_active_insn for finding the jump
table.
Index: cfgcleanup.c
===================================================================
RCS file: /cvs/gcc-cvs/gcc/gcc/cfgcleanup.c,v
retrieving revision 1.88
diff -c -3 -p -r1.88 cfgcleanup.c
*** cfgcleanup.c 5 Jul 2003 15:17:26 -0000 1.88
--- cfgcleanup.c 19 Jul 2003 16:45:07 -0000
*************** static void
*** 714,738 ****
merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
{
rtx barrier, real_b_end;
real_b_end = b->end;
- barrier = NEXT_INSN (b->end);
! /* Recognize a jump table following block B. */
! if (barrier
! && GET_CODE (barrier) == CODE_LABEL
! && NEXT_INSN (barrier)
! && GET_CODE (NEXT_INSN (barrier)) == JUMP_INSN
! && (GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_VEC
! || GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_DIFF_VEC))
{
! /* Temporarily add the table jump insn to b, so that it will also
! be moved to the correct location. */
! b->end = NEXT_INSN (barrier);
! barrier = NEXT_INSN (b->end);
}
/* There had better have been a barrier there. Delete it. */
if (barrier && GET_CODE (barrier) == BARRIER)
delete_insn (barrier);
--- 714,733 ----
merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
{
rtx barrier, real_b_end;
+ rtx label, table;
real_b_end = b->end;
! /* If there is a jump table following block B temporarily add the jump table
! to block B so that it will also be moved to the correct location. */
! if (tablejump_p (b->end, &label, &table)
! && prev_active_insn (label) == b->end)
{
! b->end = table;
}
/* There had better have been a barrier there. Delete it. */
+ barrier = NEXT_INSN (b->end);
if (barrier && GET_CODE (barrier) == BARRIER)
delete_insn (barrier);
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc-cvs/gcc/gcc/rtlanal.c,v
retrieving revision 1.165
diff -c -3 -p -r1.165 rtlanal.c
*** rtlanal.c 6 Jul 2003 09:56:08 -0000 1.165
--- rtlanal.c 19 Jul 2003 16:29:49 -0000
*************** rtx_referenced_p (rtx x, rtx body)
*** 2795,2820 ****
return for_each_rtx (&body, rtx_referenced_p_1, x);
}
! /* If INSN is a jump to jumptable insn rturn true and store the label (which
! INSN jumps to) to *LABEL and the tablejump insn to *TABLE.
! LABEL and TABLE may be NULL. */
bool
! tablejump_p (rtx insn, rtx *label, rtx *table)
{
! rtx l, t;
! if (onlyjump_p (insn)
! && (l = JUMP_LABEL (insn)) != NULL_RTX
! && (t = NEXT_INSN (l)) != NULL_RTX
! && GET_CODE (t) == JUMP_INSN
! && (GET_CODE (PATTERN (t)) == ADDR_VEC
! || GET_CODE (PATTERN (t)) == ADDR_DIFF_VEC))
{
! if (label)
! *label = l;
! if (table)
! *table = t;
return true;
}
return false;
--- 2795,2819 ----
return for_each_rtx (&body, rtx_referenced_p_1, x);
}
! /* If INSN is a tablejump return true and store the label (before jump table) to
! *LABELP and the jump table to *TABLEP. LABELP and TABLEP may be NULL. */
bool
! tablejump_p (rtx insn, rtx *labelp, rtx *tablep)
{
! rtx label, table;
! if (GET_CODE (insn) == JUMP_INSN
! && (label = JUMP_LABEL (insn)) != NULL_RTX
! && (table = next_active_insn (label)) != NULL_RTX
! && GET_CODE (table) == JUMP_INSN
! && (GET_CODE (PATTERN (table)) == ADDR_VEC
! || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
{
! if (labelp)
! *labelp = label;
! if (tablep)
! *tablep = table;
return true;
}
return false;