mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-24 22:55:11 +08:00
ifcvt.c: Include except.h.
* ifcvt.c: Include except.h. (block_has_only_trap): Break out from find_cond_trap. (find_cond_trap): Use it. Always delete the trap block. (merge_if_block): Allow then block null. Be less simplistic about what insns can end a block. * Makefile.in (ifcvt.o): Depend on except.h. * gcc.c-torture/compile/iftrap-1.c: New. * gcc.dg/iftrap-1.c: Adjust for ia64. * gcc.dg/iftrap-2.c: New. From-SVN: r52489
This commit is contained in:
parent
2640601850
commit
96b453dc81
@ -1,5 +1,12 @@
|
||||
2002-04-18 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* ifcvt.c: Include except.h.
|
||||
(block_has_only_trap): Break out from find_cond_trap.
|
||||
(find_cond_trap): Use it. Always delete the trap block.
|
||||
(merge_if_block): Allow then block null. Be less simplistic about
|
||||
what insns can end a block.
|
||||
* Makefile.in (ifcvt.o): Depend on except.h.
|
||||
|
||||
* config/ia64/ia64.md (trap, conditional_trap): New.
|
||||
|
||||
2002-04-18 Jakub Jelinek <jakub@redhat.com>
|
||||
|
@ -1589,7 +1589,7 @@ regrename.o : regrename.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) insn-config.h \
|
||||
resource.h $(OBSTACK_H) flags.h $(TM_P_H)
|
||||
ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) toplev.h \
|
||||
flags.h insn-config.h function.h $(RECOG_H) $(BASIC_BLOCK_H) $(EXPR_H) \
|
||||
output.h $(TM_P_H)
|
||||
output.h except.h $(TM_P_H)
|
||||
dependence.o : dependence.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
|
||||
$(C_COMMON_H) flags.h varray.h $(EXPR_H)
|
||||
params.o : params.c $(CONFIG_H) $(SYSTEM_H) $(PARAMS_H) toplev.h
|
||||
|
108
gcc/ifcvt.c
108
gcc/ifcvt.c
@ -27,6 +27,7 @@
|
||||
#include "flags.h"
|
||||
#include "insn-config.h"
|
||||
#include "recog.h"
|
||||
#include "except.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "basic-block.h"
|
||||
#include "expr.h"
|
||||
@ -104,6 +105,7 @@ static int find_if_block PARAMS ((basic_block, edge, edge));
|
||||
static int find_if_case_1 PARAMS ((basic_block, edge, edge));
|
||||
static int find_if_case_2 PARAMS ((basic_block, edge, edge));
|
||||
static int find_cond_trap PARAMS ((basic_block, edge, edge));
|
||||
static rtx block_has_only_trap PARAMS ((basic_block));
|
||||
static int find_memory PARAMS ((rtx *, void *));
|
||||
static int dead_or_predicable PARAMS ((basic_block, basic_block,
|
||||
basic_block, basic_block, int));
|
||||
@ -1812,11 +1814,14 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb)
|
||||
|
||||
/* First merge TEST block into THEN block. This is a no-brainer since
|
||||
the THEN block did not have a code label to begin with. */
|
||||
|
||||
if (combo_bb->global_live_at_end)
|
||||
COPY_REG_SET (combo_bb->global_live_at_end, then_bb->global_live_at_end);
|
||||
merge_blocks_nomove (combo_bb, then_bb);
|
||||
num_removed_blocks++;
|
||||
if (then_bb)
|
||||
{
|
||||
if (combo_bb->global_live_at_end)
|
||||
COPY_REG_SET (combo_bb->global_live_at_end,
|
||||
then_bb->global_live_at_end);
|
||||
merge_blocks_nomove (combo_bb, then_bb);
|
||||
num_removed_blocks++;
|
||||
}
|
||||
|
||||
/* The ELSE block, if it existed, had a label. That label count
|
||||
will almost always be zero, but odd things can happen when labels
|
||||
@ -1832,14 +1837,34 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb)
|
||||
|
||||
if (! join_bb)
|
||||
{
|
||||
rtx last = combo_bb->end;
|
||||
|
||||
/* The outgoing edge for the current COMBO block should already
|
||||
be correct. Verify this. */
|
||||
if (combo_bb->succ == NULL_EDGE)
|
||||
abort ();
|
||||
{
|
||||
if (find_reg_note (last, REG_NORETURN, NULL))
|
||||
;
|
||||
else if (GET_CODE (last) == INSN
|
||||
&& GET_CODE (PATTERN (last)) == TRAP_IF
|
||||
&& TRAP_CONDITION (PATTERN (last)) == const_true_rtx)
|
||||
;
|
||||
else
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* There should still be a branch at the end of the THEN or ELSE
|
||||
/* There should still be something at the end of the THEN or ELSE
|
||||
blocks taking us to our final destination. */
|
||||
if (GET_CODE (combo_bb->end) != JUMP_INSN)
|
||||
else if (GET_CODE (last) == JUMP_INSN)
|
||||
;
|
||||
else if (combo_bb->succ->dest == EXIT_BLOCK_PTR
|
||||
&& GET_CODE (last) == CALL_INSN
|
||||
&& SIBLING_CALL_P (last))
|
||||
;
|
||||
else if ((combo_bb->succ->flags & EDGE_EH)
|
||||
&& can_throw_internal (last))
|
||||
;
|
||||
else
|
||||
abort ();
|
||||
}
|
||||
|
||||
@ -2069,7 +2094,7 @@ find_cond_trap (test_bb, then_edge, else_edge)
|
||||
/* ??? 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 (then_bb->succ == NULL)
|
||||
if ((trap = block_has_only_trap (then_bb)) != NULL)
|
||||
{
|
||||
trap_bb = then_bb;
|
||||
if (else_bb->index != then_bb->index + 1)
|
||||
@ -2077,7 +2102,7 @@ find_cond_trap (test_bb, then_edge, else_edge)
|
||||
join_bb = else_bb;
|
||||
else_bb = NULL;
|
||||
}
|
||||
else if (else_bb->succ == NULL)
|
||||
else if ((trap = block_has_only_trap (else_bb)) != NULL)
|
||||
{
|
||||
trap_bb = else_bb;
|
||||
if (else_bb->index != then_bb->index + 1)
|
||||
@ -2091,18 +2116,6 @@ find_cond_trap (test_bb, then_edge, else_edge)
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
/* Don't confuse a conditional return with something we want to
|
||||
optimize here. */
|
||||
if (trap_bb == EXIT_BLOCK_PTR)
|
||||
return FALSE;
|
||||
|
||||
/* The only instruction in the THEN block must be the trap. */
|
||||
trap = first_active_insn (trap_bb);
|
||||
if (! (trap == trap_bb->end
|
||||
&& GET_CODE (PATTERN (trap)) == TRAP_IF
|
||||
&& TRAP_CONDITION (PATTERN (trap)) == const_true_rtx))
|
||||
return FALSE;
|
||||
|
||||
if (rtl_dump_file)
|
||||
{
|
||||
if (trap_bb == then_bb)
|
||||
@ -2149,26 +2162,55 @@ 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
|
||||
and trap insns. */
|
||||
|
||||
/* Emit the new insns before cond_earliest; delete the old jump. */
|
||||
emit_insn_before (seq, cond_earliest);
|
||||
|
||||
delete_insn (jump);
|
||||
|
||||
delete_insn (trap);
|
||||
/* 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;
|
||||
else
|
||||
abort ();
|
||||
flow_delete_block (trap_bb);
|
||||
num_removed_blocks++;
|
||||
|
||||
/* Merge the blocks! */
|
||||
if (trap_bb != then_bb && ! else_bb)
|
||||
{
|
||||
flow_delete_block (trap_bb);
|
||||
num_removed_blocks++;
|
||||
}
|
||||
/* Merge what's left. */
|
||||
merge_if_block (test_bb, then_bb, else_bb, join_bb);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Subroutine of find_cond_trap: if BB contains only a trap insn,
|
||||
return it. */
|
||||
|
||||
static rtx
|
||||
block_has_only_trap (bb)
|
||||
basic_block bb;
|
||||
{
|
||||
rtx trap;
|
||||
|
||||
/* We're not the exit block. */
|
||||
if (bb == EXIT_BLOCK_PTR)
|
||||
return NULL_RTX;
|
||||
|
||||
/* The block must have no successors. */
|
||||
if (bb->succ)
|
||||
return NULL_RTX;
|
||||
|
||||
/* The only instruction in the THEN block must be the trap. */
|
||||
trap = first_active_insn (bb);
|
||||
if (! (trap == bb->end
|
||||
&& GET_CODE (PATTERN (trap)) == TRAP_IF
|
||||
&& TRAP_CONDITION (PATTERN (trap)) == const_true_rtx))
|
||||
return NULL_RTX;
|
||||
|
||||
return trap;
|
||||
}
|
||||
|
||||
/* Look for IF-THEN-ELSE cases in which one of THEN or ELSE is
|
||||
transformable, but not necessarily the other. There need be no
|
||||
JOIN block.
|
||||
|
@ -1,3 +1,9 @@
|
||||
2002-04-18 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* gcc.c-torture/compile/iftrap-1.c: New.
|
||||
* gcc.dg/iftrap-1.c: Adjust for ia64.
|
||||
* gcc.dg/iftrap-2.c: New.
|
||||
|
||||
2002-04-18 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gcc.c-torture/compile/20020418-1.c: New test.
|
||||
|
99
gcc/testsuite/gcc.c-torture/compile/iftrap-1.c
Normal file
99
gcc/testsuite/gcc.c-torture/compile/iftrap-1.c
Normal file
@ -0,0 +1,99 @@
|
||||
/* Verify that ifcvt doesn't crash under a number of interesting conditions. */
|
||||
|
||||
void f1(int p)
|
||||
{
|
||||
if (p)
|
||||
__builtin_trap();
|
||||
}
|
||||
|
||||
void f2(int p)
|
||||
{
|
||||
if (p)
|
||||
__builtin_trap();
|
||||
else
|
||||
bar();
|
||||
}
|
||||
|
||||
void f3(int p)
|
||||
{
|
||||
if (p)
|
||||
bar();
|
||||
else
|
||||
__builtin_trap();
|
||||
}
|
||||
|
||||
void f4(int p, int q)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
bar();
|
||||
if (q)
|
||||
bar();
|
||||
}
|
||||
else
|
||||
__builtin_trap();
|
||||
}
|
||||
|
||||
void f5(int p)
|
||||
{
|
||||
if (p)
|
||||
__builtin_trap();
|
||||
else
|
||||
abort();
|
||||
}
|
||||
|
||||
void f6(int p)
|
||||
{
|
||||
if (p)
|
||||
abort();
|
||||
else
|
||||
__builtin_trap();
|
||||
}
|
||||
|
||||
void f7(int p)
|
||||
{
|
||||
if (p)
|
||||
__builtin_trap();
|
||||
else
|
||||
__builtin_trap();
|
||||
}
|
||||
|
||||
void f8(int p)
|
||||
{
|
||||
if (p)
|
||||
__builtin_trap();
|
||||
else
|
||||
{
|
||||
bar();
|
||||
__builtin_trap();
|
||||
}
|
||||
}
|
||||
|
||||
void f9(int p)
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
bar();
|
||||
__builtin_trap();
|
||||
}
|
||||
else
|
||||
__builtin_trap();
|
||||
}
|
||||
|
||||
void f10(int p)
|
||||
{
|
||||
if (p)
|
||||
__builtin_trap();
|
||||
while (1)
|
||||
bar();
|
||||
}
|
||||
|
||||
void f11(int p)
|
||||
{
|
||||
if (p)
|
||||
__builtin_trap();
|
||||
else
|
||||
bar();
|
||||
while (1)
|
||||
baz();
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/* Verify that we optimize to conditional traps. */
|
||||
/* { dg-options "-O" } */
|
||||
/* { dg-do compile { target rs6000-*-* powerpc-*-* sparc*-*-* } } */
|
||||
/* { dg-final { scan-assembler-not "^\t(trap|ta)\[ \t\]" } } */
|
||||
/* { dg-do compile { target rs6000-*-* powerpc-*-* sparc*-*-* ia64-*-* } } */
|
||||
/* { dg-final { scan-assembler-not "^\t(trap|ta|break)\[ \t\]" } } */
|
||||
|
||||
void f1(int p)
|
||||
{
|
||||
|
20
gcc/testsuite/gcc.dg/iftrap-2.c
Normal file
20
gcc/testsuite/gcc.dg/iftrap-2.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* Verify that we optimize to conditional traps. */
|
||||
/* { dg-options "-O" } */
|
||||
/* { dg-do compile { target rs6000-*-* powerpc-*-* sparc*-*-* ia64-*-* } } */
|
||||
/* { dg-final { scan-assembler-not "^\t(trap|ta|break)\[ \t\]" } } */
|
||||
|
||||
void f1(int p)
|
||||
{
|
||||
if (p)
|
||||
__builtin_trap();
|
||||
else
|
||||
abort();
|
||||
}
|
||||
|
||||
void f2(int p)
|
||||
{
|
||||
if (p)
|
||||
abort();
|
||||
else
|
||||
__builtin_trap();
|
||||
}
|
Loading…
Reference in New Issue
Block a user