Commit 4f4f436f by Richard Henderson Committed by Richard Henderson

jump.c (rtx_unsafe_p): New function.

        * jump.c (rtx_unsafe_p): New function.
        (jump_optimize): Use it on if/then/else transformations and
        conditional move transformations.

From-SVN: r20200
parent c0e3b3b3
Tue Jun 2 21:59:01 1998 Richard Henderson <rth@cygnus.com>
* jump.c (rtx_unsafe_p): New function.
(jump_optimize): Use it on if/then/else transformations and
conditional move transformations.
Tue Jun 2 22:50:10 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> Tue Jun 2 22:50:10 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* fold-const.c (fold, case EQ_EXPR): When folding VAR++ == CONST * fold-const.c (fold, case EQ_EXPR): When folding VAR++ == CONST
......
...@@ -121,6 +121,7 @@ static void redirect_tablejump PROTO((rtx, rtx)); ...@@ -121,6 +121,7 @@ static void redirect_tablejump PROTO((rtx, rtx));
#ifndef HAVE_cc0 #ifndef HAVE_cc0
static rtx find_insert_position PROTO((rtx, rtx)); static rtx find_insert_position PROTO((rtx, rtx));
#endif #endif
static int rtx_unsafe_p PROTO((rtx));
/* Delete no-op jumps and optimize jumps to jumps /* Delete no-op jumps and optimize jumps to jumps
and jumps around jumps. and jumps around jumps.
...@@ -771,11 +772,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -771,11 +772,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
&& GET_CODE (temp2) == INSN && GET_CODE (temp2) == INSN
&& (temp4 = single_set (temp2)) != 0 && (temp4 = single_set (temp2)) != 0
&& rtx_equal_p (SET_DEST (temp4), temp1) && rtx_equal_p (SET_DEST (temp4), temp1)
&& (GET_CODE (SET_SRC (temp4)) == REG && ! rtx_unsafe_p (SET_SRC (temp4))
|| GET_CODE (SET_SRC (temp4)) == SUBREG
|| (GET_CODE (SET_SRC (temp4)) == MEM
&& RTX_UNCHANGING_P (SET_SRC (temp4)))
|| CONSTANT_P (SET_SRC (temp4)))
&& (REG_NOTES (temp2) == 0 && (REG_NOTES (temp2) == 0
|| ((REG_NOTE_KIND (REG_NOTES (temp2)) == REG_EQUAL || ((REG_NOTE_KIND (REG_NOTES (temp2)) == REG_EQUAL
|| REG_NOTE_KIND (REG_NOTES (temp2)) == REG_EQUIV) || REG_NOTE_KIND (REG_NOTES (temp2)) == REG_EQUIV)
...@@ -807,6 +804,16 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -807,6 +804,16 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
rtx q; rtx q;
#endif #endif
if (!(GET_CODE (SET_SRC (temp4)) == REG
|| GET_CODE (SET_SRC (temp4)) == SUBREG
|| (GET_CODE (SET_SRC (temp4)) == MEM
&& RTX_UNCHANGING_P (SET_SRC (temp4)))
|| CONSTANT_P (SET_SRC (temp4))))
{
fprintf(stderr, "\nxyzzy 1\n");
debug_rtx (temp4);
}
/* Set P to the first jump insn that goes around "x = a;". */ /* Set P to the first jump insn that goes around "x = a;". */
for (p = temp; nuses && p; p = prev_nonnote_insn (p)) for (p = temp; nuses && p; p = prev_nonnote_insn (p))
{ {
...@@ -846,7 +853,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -846,7 +853,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
&& ! reg_referenced_between_p (temp1, p, NEXT_INSN (temp3)) && ! reg_referenced_between_p (temp1, p, NEXT_INSN (temp3))
&& ! reg_set_between_p (temp1, p, temp3) && ! reg_set_between_p (temp1, p, temp3)
&& (GET_CODE (SET_SRC (temp4)) == CONST_INT && (GET_CODE (SET_SRC (temp4)) == CONST_INT
|| ! reg_set_between_p (SET_SRC (temp4), p, temp2))) || ! modified_between_p (SET_SRC (temp4), p, temp2)))
{ {
emit_insn_after_with_line_notes (PATTERN (temp2), p, temp2); emit_insn_after_with_line_notes (PATTERN (temp2), p, temp2);
delete_insn (temp2); delete_insn (temp2);
...@@ -1161,11 +1168,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -1161,11 +1168,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
&& GET_CODE (temp1 = SET_DEST (PATTERN (temp))) == REG && GET_CODE (temp1 = SET_DEST (PATTERN (temp))) == REG
&& (! SMALL_REGISTER_CLASSES && (! SMALL_REGISTER_CLASSES
|| REGNO (temp1) >= FIRST_PSEUDO_REGISTER) || REGNO (temp1) >= FIRST_PSEUDO_REGISTER)
&& (GET_CODE (temp2 = SET_SRC (PATTERN (temp))) == REG && ! rtx_unsafe_p (temp2 = SET_SRC (PATTERN (temp)))
|| (GET_CODE (temp2) == MEM && RTX_UNCHANGING_P (temp2))
|| GET_CODE (temp2) == SUBREG
/* ??? How about floating point constants? */
|| CONSTANT_P (temp2))
/* Allow either form, but prefer the former if both apply. /* Allow either form, but prefer the former if both apply.
There is no point in using the old value of TEMP1 if There is no point in using the old value of TEMP1 if
it is a register, since cse will alias them. It can it is a register, since cse will alias them. It can
...@@ -1203,6 +1206,16 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -1203,6 +1206,16 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
#endif #endif
) )
{ {
if (! (GET_CODE (temp2) == REG
|| (GET_CODE (temp2) == MEM && RTX_UNCHANGING_P (temp2))
|| GET_CODE (temp2) == SUBREG
/* ??? How about floating point constants? */
|| CONSTANT_P (temp2)))
{
fprintf(stderr, "\nxyzzy 2\n");
debug_rtx (PATTERN (temp));
}
#ifdef HAVE_conditional_move #ifdef HAVE_conditional_move
/* First try a conditional move. */ /* First try a conditional move. */
{ {
...@@ -4783,4 +4796,73 @@ find_insert_position (insn, new) ...@@ -4783,4 +4796,73 @@ find_insert_position (insn, new)
return reg_mentioned_p (SET_DEST (single_set (new)), prev) ? 0 : prev; return reg_mentioned_p (SET_DEST (single_set (new)), prev) ? 0 : prev;
} }
/* Return 1 if the value of X is unsafe to arbitrarily evaluate, i.e.
might fault on some arguments. This is used in connection with
conditional move optimization. */
static int
rtx_unsafe_p (x)
rtx x;
{
register RTX_CODE code = GET_CODE (x);
register int i;
register char *fmt;
switch (code)
{
case MEM:
return ! RTX_UNCHANGING_P (x);
case QUEUED:
return 1;
case CONST_INT:
case CONST_DOUBLE:
case CONST_STRING:
case CONST:
case PC:
case LABEL_REF:
case SYMBOL_REF:
case ADDRESSOF:
case REG:
return 0;
case DIV:
case MOD:
case UDIV:
case UMOD:
case SQRT:
return 1;
default:
if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
&& !flag_fast_math
&& FLOAT_MODE_P (GET_MODE (x)))
return 1;
switch (GET_RTX_CLASS (code))
{
case '<':
case '1':
case '2':
case '3':
case 'c':
case 'b':
break;
default:
return 1;
}
break;
}
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
if (fmt[i] == 'e')
if (rtx_unsafe_p (XEXP (x, i)))
return 1;
return 0;
}
#endif /* !HAVE_cc0 */ #endif /* !HAVE_cc0 */
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