ifcvt.c (find_cond_trap): Handle cases with no proper THEN or JOIN blocks.

* ifcvt.c (find_cond_trap): Handle cases with no proper THEN or JOIN
        blocks.  Handle multiple references to the TRAP block.  Handle
        non-adjacent THEN and OTHER blocks.

        * gcc.dg/20000906-1.c: Enable for all targets.
        * gcc.c-torture/compile/iftrap-2.c: New.

From-SVN: r52506
This commit is contained in:
Richard Henderson 2002-04-18 20:56:33 -07:00 committed by Richard Henderson
parent c0163d3db9
commit 1245e56dde
4 changed files with 48 additions and 50 deletions

View File

@ -1,3 +1,9 @@
2002-04-18 Richard Henderson <rth@redhat.com>
* ifcvt.c (find_cond_trap): Handle cases with no proper THEN or JOIN
blocks. Handle multiple references to the TRAP block. Handle
non-adjacent THEN and OTHER blocks.
2002-04-18 Richard Henderson <rth@redhat.com>
* config/ia64/ia64.c (ia64_function_arg_pass_by_reference): Don't

View File

@ -2115,56 +2115,27 @@ find_cond_trap (test_bb, then_edge, else_edge)
basic_block test_bb;
edge then_edge, else_edge;
{
basic_block then_bb, else_bb, join_bb, trap_bb;
basic_block then_bb, else_bb, trap_bb, other_bb;
rtx trap, jump, cond, cond_earliest, seq;
enum rtx_code code;
then_bb = then_edge->dest;
else_bb = else_edge->dest;
join_bb = NULL;
/* Locate the block with the trap instruction. */
/* ??? While we look for no successors, we really ought to allow
EH successors. Need to fix merge_if_block for that to work. */
/* ??? We can't currently handle merging the blocks if they are not
already adjacent. Prevent losage in merge_if_block by detecting
this now. */
if ((trap = block_has_only_trap (then_bb)) != NULL)
{
trap_bb = then_bb;
if (else_bb->index != then_bb->index + 1)
return FALSE;
join_bb = else_bb;
else_bb = NULL;
}
trap_bb = then_bb, other_bb = else_bb;
else if ((trap = block_has_only_trap (else_bb)) != NULL)
{
trap_bb = else_bb;
if (else_bb->index != then_bb->index + 1)
else_bb = NULL;
else if (then_bb->succ
&& ! then_bb->succ->succ_next
&& ! (then_bb->succ->flags & EDGE_COMPLEX)
&& then_bb->succ->dest->index == else_bb->index + 1)
join_bb = then_bb->succ->dest;
}
trap_bb = else_bb, other_bb = then_bb;
else
return FALSE;
if (rtl_dump_file)
{
if (trap_bb == then_bb)
fprintf (rtl_dump_file,
"\nTRAP-IF block found, start %d, trap %d",
test_bb->index, then_bb->index);
else
fprintf (rtl_dump_file,
"\nTRAP-IF block found, start %d, then %d, trap %d",
test_bb->index, then_bb->index, trap_bb->index);
if (join_bb)
fprintf (rtl_dump_file, ", join %d\n", join_bb->index);
else
fputc ('\n', rtl_dump_file);
fprintf (rtl_dump_file, "\nTRAP-IF block found, start %d, trap %d\n",
test_bb->index, trap_bb->index);
}
/* If this is not a standard conditional jump, we can't parse it. */
@ -2197,24 +2168,36 @@ find_cond_trap (test_bb, then_edge, else_edge)
if (seq == NULL)
return FALSE;
/* Emit the new insns before cond_earliest; delete the old jump. */
/* Emit the new insns before cond_earliest. */
emit_insn_before (seq, cond_earliest);
delete_insn (jump);
/* Delete the trap block together with its insn. */
if (trap_bb == then_bb)
then_bb = NULL;
else if (else_bb == NULL)
;
else if (trap_bb == else_bb)
else_bb = NULL;
/* Delete the trap block if possible. */
remove_edge (trap_bb == then_bb ? then_edge : else_edge);
if (trap_bb->pred == NULL)
{
flow_delete_block (trap_bb);
num_removed_blocks++;
}
/* If the non-trap block and the test are now adjacent, merge them.
Otherwise we must insert a direct branch. */
if (test_bb->index + 1 == other_bb->index)
{
delete_insn (jump);
merge_if_block (test_bb, NULL, NULL, other_bb);
}
else
abort ();
flow_delete_block (trap_bb);
num_removed_blocks++;
{
rtx lab, newjump;
/* Merge what's left. */
merge_if_block (test_bb, then_bb, else_bb, join_bb);
lab = JUMP_LABEL (jump);
newjump = emit_jump_insn_after (gen_jump (lab), jump);
LABEL_NUSES (lab) += 1;
JUMP_LABEL (newjump) = lab;
emit_barrier_after (newjump);
delete_insn (jump);
}
return TRUE;
}

View File

@ -0,0 +1,10 @@
void foo(int p, int q)
{
if (p)
{
if (q)
__builtin_trap ();
}
else
bar();
}

View File

@ -1,5 +1,4 @@
/* The target must support __builtin_trap to run this test. */
/* { dg-do run { target i?86-*-* mips*-*-* powerpc*-*-* m68k-*-* sparc*-*-* i960*-*-* } } */
/* { dg-do run } */
/* Testcase distilled from glibc's nss_parse_service_list in nss/nsswitch.c
It can't be distilled further. Fails with `-O2' for i[3456]86. */