Commit 96b453dc by Richard Henderson Committed by Richard Henderson

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
parent 26406018
2002-04-18 Richard Henderson <rth@redhat.com> 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. * config/ia64/ia64.md (trap, conditional_trap): New.
2002-04-18 Jakub Jelinek <jakub@redhat.com> 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 \ ...@@ -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) resource.h $(OBSTACK_H) flags.h $(TM_P_H)
ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) toplev.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) \ 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) \ dependence.o : dependence.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
$(C_COMMON_H) flags.h varray.h $(EXPR_H) $(C_COMMON_H) flags.h varray.h $(EXPR_H)
params.o : params.c $(CONFIG_H) $(SYSTEM_H) $(PARAMS_H) toplev.h params.o : params.c $(CONFIG_H) $(SYSTEM_H) $(PARAMS_H) toplev.h
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "flags.h" #include "flags.h"
#include "insn-config.h" #include "insn-config.h"
#include "recog.h" #include "recog.h"
#include "except.h"
#include "hard-reg-set.h" #include "hard-reg-set.h"
#include "basic-block.h" #include "basic-block.h"
#include "expr.h" #include "expr.h"
...@@ -104,6 +105,7 @@ static int find_if_block PARAMS ((basic_block, edge, edge)); ...@@ -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_1 PARAMS ((basic_block, edge, edge));
static int find_if_case_2 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 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 find_memory PARAMS ((rtx *, void *));
static int dead_or_predicable PARAMS ((basic_block, basic_block, static int dead_or_predicable PARAMS ((basic_block, basic_block,
basic_block, basic_block, int)); basic_block, basic_block, int));
...@@ -1812,11 +1814,14 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb) ...@@ -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 /* 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. */ the THEN block did not have a code label to begin with. */
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); if (combo_bb->global_live_at_end)
merge_blocks_nomove (combo_bb, then_bb); COPY_REG_SET (combo_bb->global_live_at_end,
num_removed_blocks++; 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 /* The ELSE block, if it existed, had a label. That label count
will almost always be zero, but odd things can happen when labels 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) ...@@ -1832,14 +1837,34 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb)
if (! join_bb) if (! join_bb)
{ {
rtx last = combo_bb->end;
/* The outgoing edge for the current COMBO block should already /* The outgoing edge for the current COMBO block should already
be correct. Verify this. */ be correct. Verify this. */
if (combo_bb->succ == NULL_EDGE) 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. */ 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 (); abort ();
} }
...@@ -2069,7 +2094,7 @@ find_cond_trap (test_bb, then_edge, else_edge) ...@@ -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 /* ??? We can't currently handle merging the blocks if they are not
already adjacent. Prevent losage in merge_if_block by detecting already adjacent. Prevent losage in merge_if_block by detecting
this now. */ this now. */
if (then_bb->succ == NULL) if ((trap = block_has_only_trap (then_bb)) != NULL)
{ {
trap_bb = then_bb; trap_bb = then_bb;
if (else_bb->index != then_bb->index + 1) if (else_bb->index != then_bb->index + 1)
...@@ -2077,7 +2102,7 @@ find_cond_trap (test_bb, then_edge, else_edge) ...@@ -2077,7 +2102,7 @@ find_cond_trap (test_bb, then_edge, else_edge)
join_bb = else_bb; join_bb = else_bb;
else_bb = NULL; else_bb = NULL;
} }
else if (else_bb->succ == NULL) else if ((trap = block_has_only_trap (else_bb)) != NULL)
{ {
trap_bb = else_bb; trap_bb = else_bb;
if (else_bb->index != then_bb->index + 1) if (else_bb->index != then_bb->index + 1)
...@@ -2091,18 +2116,6 @@ find_cond_trap (test_bb, then_edge, else_edge) ...@@ -2091,18 +2116,6 @@ find_cond_trap (test_bb, then_edge, else_edge)
else else
return FALSE; 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 (rtl_dump_file)
{ {
if (trap_bb == then_bb) if (trap_bb == then_bb)
...@@ -2149,26 +2162,55 @@ find_cond_trap (test_bb, then_edge, else_edge) ...@@ -2149,26 +2162,55 @@ find_cond_trap (test_bb, then_edge, else_edge)
if (seq == NULL) if (seq == NULL)
return FALSE; return FALSE;
/* Emit the new insns before cond_earliest; delete the old jump /* Emit the new insns before cond_earliest; delete the old jump. */
and trap insns. */
emit_insn_before (seq, cond_earliest); emit_insn_before (seq, cond_earliest);
delete_insn (jump); 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! */ /* Merge what's left. */
if (trap_bb != then_bb && ! else_bb)
{
flow_delete_block (trap_bb);
num_removed_blocks++;
}
merge_if_block (test_bb, then_bb, else_bb, join_bb); merge_if_block (test_bb, then_bb, else_bb, join_bb);
return TRUE; 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 /* Look for IF-THEN-ELSE cases in which one of THEN or ELSE is
transformable, but not necessarily the other. There need be no transformable, but not necessarily the other. There need be no
JOIN block. JOIN block.
......
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> 2002-04-18 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/compile/20020418-1.c: New test. * gcc.c-torture/compile/20020418-1.c: New test.
......
/* 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();
}
/* Verify that we optimize to conditional traps. */ /* Verify that we optimize to conditional traps. */
/* { dg-options "-O" } */ /* { dg-options "-O" } */
/* { dg-do compile { target rs6000-*-* powerpc-*-* sparc*-*-* } } */ /* { dg-do compile { target rs6000-*-* powerpc-*-* sparc*-*-* ia64-*-* } } */
/* { dg-final { scan-assembler-not "^\t(trap|ta)\[ \t\]" } } */ /* { dg-final { scan-assembler-not "^\t(trap|ta|break)\[ \t\]" } } */
void f1(int p) void f1(int p)
{ {
......
/* 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();
}
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