diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9d377b3eae5..6bb0422d841 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2004-07-27 Richard Sandiford + + * expr.h (canonicalize_condition, get_condition): Add an int argument. + * gcse.c (fis_get_condition): Reimplement using get_condition, leaving + it to check whether the condition is still valid at the jump insn. + * ifcvt.c (noce_get_condition): Likewise. + (noce_get_alt_condition): Update call to canonicalize_condition. + * loop-iv.c (simplify_using_initial_values): Update call to + get_condition. Remove FIXME. + (check_simple_exit): Update call to get_condition. + * loop-unswitch.c (may_unswitch_on): Likewise. + * loop.c (check_dbra_loop): Likewise. + (canonicalize_condition, get_condition): Add an argument to say whether + the condition must still be valid at INSN. + (get_condition_for_loop): Update call to get_condition. Require that + the condition be valid at INSN. + * predict.c (estimate_probability): Update call to get_condition. + Remove unused earliest parameter. + (expected_value_to_br_prob): Update call to canonicalize_condition. + 2004-07-26 Eric Christopher * tree-dfa.c (add_referenced_var): Register initializers of global diff --git a/gcc/expr.h b/gcc/expr.h index 0126c5869a9..ad487483677 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -338,11 +338,11 @@ extern rtx emit_store_flag_force (rtx, enum rtx_code, rtx, rtx, /* Given an insn and condition, return a canonical description of the test being made. */ -extern rtx canonicalize_condition (rtx, rtx, int, rtx *, rtx, int); +extern rtx canonicalize_condition (rtx, rtx, int, rtx *, rtx, int, int); /* Given a JUMP_INSN, return a canonical description of the test being made. */ -extern rtx get_condition (rtx, rtx *, int); +extern rtx get_condition (rtx, rtx *, int, int); /* Generate a conditional trap instruction. */ extern rtx gen_cond_trap (enum rtx_code, rtx, rtx, rtx); diff --git a/gcc/gcse.c b/gcc/gcse.c index 1d7212559b5..b99fc415eaf 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -3687,52 +3687,7 @@ cprop (int alter_jumps) rtx fis_get_condition (rtx jump) { - rtx cond, set, tmp, insn, earliest; - bool reverse; - - if (! any_condjump_p (jump)) - return NULL_RTX; - - set = pc_set (jump); - cond = XEXP (SET_SRC (set), 0); - - /* 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)); - - /* Use 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, - false); - if (!tmp) - return NULL_RTX; - - /* Verify that the given condition is valid at JUMP by virtue of not - having been modified since EARLIEST. */ - 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, - false); - 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 get_condition (jump, NULL, false, true); } /* Check the comparison COND to see if we can safely form an implicit set from diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index ac478af71ba..96833a54dda 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1489,7 +1489,7 @@ noce_get_alt_condition (struct noce_if_info *if_info, rtx target, } cond = canonicalize_condition (if_info->jump, cond, reverse, - earliest, target, false); + earliest, target, false, true); if (! cond || ! reg_mentioned_p (target, cond)) return NULL; @@ -1800,7 +1800,7 @@ noce_try_sign_mask (struct noce_if_info *if_info) static rtx noce_get_condition (rtx jump, rtx *earliest) { - rtx cond, set, tmp, insn; + rtx cond, set, tmp; bool reverse; if (! any_condjump_p (jump)) @@ -1829,38 +1829,8 @@ noce_get_condition (rtx jump, rtx *earliest) /* 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, - false); - 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, - false); - 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 canonicalize_condition (jump, cond, reverse, earliest, + NULL_RTX, false, true); } /* Return true if OP is ok for if-then-else processing. */ diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c index f390cdd487c..68b0013c06c 100644 --- a/gcc/loop-iv.c +++ b/gcc/loop-iv.c @@ -1737,9 +1737,7 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr) insn = BB_END (e->src); if (any_condjump_p (insn)) { - /* FIXME -- slightly wrong -- what if compared register - gets altered between start of the condition and insn? */ - rtx cond = get_condition (BB_END (e->src), NULL, false); + rtx cond = get_condition (BB_END (e->src), NULL, false, true); if (cond && (e->flags & EDGE_FALLTHRU)) cond = reversed_condition (cond); @@ -2472,7 +2470,7 @@ check_simple_exit (struct loop *loop, edge e, struct niter_desc *desc) desc->in_edge = ei; /* Test whether the condition is suitable. */ - if (!(condition = get_condition (BB_END (ei->src), &at, false))) + if (!(condition = get_condition (BB_END (ei->src), &at, false, false))) return; if (ei->flags & EDGE_FALLTHRU) diff --git a/gcc/loop-unswitch.c b/gcc/loop-unswitch.c index 8f1f54f0d73..08780f0d58f 100644 --- a/gcc/loop-unswitch.c +++ b/gcc/loop-unswitch.c @@ -196,7 +196,7 @@ may_unswitch_on (basic_block bb, struct loop *loop, rtx *cinsn) return NULL_RTX; /* Condition must be invariant. */ - test = get_condition (BB_END (bb), &at, true); + test = get_condition (BB_END (bb), &at, true, false); if (!test) return NULL_RTX; diff --git a/gcc/loop.c b/gcc/loop.c index a6353d79518..c8a16e0850d 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -8001,7 +8001,7 @@ check_dbra_loop (struct loop *loop, int insn_count) /* Try to compute whether the compare/branch at the loop end is one or two instructions. */ - get_condition (jump, &first_compare, false); + get_condition (jump, &first_compare, false, true); if (first_compare == jump) compare_and_branch = 1; else if (first_compare == prev_nonnote_insn (jump)) @@ -9195,11 +9195,14 @@ update_reg_last_use (rtx x, rtx insn) If WANT_REG is nonzero, we wish the condition to be relative to that register, if possible. Therefore, do not canonicalize the condition further. If ALLOW_CC_MODE is nonzero, allow the condition returned - to be a compare to a CC mode register. */ + to be a compare to a CC mode register. + + If VALID_AT_INSN_P, the condition must be valid at both *EARLIEST + and at INSN. */ rtx canonicalize_condition (rtx insn, rtx cond, int reverse, rtx *earliest, - rtx want_reg, int allow_cc_mode) + rtx want_reg, int allow_cc_mode, int valid_at_insn_p) { enum rtx_code code; rtx prev = insn; @@ -9357,6 +9360,11 @@ canonicalize_condition (rtx insn, rtx cond, int reverse, rtx *earliest, if (x) { + /* If the caller is expecting the condition to be valid at INSN, + make sure X doesn't change before INSN. */ + if (valid_at_insn_p) + if (modified_in_p (x, prev) || modified_between_p (x, prev, insn)) + break; if (COMPARISON_P (x)) code = GET_CODE (x); if (reverse_code) @@ -9443,13 +9451,16 @@ canonicalize_condition (rtx insn, rtx cond, int reverse, rtx *earliest, If EARLIEST is nonzero, it is a pointer to a place where the earliest insn used in locating the condition was found. If a replacement test of the condition is desired, it should be placed in front of that - insn and we will be sure that the inputs are still valid. + insn and we will be sure that the inputs are still valid. If EARLIEST + is null, the returned condition will be valid at INSN. If ALLOW_CC_MODE is nonzero, allow the condition returned to be a - compare CC mode register. */ + compare CC mode register. + + VALID_AT_INSN_P is the same as for canonicalize_condition. */ rtx -get_condition (rtx jump, rtx *earliest, int allow_cc_mode) +get_condition (rtx jump, rtx *earliest, int allow_cc_mode, int valid_at_insn_p) { rtx cond; int reverse; @@ -9470,7 +9481,7 @@ get_condition (rtx jump, rtx *earliest, int allow_cc_mode) && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump); return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX, - allow_cc_mode); + allow_cc_mode, valid_at_insn_p); } /* Similar to above routine, except that we also put an invariant last @@ -9479,7 +9490,7 @@ get_condition (rtx jump, rtx *earliest, int allow_cc_mode) rtx get_condition_for_loop (const struct loop *loop, rtx x) { - rtx comparison = get_condition (x, (rtx*) 0, false); + rtx comparison = get_condition (x, (rtx*) 0, false, true); if (comparison == 0 || ! loop_invariant_p (loop, XEXP (comparison, 0)) diff --git a/gcc/predict.c b/gcc/predict.c index c92b27f8bdf..e55427d9acc 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -636,7 +636,7 @@ estimate_probability (struct loops *loops_info) FOR_EACH_BB (bb) { rtx last_insn = BB_END (bb); - rtx cond, earliest; + rtx cond; edge e; if (! can_predict_insn_p (last_insn)) @@ -681,7 +681,7 @@ estimate_probability (struct loops *loops_info) } } - cond = get_condition (last_insn, &earliest, false); + cond = get_condition (last_insn, NULL, false, false); if (! cond) continue; @@ -1043,7 +1043,8 @@ expected_value_to_br_prob (void) (lt r70, r71) Could use cselib to try and reduce this further. */ cond = XEXP (SET_SRC (pc_set (insn)), 0); - cond = canonicalize_condition (insn, cond, 0, NULL, ev_reg, false); + cond = canonicalize_condition (insn, cond, 0, NULL, ev_reg, + false, false); if (! cond || XEXP (cond, 0) != ev_reg || GET_CODE (XEXP (cond, 1)) != CONST_INT) continue;