diff options
author | Richard Henderson <rth@gcc.gnu.org> | 2002-07-18 10:48:04 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2002-07-18 10:48:04 -0700 |
commit | 30484ccf418d52a3b7ad165785dc7853ae01a77f (patch) | |
tree | be72f09712cf01a23ee3111573e710a3877998c1 /gcc/ifcvt.c | |
parent | c1740ae3c12105406dffbf001d67f5905b70b069 (diff) | |
download | gcc-30484ccf418d52a3b7ad165785dc7853ae01a77f.zip gcc-30484ccf418d52a3b7ad165785dc7853ae01a77f.tar.gz gcc-30484ccf418d52a3b7ad165785dc7853ae01a77f.tar.bz2 |
ifcvt.c (noce_get_condition): Make certain that the condition is valid at JUMP.
* ifcvt.c (noce_get_condition): Make certain that the condition
is valid at JUMP.
From-SVN: r55560
Diffstat (limited to 'gcc/ifcvt.c')
-rw-r--r-- | gcc/ifcvt.c | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 6bc522d..cf7b660 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1496,45 +1496,73 @@ noce_try_abs (if_info) return TRUE; } -/* Look for the condition for the jump first. We'd prefer to avoid - get_condition if we can -- it tries to look back for the contents - of an original compare. On targets that use normal integers for - comparisons, e.g. alpha, this is wasteful. */ +/* Similar to get_condition, only the resulting condition must be + valid at JUMP, instead of at EARLIEST. */ static rtx noce_get_condition (jump, earliest) rtx jump; rtx *earliest; { - rtx cond; - rtx set; - - /* If the condition variable is a register and is MODE_INT, accept it. - Otherwise, fall back on get_condition. */ + rtx cond, set, tmp, insn; + bool reverse; if (! any_condjump_p (jump)) return NULL_RTX; set = pc_set (jump); + /* If this branches to JUMP_LABEL when the condition is false, + reverse the condition. */ + reverse = (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF + && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump)); + + /* If the condition variable is a register and is MODE_INT, accept it. */ + cond = XEXP (SET_SRC (set), 0); - if (GET_CODE (XEXP (cond, 0)) == REG - && GET_MODE_CLASS (GET_MODE (XEXP (cond, 0))) == MODE_INT) + tmp = XEXP (cond, 0); + if (REG_P (tmp) && GET_MODE_CLASS (GET_MODE (tmp)) == MODE_INT) { *earliest = jump; - /* If this branches to JUMP_LABEL when the condition is false, - reverse the condition. */ - if (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF - && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump)) + if (reverse) cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)), - GET_MODE (cond), XEXP (cond, 0), - XEXP (cond, 1)); + GET_MODE (cond), tmp, XEXP (cond, 1)); + return cond; } - else - cond = get_condition (jump, earliest); - return cond; + /* Otherwise, fall back on canonicalize_condition to do the dirty + work of manipulating MODE_CC values and COMPARE rtx codes. */ + + tmp = canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX); + if (!tmp) + return NULL_RTX; + + /* We are going to insert code before JUMP, not before EARLIEST. + We must therefore be certain that the given condition is valid + at JUMP by virtue of not having been modified since. */ + for (insn = *earliest; insn != jump; insn = NEXT_INSN (insn)) + if (INSN_P (insn) && modified_in_p (tmp, insn)) + break; + if (insn == jump) + return tmp; + + /* The condition was modified. See if we can get a partial result + that doesn't follow all the reversals. Perhaps combine can fold + them together later. */ + tmp = XEXP (tmp, 0); + if (!REG_P (tmp) || GET_MODE_CLASS (GET_MODE (tmp)) != MODE_INT) + return NULL_RTX; + tmp = canonicalize_condition (jump, cond, reverse, earliest, tmp); + if (!tmp) + return NULL_RTX; + + /* For sanity's sake, re-validate the new result. */ + for (insn = *earliest; insn != jump; insn = NEXT_INSN (insn)) + if (INSN_P (insn) && modified_in_p (tmp, insn)) + return NULL_RTX; + + return tmp; } /* Return true if OP is ok for if-then-else processing. */ |