Commit 999c0669 by Richard Henderson Committed by Richard Henderson

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
parent 386eda2e
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> 2001-07-14 Alan Modra <amodra@bigpond.net.au>
* config/pa/pa.c (emit_hpdiv_const): Return reg is r2 for 64-bit * config/pa/pa.c (emit_hpdiv_const): Return reg is r2 for 64-bit
......
...@@ -48,6 +48,12 @@ ...@@ -48,6 +48,12 @@
#ifndef HAVE_decscc #ifndef HAVE_decscc
#define HAVE_decscc 0 #define HAVE_decscc 0
#endif #endif
#ifndef HAVE_trap
#define HAVE_trap 0
#endif
#ifndef HAVE_conditional_trap
#define HAVE_conditional_trap 0
#endif
#ifndef MAX_CONDITIONAL_EXECUTE #ifndef MAX_CONDITIONAL_EXECUTE
#define MAX_CONDITIONAL_EXECUTE (BRANCH_COST + 1) #define MAX_CONDITIONAL_EXECUTE (BRANCH_COST + 1)
...@@ -97,6 +103,7 @@ static int find_if_header PARAMS ((basic_block)); ...@@ -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_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_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, rtx, int)); basic_block, rtx, int));
...@@ -1757,10 +1764,9 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb) ...@@ -1757,10 +1764,9 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb)
if (combo_bb->succ == NULL_EDGE) if (combo_bb->succ == NULL_EDGE)
abort (); 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. */ blocks taking us to our final destination. */
if (! any_uncondjump_p (combo_bb->end) if (GET_CODE (combo_bb->end) != JUMP_INSN)
&& ! returnjump_p (combo_bb->end))
abort (); abort ();
} }
...@@ -1835,6 +1841,9 @@ find_if_header (test_bb) ...@@ -1835,6 +1841,9 @@ find_if_header (test_bb)
if (find_if_block (test_bb, then_edge, else_edge)) if (find_if_block (test_bb, then_edge, else_edge))
goto success; goto success;
if (HAVE_trap && HAVE_conditional_trap
&& find_cond_trap (test_bb, then_edge, else_edge))
goto success;
if (post_dominators if (post_dominators
&& (! HAVE_conditional_execution || reload_completed)) && (! HAVE_conditional_execution || reload_completed))
{ {
...@@ -1965,6 +1974,125 @@ find_if_block (test_bb, then_edge, else_edge) ...@@ -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); 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 /* 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.
......
...@@ -208,9 +208,6 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, ...@@ -208,9 +208,6 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan,
int first = 1; int first = 1;
int max_uid = 0; int max_uid = 0;
rtx last_insn; rtx last_insn;
#ifdef HAVE_trap
enum rtx_code reversed_code;
#endif
cross_jump_death_matters = (cross_jump == 2); cross_jump_death_matters = (cross_jump == 2);
max_uid = init_label_info (f) + 1; max_uid = init_label_info (f) + 1;
...@@ -498,82 +495,6 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, ...@@ -498,82 +495,6 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan,
changed = 1; changed = 1;
next = NEXT_INSN (insn); 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 else
{ {
/* Now that the jump has been tensioned, /* Now that the jump has been tensioned,
......
2001-07-14 Richard Henderson <rth@redhat.com>
* gcc.dg/iftrap-1.c: New.
2001-07-11 David Billinghurst <David.Billinghurst@riotinto.com> 2001-07-11 David Billinghurst <David.Billinghurst@riotinto.com>
* g77.f-torture/execute/intrinsic77.f: New test. * g77.f-torture/execute/intrinsic77.f: New test.
......
/* 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();
}
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