diff -ur gcc-4.1-20070514.orig/gcc/loop.c gcc-4.1-20070514/gcc/loop.c --- gcc-4.1-20070514.orig/gcc/loop.c 2007-05-08 15:00:35.000000000 +0200 +++ gcc-4.1-20070514/gcc/loop.c 2007-05-19 11:11:11.000000000 +0200 @@ -746,6 +746,20 @@ && INSN_LUID (INSN) >= INSN_LUID (START) \ && INSN_LUID (INSN) <= INSN_LUID (END)) +/* Good completeness of 6 predicates that combine the logic of tests of + 3 values 0, 1 and 2 from the return of loop_invariant_p (..) + and consec_sets_invariant_p (..) functions. + It's more legible and less confuse to understand it than before. + Be careful when extends it, if has more than 3 values then modify and + add the predicates adequately. + For more info, to see http://gcc.gnu.org/ml/gcc/2007-05/msg00451.html */ +#define IS_NOT_INVARIANT_OF_LOOP_P(x) ((x) == 0) +#define IS_INVARIANT_INCONDITIONAL_OF_LOOP_P(x) ((x) == 1) +#define IS_INVARIANT_CONDITIONAL_OF_LOOP_P(x) ((x) == 2) +#define IS_NOT_INVARIANT__OR_INVARIANT_INCONDITIONAL_OF_LOOP_P(x) ((x) != 2) +#define IS_NOT_INVARIANT__OR_INVARIANT_CONDITIONAL_OF_LOOP_P(x) ((x) != 1) +#define IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P(x) ((x) != 0) + /* Indirect_jump_in_function is computed once per function. */ static int indirect_jump_in_function; static int indirect_jump_in_function_p (rtx); @@ -1249,23 +1263,24 @@ && LEGITIMATE_CONSTANT_P (SET_SRC (set))) || REGNO (SET_DEST (set)) < FIRST_PSEUDO_REGISTER)) ; - else if ((tem = loop_invariant_p (loop, src)) - && (dependencies == 0 - || (tem2 - = loop_invariant_p (loop, dependencies)) != 0) - && (regs->array[REGNO (SET_DEST (set))].set_in_loop == 1 - || (tem1 - = consec_sets_invariant_p - (loop, SET_DEST (set), - regs->array[REGNO (SET_DEST (set))].set_in_loop, - p))) + else if (IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P ( + tem = loop_invariant_p (loop, src)) + && (dependencies == 0 + || IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P ( + tem2 = loop_invariant_p (loop, dependencies))) + && (regs->array[REGNO (SET_DEST (set))].set_in_loop == 1 + || (IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P ( + tem1 = consec_sets_invariant_p ( + loop, SET_DEST (set), + regs->array[REGNO (SET_DEST (set))].set_in_loop, + p)))) /* If the insn can cause a trap (such as divide by zero), can't move it unless it's guaranteed to be executed once loop is entered. Even a function call might prevent the trap insn from being reached (since it might exit!) */ - && ! ((maybe_never || call_passed) - && may_trap_p (src))) + && ! ((maybe_never || call_passed) + && may_trap_p (src))) { struct movable *m; int regno = REGNO (SET_DEST (set)); @@ -1350,7 +1365,9 @@ /* Set M->cond if either loop_invariant_p or consec_sets_invariant_p returned 2 (only conditionally invariant). */ - m->cond = ((tem | tem1 | tem2) > 1); + m->cond = IS_INVARIANT_CONDITIONAL_OF_LOOP_P (tem) + || IS_INVARIANT_CONDITIONAL_OF_LOOP_P (tem1) + || IS_INVARIANT_CONDITIONAL_OF_LOOP_P (tem2); m->global = LOOP_REG_GLOBAL_P (loop, regno); m->match = 0; m->lifetime = LOOP_REG_LIFETIME (loop, regno); @@ -2225,13 +2242,16 @@ if (!m->done && (! m->cond - || (1 == loop_invariant_p (loop, m->set_src) + || (IS_INVARIANT_INCONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, m->set_src)) && (m->dependencies == 0 - || 1 == loop_invariant_p (loop, m->dependencies)) + || IS_INVARIANT_INCONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, m->dependencies))) && (m->consec == 0 - || 1 == consec_sets_invariant_p (loop, m->set_dest, - m->consec + 1, - m->insn)))) + || IS_INVARIANT_INCONDITIONAL_OF_LOOP_P ( + consec_sets_invariant_p (loop, m->set_dest, + m->consec + 1, + m->insn))))) && (! m->forces || m->forces->done)) { int regno; @@ -2561,7 +2581,8 @@ like this as a result of record_jump_cond. */ if ((temp = find_reg_note (i1, REG_EQUAL, NULL_RTX)) - && loop_invariant_p (loop, XEXP (temp, 0)) != 1) + && IS_NOT_INVARIANT__OR_INVARIANT_CONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, XEXP (temp, 0)))) remove_note (i1, temp); } @@ -2824,7 +2845,8 @@ return 0; case MEM: - return ((loop_invariant_p (loop, XEXP (x, 0)) != 1) + return (IS_NOT_INVARIANT__OR_INVARIANT_CONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, XEXP (x, 0))) + count_nonfixed_reads (loop, XEXP (x, 0))); default: @@ -3698,9 +3720,9 @@ if (fmt[i] == 'e') { int tem = loop_invariant_p (loop, XEXP (x, i)); - if (tem == 0) + if (IS_NOT_INVARIANT_OF_LOOP_P (tem)) return 0; - if (tem == 2) + if (IS_INVARIANT_CONDITIONAL_OF_LOOP_P (tem)) conditional = 1; } else if (fmt[i] == 'E') @@ -3709,9 +3731,9 @@ for (j = 0; j < XVECLEN (x, i); j++) { int tem = loop_invariant_p (loop, XVECEXP (x, i, j)); - if (tem == 0) + if (IS_NOT_INVARIANT_OF_LOOP_P (tem)) return 0; - if (tem == 2) + if (IS_INVARIANT_CONDITIONAL_OF_LOOP_P (tem)) conditional = 1; } @@ -3743,7 +3765,7 @@ int count = n_sets - 1; int old = regs->array[regno].set_in_loop; int value = 0; - int this; + int thisThing; // warn! 'this' is a reserved word of C++, so renamed. /* If N_SETS hit the limit, we can't rely on its value. */ if (n_sets == 127) @@ -3763,28 +3785,30 @@ if (code == INSN && (temp = find_reg_note (p, REG_LIBCALL, NULL_RTX))) p = XEXP (temp, 0); - this = 0; + thisThing = 0; if (code == INSN && (set = single_set (p)) && REG_P (SET_DEST (set)) && REGNO (SET_DEST (set)) == regno) { - this = loop_invariant_p (loop, SET_SRC (set)); - if (this != 0) - value |= this; + thisThing = loop_invariant_p (loop, SET_SRC (set)); + if (IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P (thisThing)) + value |= thisThing; else if ((temp = find_reg_note (p, REG_EQUAL, NULL_RTX))) { /* If this is a libcall, then any invariant REG_EQUAL note is OK. If this is an ordinary insn, then only CONSTANT_P REG_EQUAL notes are OK. */ - this = (CONSTANT_P (XEXP (temp, 0)) + thisThing = (CONSTANT_P (XEXP (temp, 0)) || (find_reg_note (p, REG_RETVAL, NULL_RTX) - && loop_invariant_p (loop, XEXP (temp, 0)))); - if (this != 0) - value |= this; + && IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, XEXP (temp, 0))))); + if (IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P ( + thisThing)) + value |= thisThing; } } - if (this != 0) + if (IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P (thisThing)) count--; else if (code != NOTE) { @@ -4257,7 +4281,8 @@ /* Ignore GIVs with varying add values; we can't predict the value for the next iteration. */ - else if (!loop_invariant_p (loop, iv->add_val)) + else if (IS_NOT_INVARIANT_OF_LOOP_P ( + loop_invariant_p (loop, iv->add_val))) ignore_reason = "giv has varying add value"; /* Ignore GIVs in the nested loops; they ought to have been @@ -5169,11 +5194,13 @@ if (n_iterations != 0 && ! loop->exit_count - && loop_invariant_p (loop, bl->initial_value)) + && IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, bl->initial_value))) { increment = biv_total_increment (bl); - if (increment && loop_invariant_p (loop, increment)) + if (increment && IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, increment))) { /* Can calculate the loop exit value, emit insns after loop end to calculate this value into a temporary register in @@ -6078,13 +6105,14 @@ final_value = comparison_value; if (REG_P (comparison_value) - && loop_invariant_p (loop, comparison_value)) + && IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, comparison_value))) { final_value = loop_find_equiv_value (loop, comparison_value); /* If we don't get an invariant final value, we are better off with the original register. */ - if (! loop_invariant_p (loop, final_value)) + if (IS_NOT_INVARIANT_OF_LOOP_P (loop_invariant_p (loop, final_value))) final_value = comparison_value; } @@ -6146,7 +6174,8 @@ if (find_common_reg_term (temp, reg2)) initial_value = temp; - else if (loop_invariant_p (loop, reg2)) + else if (IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, reg2))) { /* Find what reg2 is equivalent to. Hopefully it will either be reg1 or reg1 plus a constant. Let's ignore @@ -7223,8 +7252,11 @@ increment = biv_total_increment (bl); - if (increment && loop_invariant_p (loop, increment) - && loop_invariant_p (loop, bl->initial_value)) + if (increment + && IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, increment)) + && IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, bl->initial_value))) { /* Can calculate the loop exit value of its biv as (n_iterations * increment) + initial_value */ @@ -7616,7 +7648,8 @@ return 0; arg = *argp; - if (loop_invariant_p (loop, arg) != 1) + if (IS_NOT_INVARIANT__OR_INVARIANT_CONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, arg))) return 0; /* convert_modes can emit new instructions, e.g. when arg is a loop @@ -7710,7 +7743,8 @@ as a biv of the outer loop, causing code to be moved INTO the inner loop. */ case MEM: - if (loop_invariant_p (loop, x) != 1) + if (IS_NOT_INVARIANT__OR_INVARIANT_CONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, x))) return 0; case CONST_INT: case SYMBOL_REF: @@ -7821,7 +7855,7 @@ rtx orig_x = x; /* If this is an invariant, forget it, it isn't a giv. */ - if (loop_invariant_p (loop, x) == 1) + if (IS_INVARIANT_INCONDITIONAL_OF_LOOP_P (loop_invariant_p (loop, x))) return 0; *pbenefit = 0; @@ -8242,7 +8276,7 @@ /* If it isn't an induction variable, and it is invariant, we may be able to simplify things further by looking through the bits we just moved outside the loop. */ - if (loop_invariant_p (loop, x) == 1) + if (IS_INVARIANT_INCONDITIONAL_OF_LOOP_P (loop_invariant_p (loop, x))) { struct movable *m; struct loop_movables *movables = LOOP_MOVABLES (loop); @@ -8323,7 +8357,7 @@ if (GET_CODE (x) == USE) x = XEXP (x, 0); - if (loop_invariant_p (loop, x) == 1) + if (IS_INVARIANT_INCONDITIONAL_OF_LOOP_P (loop_invariant_p (loop, x))) { if (GET_CODE (x) == CONST_INT) return x; @@ -8841,7 +8875,8 @@ if (mode == GET_MODE (bl->biv->src_reg) && bl->biv->src_reg == loop_info->iteration_var && loop_info->comparison_value - && loop_invariant_p (loop, loop_info->comparison_value)) + && IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, loop_info->comparison_value))) { /* If the increment is +1, and the exit test is a <, the BIV cannot overflow. (For <=, we have the problematic case that @@ -9783,7 +9818,8 @@ ??? If the insns which initialize the comparison value as a whole compute an invariant result, then we could move them out of the loop and proceed with loop reversal. */ - if (! loop_invariant_p (loop, comparison_value)) + if (IS_NOT_INVARIANT_OF_LOOP_P ( + loop_invariant_p (loop, comparison_value))) return 0; if (GET_CODE (comparison_value) == CONST_INT) @@ -10507,8 +10543,10 @@ rtx comparison = get_condition (x, (rtx*) 0, false, true); if (comparison == 0 - || ! loop_invariant_p (loop, XEXP (comparison, 0)) - || loop_invariant_p (loop, XEXP (comparison, 1))) + || IS_NOT_INVARIANT_OF_LOOP_P ( + loop_invariant_p (loop, XEXP (comparison, 0))) + || IS_INVARIANT_INCONDITIONAL_OR_CONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, XEXP (comparison, 1)))) return comparison; return gen_rtx_fmt_ee (swap_condition (GET_CODE (comparison)), VOIDmode, @@ -10846,7 +10884,8 @@ rtx mem_list_entry; if (MEM_VOLATILE_P (mem) - || loop_invariant_p (loop, XEXP (mem, 0)) != 1) + || IS_NOT_INVARIANT__OR_INVARIANT_CONDITIONAL_OF_LOOP_P ( + loop_invariant_p (loop, XEXP (mem, 0)))) /* There's no telling whether or not MEM is modified. */ loop_info->mems[i].optimize = 0;