mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-20 17:40:46 +08:00
re PR rtl-optimization/18861 (ICE Segmentation fault in try_crossjump_to_edge at ../../gcc/gcc/cfgcleanup.c:1637 with two switches (table jumps))
PR rtl-optimization/18861 * cfgbuild.c (BLOCK_USED_BY_TABLEJUMP): Define. (FULL_STATE): Define. (mark_tablejump_edge): New function. (purge_dead_tablejump_edges): New function. (find_bb_boundaries): Use it. * gcc.dg/20050105-1.c: New test. From-SVN: r93041
This commit is contained in:
parent
8870e2121d
commit
0210ae141e
gcc
@ -1,5 +1,12 @@
|
||||
2005-01-07 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/18861
|
||||
* cfgbuild.c (BLOCK_USED_BY_TABLEJUMP): Define.
|
||||
(FULL_STATE): Define.
|
||||
(mark_tablejump_edge): New function.
|
||||
(purge_dead_tablejump_edges): New function.
|
||||
(find_bb_boundaries): Use it.
|
||||
|
||||
PR tree-optimization/18828
|
||||
* builtins.c (expand_builtin_next_arg): Remove argument and all
|
||||
the argument checking.
|
||||
|
@ -559,14 +559,73 @@ enum state {BLOCK_NEW = 0, BLOCK_ORIGINAL, BLOCK_TO_SPLIT};
|
||||
#define STATE(BB) (enum state) ((size_t) (BB)->aux)
|
||||
#define SET_STATE(BB, STATE) ((BB)->aux = (void *) (size_t) (STATE))
|
||||
|
||||
/* Used internally by purge_dead_tablejump_edges, ORed into state. */
|
||||
#define BLOCK_USED_BY_TABLEJUMP 32
|
||||
#define FULL_STATE(BB) ((size_t) (BB)->aux)
|
||||
|
||||
static void
|
||||
mark_tablejump_edge (rtx label)
|
||||
{
|
||||
basic_block bb;
|
||||
|
||||
gcc_assert (LABEL_P (label));
|
||||
/* See comment in make_label_edge. */
|
||||
if (INSN_UID (label) == 0)
|
||||
return;
|
||||
bb = BLOCK_FOR_INSN (label);
|
||||
SET_STATE (bb, FULL_STATE (bb) | BLOCK_USED_BY_TABLEJUMP);
|
||||
}
|
||||
|
||||
static void
|
||||
purge_dead_tablejump_edges (basic_block bb, rtx table)
|
||||
{
|
||||
rtx insn = BB_END (bb), tmp;
|
||||
rtvec vec;
|
||||
int j;
|
||||
edge_iterator ei;
|
||||
edge e;
|
||||
|
||||
if (GET_CODE (PATTERN (table)) == ADDR_VEC)
|
||||
vec = XVEC (PATTERN (table), 0);
|
||||
else
|
||||
vec = XVEC (PATTERN (table), 1);
|
||||
|
||||
for (j = GET_NUM_ELEM (vec) - 1; j >= 0; --j)
|
||||
mark_tablejump_edge (XEXP (RTVEC_ELT (vec, j), 0));
|
||||
|
||||
/* Some targets (eg, ARM) emit a conditional jump that also
|
||||
contains the out-of-range target. Scan for these and
|
||||
add an edge if necessary. */
|
||||
if ((tmp = single_set (insn)) != NULL
|
||||
&& SET_DEST (tmp) == pc_rtx
|
||||
&& GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE
|
||||
&& GET_CODE (XEXP (SET_SRC (tmp), 2)) == LABEL_REF)
|
||||
mark_tablejump_edge (XEXP (XEXP (SET_SRC (tmp), 2), 0));
|
||||
|
||||
for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
|
||||
{
|
||||
if (FULL_STATE (e->dest) & BLOCK_USED_BY_TABLEJUMP)
|
||||
SET_STATE (e->dest, FULL_STATE (e->dest)
|
||||
& ~(size_t) BLOCK_USED_BY_TABLEJUMP);
|
||||
else if (!(e->flags & (EDGE_ABNORMAL | EDGE_EH)))
|
||||
{
|
||||
remove_edge (e);
|
||||
continue;
|
||||
}
|
||||
ei_next (&ei);
|
||||
}
|
||||
}
|
||||
|
||||
/* Scan basic block BB for possible BB boundaries inside the block
|
||||
and create new basic blocks in the progress. */
|
||||
|
||||
static void
|
||||
find_bb_boundaries (basic_block bb)
|
||||
{
|
||||
basic_block orig_bb = bb;
|
||||
rtx insn = BB_HEAD (bb);
|
||||
rtx end = BB_END (bb);
|
||||
rtx table;
|
||||
rtx flow_transfer_insn = NULL_RTX;
|
||||
edge fallthru = NULL;
|
||||
|
||||
@ -623,6 +682,11 @@ find_bb_boundaries (basic_block bb)
|
||||
followed by cleanup at fallthru edge, so the outgoing edges may
|
||||
be dead. */
|
||||
purge_dead_edges (bb);
|
||||
|
||||
/* purge_dead_edges doesn't handle tablejump's, but if we have split the
|
||||
basic block, we might need to kill some edges. */
|
||||
if (bb != orig_bb && tablejump_p (BB_END (bb), NULL, &table))
|
||||
purge_dead_tablejump_edges (bb, table);
|
||||
}
|
||||
|
||||
/* Assume that frequency of basic block B is known. Compute frequencies
|
||||
|
@ -1,5 +1,8 @@
|
||||
2005-01-07 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/18861
|
||||
* gcc.dg/20050105-1.c: New test.
|
||||
|
||||
PR tree-optimization/18828
|
||||
* gcc.dg/20050105-2.c: New test.
|
||||
|
||||
|
31
gcc/testsuite/gcc.dg/20050105-1.c
Normal file
31
gcc/testsuite/gcc.dg/20050105-1.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* PR rtl-optimization/18861 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -floop-optimize2" } */
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
int
|
||||
foo (int code)
|
||||
{
|
||||
if (code >= 3)
|
||||
switch (code)
|
||||
{
|
||||
case 3: return 4;
|
||||
case 4: return 3;
|
||||
case 5: return 6;
|
||||
case 6: return 7;
|
||||
case 7: return 8;
|
||||
case 8: return 5;
|
||||
default: abort ();
|
||||
}
|
||||
switch (code)
|
||||
{
|
||||
case 3: return 4;
|
||||
case 4: return 3;
|
||||
case 5: return 6;
|
||||
case 6: return 7;
|
||||
case 7: return 8;
|
||||
case 8: return 5;
|
||||
default: abort ();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user