From: Zdenek Dvorak Date: Mon, 15 Sep 2003 01:55:53 +0000 (+0200) Subject: re PR rtl-optimization/10914 (unswitch loops does not work on powerpc) X-Git-Tag: releases/gcc-3.4.0~3735 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ec6ec6aaabd93cd9018f73d5a9880466eb55b55c;p=thirdparty%2Fgcc.git re PR rtl-optimization/10914 (unswitch loops does not work on powerpc) 2003-09-12 Zdenek Dvorak PR optimization/10914 * expr.h (get_condition, canonicalize_condition): Declaration changed. * cfgloopanal.c (simple_loop_exit_p): Add parameter to a get_condition and canonicalize_condition calls. * gcse.c (fis_get_condition, delete_null_pointer_checks_1, delete_null_pointer_checks): Ditto. * ifcvt.c (noce_get_alt_condition, noce_get_condition): Ditto. * predict.c (estimate_probability, expected_value_to_br_prob): Ditto. * loop.c (check_dbra_loop, get_condition_for_loop): Ditto. (canonicalize_condition, get_condition): Allow to return comparisons of cc mode registers. * loop-unswitch.c (may_unswitch_on_p, unswitch_single_loop): Allow cc mode registers comparison in condition. From-SVN: r71398 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d7e7d64d829f..362e6d56b331 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2003-09-12 Zdenek Dvorak + + PR optimization/10914 + * expr.h (get_condition, canonicalize_condition): Declaration changed. + * cfgloopanal.c (simple_loop_exit_p): Add parameter to a get_condition + and canonicalize_condition calls. + * gcse.c (fis_get_condition, delete_null_pointer_checks_1, + delete_null_pointer_checks): Ditto. + * ifcvt.c (noce_get_alt_condition, noce_get_condition): Ditto. + * predict.c (estimate_probability, expected_value_to_br_prob): Ditto. + * loop.c (check_dbra_loop, get_condition_for_loop): Ditto. + (canonicalize_condition, get_condition): Allow to return comparisons + of cc mode registers. + * loop-unswitch.c (may_unswitch_on_p, unswitch_single_loop): Allow + cc mode registers comparison in condition. + 2003-09-12 Mark Mitchell * coverage.c (create_coverage): Do not call pushlevel/poplevel. diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c index da3602ebf019..68dd92823334 100644 --- a/gcc/cfgloopanal.c +++ b/gcc/cfgloopanal.c @@ -775,7 +775,7 @@ simple_loop_exit_p (struct loops *loops, struct loop *loop, edge exit_edge, /* Condition must be a simple comparison in that one of operands is register and the other one is invariant. */ - if (!(condition = get_condition (exit_bb->end, NULL))) + if (!(condition = get_condition (exit_bb->end, NULL, false))) return false; if (!simple_condition_p (loop, condition, invariant_regs, desc)) diff --git a/gcc/expr.h b/gcc/expr.h index aa9936e1555f..2037119df34d 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -317,11 +317,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); +extern rtx canonicalize_condition (rtx, rtx, int, rtx *, rtx, int); /* Given a JUMP_INSN, return a canonical description of the test being made. */ -extern rtx get_condition (rtx, rtx *); +extern rtx get_condition (rtx, rtx *, 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 edc8a6257469..3ea5411e17a0 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -4480,7 +4480,8 @@ fis_get_condition (rtx 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); + tmp = canonicalize_condition (jump, cond, reverse, &earliest, NULL_RTX, + false); if (!tmp) return NULL_RTX; @@ -4498,7 +4499,8 @@ fis_get_condition (rtx jump) 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); + tmp = canonicalize_condition (jump, cond, reverse, &earliest, tmp, + false); if (!tmp) return NULL_RTX; @@ -5880,7 +5882,7 @@ delete_null_pointer_checks_1 (unsigned int *block_reg, sbitmap *nonnull_avin, continue; /* LAST_INSN is a conditional jump. Get its condition. */ - condition = get_condition (last_insn, &earliest); + condition = get_condition (last_insn, &earliest, false); /* If we can't determine the condition then skip. */ if (! condition) @@ -5994,7 +5996,7 @@ delete_null_pointer_checks (rtx f ATTRIBUTE_UNUSED) continue; /* LAST_INSN is a conditional jump. Get its condition. */ - condition = get_condition (last_insn, &earliest); + condition = get_condition (last_insn, &earliest, false); /* If we were unable to get the condition, or it is not an equality comparison against zero then there's nothing we can do. */ diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index eec1f369cd32..782960bac664 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1397,7 +1397,7 @@ noce_get_alt_condition (struct noce_if_info *if_info, rtx target, } cond = canonicalize_condition (if_info->jump, cond, reverse, - earliest, target); + earliest, target, false); if (! cond || ! reg_mentioned_p (target, cond)) return NULL; @@ -1671,7 +1671,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); + tmp = canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX, + false); if (!tmp) return NULL_RTX; @@ -1690,7 +1691,8 @@ noce_get_condition (rtx jump, rtx *earliest) 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); + tmp = canonicalize_condition (jump, cond, reverse, earliest, tmp, + false); if (!tmp) return NULL_RTX; diff --git a/gcc/loop-unswitch.c b/gcc/loop-unswitch.c index b7c7f2703852..c1971c6f4c0e 100644 --- a/gcc/loop-unswitch.c +++ b/gcc/loop-unswitch.c @@ -141,7 +141,7 @@ may_unswitch_on_p (struct loops *loops, basic_block bb, struct loop *loop, /* Condition must be invariant. We use just a stupid test of invariantness of the condition: all used regs must not be modified inside loop body. */ - test = get_condition (bb->end, NULL); + test = get_condition (bb->end, NULL, true); if (!test) return false; @@ -248,7 +248,7 @@ unswitch_single_loop (struct loops *loops, struct loop *loop, return; } - if (!(cond = get_condition (bbs[i]->end, &split_before))) + if (!(cond = get_condition (bbs[i]->end, &split_before, true))) abort (); rcond = reversed_condition (cond); diff --git a/gcc/loop.c b/gcc/loop.c index 2866ce0cb4b7..9d41e071d1f7 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -7980,7 +7980,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); + get_condition (jump, &first_compare, false); if (first_compare == jump) compare_and_branch = 1; else if (first_compare == prev_nonnote_insn (jump)) @@ -9143,11 +9143,12 @@ 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. */ + further. If ALLOW_CC_MODE is nonzero, allow the condition returned + to be a compare to a CC mode register. */ rtx canonicalize_condition (rtx insn, rtx cond, int reverse, rtx *earliest, - rtx want_reg) + rtx want_reg, int allow_cc_mode) { enum rtx_code code; rtx prev = insn; @@ -9326,14 +9327,16 @@ canonicalize_condition (rtx insn, rtx cond, int reverse, rtx *earliest, /* If OP0 is the result of a comparison, we weren't able to find what was really being compared, so fail. */ - if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC) + if (!allow_cc_mode + && GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC) return 0; /* Canonicalize any ordered comparison with integers involving equality if we can do computations in the relevant mode and we do not overflow. */ - if (GET_CODE (op1) == CONST_INT + if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_CC + && GET_CODE (op1) == CONST_INT && GET_MODE (op0) != VOIDmode && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT) { @@ -9388,10 +9391,13 @@ 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 ALLOW_CC_MODE is nonzero, allow the condition returned to be a + compare CC mode register. */ rtx -get_condition (rtx jump, rtx *earliest) +get_condition (rtx jump, rtx *earliest, int allow_cc_mode) { rtx cond; int reverse; @@ -9411,7 +9417,8 @@ get_condition (rtx jump, rtx *earliest) = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump); - return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX); + return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX, + allow_cc_mode); } /* Similar to above routine, except that we also put an invariant last @@ -9420,7 +9427,7 @@ get_condition (rtx jump, rtx *earliest) rtx get_condition_for_loop (const struct loop *loop, rtx x) { - rtx comparison = get_condition (x, (rtx*) 0); + rtx comparison = get_condition (x, (rtx*) 0, false); if (comparison == 0 || ! loop_invariant_p (loop, XEXP (comparison, 0)) diff --git a/gcc/predict.c b/gcc/predict.c index e42eed04f1e3..243c814775d5 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -522,7 +522,7 @@ estimate_probability (struct loops *loops_info) } } - cond = get_condition (last_insn, &earliest); + cond = get_condition (last_insn, &earliest, false); if (! cond) continue; @@ -678,7 +678,7 @@ 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); + cond = canonicalize_condition (insn, cond, 0, NULL, ev_reg, false); if (! cond || XEXP (cond, 0) != ev_reg || GET_CODE (XEXP (cond, 1)) != CONST_INT) continue;