diff options
author | Richard Henderson <rth@redhat.com> | 2002-04-18 13:02:18 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2002-04-18 13:02:18 -0700 |
commit | 96b453dc817b2af01b88e22f4e57394b79342339 (patch) | |
tree | 14f600f23fb352e68da7b61ad3f6ac0326cad42c | |
parent | 26406018509b6c8884453317d30e01c987fe9977 (diff) | |
download | gcc-96b453dc817b2af01b88e22f4e57394b79342339.zip gcc-96b453dc817b2af01b88e22f4e57394b79342339.tar.gz gcc-96b453dc817b2af01b88e22f4e57394b79342339.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/ifcvt.c | 108 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/iftrap-1.c | 99 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/iftrap-1.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/iftrap-2.c | 20 |
7 files changed, 210 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 05a5f09..137640d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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> diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 1f7ad81..5a386ea 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -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 diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 207ff5c..880f94a 100644 --- a/gcc/ifcvt.c +++ b/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. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9c6bd86..2a2aeda 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/gcc.c-torture/compile/iftrap-1.c b/gcc/testsuite/gcc.c-torture/compile/iftrap-1.c new file mode 100644 index 0000000..a0adc78 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/iftrap-1.c @@ -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(); +} diff --git a/gcc/testsuite/gcc.dg/iftrap-1.c b/gcc/testsuite/gcc.dg/iftrap-1.c index b6abfc4..69d754d 100644 --- a/gcc/testsuite/gcc.dg/iftrap-1.c +++ b/gcc/testsuite/gcc.dg/iftrap-1.c @@ -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) { diff --git a/gcc/testsuite/gcc.dg/iftrap-2.c b/gcc/testsuite/gcc.dg/iftrap-2.c new file mode 100644 index 0000000..909a85f --- /dev/null +++ b/gcc/testsuite/gcc.dg/iftrap-2.c @@ -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(); +} |