Commit 0210ae14 by Jakub Jelinek Committed by Jakub Jelinek

re PR rtl-optimization/18861 (ICE Segmentation fault in try_crossjump_to_edge at…

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
parent 8870e212
2005-01-07 Jakub Jelinek <jakub@redhat.com> 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 PR tree-optimization/18828
* builtins.c (expand_builtin_next_arg): Remove argument and all * builtins.c (expand_builtin_next_arg): Remove argument and all
the argument checking. the argument checking.
......
...@@ -559,14 +559,73 @@ enum state {BLOCK_NEW = 0, BLOCK_ORIGINAL, BLOCK_TO_SPLIT}; ...@@ -559,14 +559,73 @@ enum state {BLOCK_NEW = 0, BLOCK_ORIGINAL, BLOCK_TO_SPLIT};
#define STATE(BB) (enum state) ((size_t) (BB)->aux) #define STATE(BB) (enum state) ((size_t) (BB)->aux)
#define SET_STATE(BB, STATE) ((BB)->aux = (void *) (size_t) (STATE)) #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 /* Scan basic block BB for possible BB boundaries inside the block
and create new basic blocks in the progress. */ and create new basic blocks in the progress. */
static void static void
find_bb_boundaries (basic_block bb) find_bb_boundaries (basic_block bb)
{ {
basic_block orig_bb = bb;
rtx insn = BB_HEAD (bb); rtx insn = BB_HEAD (bb);
rtx end = BB_END (bb); rtx end = BB_END (bb);
rtx table;
rtx flow_transfer_insn = NULL_RTX; rtx flow_transfer_insn = NULL_RTX;
edge fallthru = NULL; edge fallthru = NULL;
...@@ -623,6 +682,11 @@ find_bb_boundaries (basic_block bb) ...@@ -623,6 +682,11 @@ find_bb_boundaries (basic_block bb)
followed by cleanup at fallthru edge, so the outgoing edges may followed by cleanup at fallthru edge, so the outgoing edges may
be dead. */ be dead. */
purge_dead_edges (bb); 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 /* Assume that frequency of basic block B is known. Compute frequencies
......
2005-01-07 Jakub Jelinek <jakub@redhat.com> 2005-01-07 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/18861
* gcc.dg/20050105-1.c: New test.
PR tree-optimization/18828 PR tree-optimization/18828
* gcc.dg/20050105-2.c: New test. * gcc.dg/20050105-2.c: New test.
......
/* 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 ();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment