ifcvt.c (find_cond_trap): New.

* ifcvt.c (find_cond_trap): New.
        (find_if_header): Call it.
        (merge_if_block): Relax existing jump sanity check.
        * jump.c (jump_optimize_1): Remove conditional trap handling.

	* gcc.dg/iftrap-1.c: New.

From-SVN: r44006
This commit is contained in:
Richard Henderson 2001-07-14 11:39:16 -07:00 committed by Richard Henderson
parent 386eda2e22
commit 999c066978
5 changed files with 180 additions and 82 deletions

View File

@ -1,3 +1,10 @@
2001-07-14 Richard Henderson <rth@redhat.com>
* ifcvt.c (find_cond_trap): New.
(find_if_header): Call it.
(merge_if_block): Relax existing jump sanity check.
* jump.c (jump_optimize_1): Remove conditional trap handling.
2001-07-14 Alan Modra <amodra@bigpond.net.au>
* config/pa/pa.c (emit_hpdiv_const): Return reg is r2 for 64-bit

View File

@ -48,6 +48,12 @@
#ifndef HAVE_decscc
#define HAVE_decscc 0
#endif
#ifndef HAVE_trap
#define HAVE_trap 0
#endif
#ifndef HAVE_conditional_trap
#define HAVE_conditional_trap 0
#endif
#ifndef MAX_CONDITIONAL_EXECUTE
#define MAX_CONDITIONAL_EXECUTE (BRANCH_COST + 1)
@ -97,6 +103,7 @@ static int find_if_header PARAMS ((basic_block));
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 int find_memory PARAMS ((rtx *, void *));
static int dead_or_predicable PARAMS ((basic_block, basic_block,
basic_block, rtx, int));
@ -1757,10 +1764,9 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb)
if (combo_bb->succ == NULL_EDGE)
abort ();
/* There should sill be a branch at the end of the THEN or ELSE
/* There should still be a branch at the end of the THEN or ELSE
blocks taking us to our final destination. */
if (! any_uncondjump_p (combo_bb->end)
&& ! returnjump_p (combo_bb->end))
if (GET_CODE (combo_bb->end) != JUMP_INSN)
abort ();
}
@ -1835,6 +1841,9 @@ find_if_header (test_bb)
if (find_if_block (test_bb, then_edge, else_edge))
goto success;
if (HAVE_trap && HAVE_conditional_trap
&& find_cond_trap (test_bb, then_edge, else_edge))
goto success;
if (post_dominators
&& (! HAVE_conditional_execution || reload_completed))
{
@ -1965,6 +1974,125 @@ find_if_block (test_bb, then_edge, else_edge)
return process_if_block (test_bb, then_bb, else_bb, join_bb);
}
/* Convert a branch over a trap, or a branch to a trap,
into a conditional trap. */
static int
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;
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 (then_bb->succ == NULL)
{
trap_bb = then_bb;
if (else_bb->index != then_bb->index + 1)
return FALSE;
join_bb = else_bb;
else_bb = NULL;
}
else if (else_bb->succ == 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;
}
else
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)
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);
}
/* If this is not a standard conditional jump, we can't parse it. */
jump = test_bb->end;
cond = noce_get_condition (jump, &cond_earliest);
if (! cond)
return FALSE;
/* If the conditional jump is more than just a conditional jump,
then we can not do if-conversion on this block. */
if (! onlyjump_p (jump))
return FALSE;
/* We must be comparing objects whose modes imply the size. */
if (GET_MODE (XEXP (cond, 0)) == BLKmode)
return FALSE;
/* Reverse the comparison code, if necessary. */
code = GET_CODE (cond);
if (then_bb == trap_bb)
{
code = reversed_comparison_code (cond, jump);
if (code == UNKNOWN)
return FALSE;
}
/* Attempt to generate the conditional trap. */
seq = gen_cond_trap (code, XEXP (cond, 0), XEXP (cond, 1),
TRAP_CODE (PATTERN (trap)));
if (seq == NULL)
return FALSE;
/* Emit the new insns before cond_earliest; delete the old jump
and trap insns. */
emit_insn_before (seq, cond_earliest);
test_bb->end = PREV_INSN (jump);
flow_delete_insn (jump);
trap_bb->end = PREV_INSN (trap);
flow_delete_insn (trap);
/* Merge the blocks! */
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);
return TRUE;
}
/* 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.

View File

@ -208,9 +208,6 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan,
int first = 1;
int max_uid = 0;
rtx last_insn;
#ifdef HAVE_trap
enum rtx_code reversed_code;
#endif
cross_jump_death_matters = (cross_jump == 2);
max_uid = init_label_info (f) + 1;
@ -498,82 +495,6 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan,
changed = 1;
next = NEXT_INSN (insn);
}
#ifdef HAVE_trap
/* Detect a conditional jump jumping over an unconditional trap. */
if (HAVE_trap
&& this_is_any_condjump && this_is_onlyjump
&& reallabelprev != 0
&& GET_CODE (reallabelprev) == INSN
&& GET_CODE (PATTERN (reallabelprev)) == TRAP_IF
&& TRAP_CONDITION (PATTERN (reallabelprev)) == const_true_rtx
&& prev_active_insn (reallabelprev) == insn
&& no_labels_between_p (insn, reallabelprev)
&& (temp2 = get_condition (insn, &temp4))
&& ((reversed_code = reversed_comparison_code (temp2, insn))
!= UNKNOWN))
{
rtx new = gen_cond_trap (reversed_code,
XEXP (temp2, 0), XEXP (temp2, 1),
TRAP_CODE (PATTERN (reallabelprev)));
if (new)
{
emit_insn_before (new, temp4);
delete_insn (reallabelprev);
delete_jump (insn);
changed = 1;
continue;
}
}
/* Detect a jump jumping to an unconditional trap. */
else if (HAVE_trap && this_is_onlyjump
&& (temp = next_active_insn (JUMP_LABEL (insn)))
&& GET_CODE (temp) == INSN
&& GET_CODE (PATTERN (temp)) == TRAP_IF
&& (this_is_any_uncondjump
|| (this_is_any_condjump
&& (temp2 = get_condition (insn, &temp4)))))
{
rtx tc = TRAP_CONDITION (PATTERN (temp));
if (tc == const_true_rtx
|| (! this_is_any_uncondjump && rtx_equal_p (temp2, tc)))
{
rtx new;
/* Replace an unconditional jump to a trap with a trap. */
if (this_is_any_uncondjump)
{
emit_barrier_after (emit_insn_before (gen_trap (), insn));
delete_jump (insn);
changed = 1;
continue;
}
new = gen_cond_trap (GET_CODE (temp2), XEXP (temp2, 0),
XEXP (temp2, 1),
TRAP_CODE (PATTERN (temp)));
if (new)
{
emit_insn_before (new, temp4);
delete_jump (insn);
changed = 1;
continue;
}
}
/* If the trap condition and jump condition are mutually
exclusive, redirect the jump to the following insn. */
else if (GET_RTX_CLASS (GET_CODE (tc)) == '<'
&& this_is_any_condjump
&& swap_condition (GET_CODE (temp2)) == GET_CODE (tc)
&& rtx_equal_p (XEXP (tc, 0), XEXP (temp2, 0))
&& rtx_equal_p (XEXP (tc, 1), XEXP (temp2, 1))
&& redirect_jump (insn, get_label_after (temp), 1))
{
changed = 1;
continue;
}
}
#endif
else
{
/* Now that the jump has been tensioned,

View File

@ -1,3 +1,7 @@
2001-07-14 Richard Henderson <rth@redhat.com>
* gcc.dg/iftrap-1.c: New.
2001-07-11 David Billinghurst <David.Billinghurst@riotinto.com>
* g77.f-torture/execute/intrinsic77.f: New test.

View File

@ -0,0 +1,38 @@
/* Verify that we optimize to conditional traps. */
/* { dg-options "-O" } */
/* { dg-do compile { target rs6000-* powerpc-* sparc*-* } } */
/* { dg-final { scan-assembler-not iftrap-1.c "^\t(trap|ta)\[ \t\]" } } */
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();
}