From: Richard Henderson Date: Tue, 2 Jun 1998 22:03:22 +0000 (-0700) Subject: jump.c (rtx_unsafe_p): New function. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4f4f436f0784431645c407e93fafcc6017a77e5c;p=platform%2Fupstream%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index af9dab8..e09d852 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +Tue Jun 2 21:59:01 1998 Richard Henderson + + * 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 * fold-const.c (fold, case EQ_EXPR): When folding VAR++ == CONST diff --git a/gcc/jump.c b/gcc/jump.c index d5e3396..0a4fecd 100644 --- a/gcc/jump.c +++ b/gcc/jump.c @@ -121,6 +121,7 @@ static void redirect_tablejump PROTO((rtx, rtx)); #ifndef HAVE_cc0 static rtx find_insert_position PROTO((rtx, rtx)); #endif +static int rtx_unsafe_p PROTO((rtx)); /* Delete no-op jumps and optimize jumps to jumps and jumps around jumps. @@ -771,11 +772,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) && GET_CODE (temp2) == INSN && (temp4 = single_set (temp2)) != 0 && rtx_equal_p (SET_DEST (temp4), temp1) - && (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))) + && ! rtx_unsafe_p (SET_SRC (temp4)) && (REG_NOTES (temp2) == 0 || ((REG_NOTE_KIND (REG_NOTES (temp2)) == REG_EQUAL || REG_NOTE_KIND (REG_NOTES (temp2)) == REG_EQUIV) @@ -807,6 +804,16 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) rtx q; #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;". */ for (p = temp; nuses && p; p = prev_nonnote_insn (p)) { @@ -846,7 +853,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) && ! reg_referenced_between_p (temp1, p, NEXT_INSN (temp3)) && ! reg_set_between_p (temp1, p, temp3) && (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); delete_insn (temp2); @@ -1161,11 +1168,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) && GET_CODE (temp1 = SET_DEST (PATTERN (temp))) == REG && (! SMALL_REGISTER_CLASSES || REGNO (temp1) >= FIRST_PSEUDO_REGISTER) - && (GET_CODE (temp2 = SET_SRC (PATTERN (temp))) == REG - || (GET_CODE (temp2) == MEM && RTX_UNCHANGING_P (temp2)) - || GET_CODE (temp2) == SUBREG - /* ??? How about floating point constants? */ - || CONSTANT_P (temp2)) + && ! rtx_unsafe_p (temp2 = SET_SRC (PATTERN (temp))) /* Allow either form, but prefer the former if both apply. There is no point in using the old value of TEMP1 if it is a register, since cse will alias them. It can @@ -1203,6 +1206,16 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) #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 /* First try a conditional move. */ { @@ -4783,4 +4796,73 @@ find_insert_position (insn, new) 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 */