diff options
author | Michael Hayes <m.hayes@elec.canterbury.ac.nz> | 2000-01-25 22:49:56 +0000 |
---|---|---|
committer | Michael Hayes <m.hayes@gcc.gnu.org> | 2000-01-25 22:49:56 +0000 |
commit | 0534b8047e8a12c4748f70a7bbb3267319c21216 (patch) | |
tree | 485accfbaa9a9a0c623a1a52c041fc3b441001ea /gcc/unroll.c | |
parent | 8e46653128e8fdebfd07d72f8190cea7b632bec6 (diff) | |
download | gcc-0534b8047e8a12c4748f70a7bbb3267319c21216.zip gcc-0534b8047e8a12c4748f70a7bbb3267319c21216.tar.gz gcc-0534b8047e8a12c4748f70a7bbb3267319c21216.tar.bz2 |
loop.c (current_loop_info): Delete.
2000-01-26 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
* loop.c (current_loop_info): Delete.
(consec_sets_invariant_p): Add loop argument, update callers.
(get_condition_for_loop): Likewise.
(count_nonfixed_reads, update_giv_derive): Likewise.
(simplify_giv_expr, general_induction_var): Likewise.
(consec_sets_giv, recombine_givs): Likewise.
(move_movables): Delete loop_start and loop_end arguments,
add loop argument, and update callers.
(find_mem_givs, check_final_value): Likewise.
(record_giv, maybe_eliminate_biv, maybe_eliminate_biv_1): Likewise.
(loop_invariant_p): Rename from invariant_p, add loop argument, and
update callers.
(basic_induction_var): Add loop argument, delete loop_level argument,
and update callers.
* unroll.c (iteration_info): Delete loop_start and loop_end arguments,
add loop argument, and update callers.
(find_splittable_regs, find_splittable_givs): Likewise.
(reg_dead_after_loop, loop_find_equiv_value): Likewise.
(final_biv_value, final_giv_value, back_branch_in_range_p): Likewise.
(biv_total_increment): Delete loop_start and loop_end arguments;
update callers.
(precondition_loop_p): Delete loop_start and loop_info arguments;
update callers.
* loop.h (get_condition_for_loop): Add loop argument.
(biv_total_increment): Delete loop_start and loop_end arguments.
(precondition_loop_p): Delete loop_start and loop_info arguments;
add loop argument.
(final_biv_value): Delete loop_start and loop_end arguments;
add loop argument.
(final_giv_value, back_branch_in_range_p): Likewise.
From-SVN: r31618
Diffstat (limited to 'gcc/unroll.c')
-rw-r--r-- | gcc/unroll.c | 205 |
1 files changed, 104 insertions, 101 deletions
diff --git a/gcc/unroll.c b/gcc/unroll.c index f325cea..7f3658e 100644 --- a/gcc/unroll.c +++ b/gcc/unroll.c @@ -200,26 +200,27 @@ static rtx initial_reg_note_copy PARAMS ((rtx, struct inline_remap *)); static void final_reg_note_copy PARAMS ((rtx, struct inline_remap *)); static void copy_loop_body PARAMS ((rtx, rtx, struct inline_remap *, rtx, int, enum unroll_types, rtx, rtx, rtx, rtx)); -static void iteration_info PARAMS ((rtx, rtx *, rtx *, rtx, rtx)); -static int find_splittable_regs PARAMS ((enum unroll_types, rtx, rtx, rtx, int, - unsigned HOST_WIDE_INT)); -static int find_splittable_givs PARAMS ((struct iv_class *, enum unroll_types, - rtx, rtx, rtx, int)); -static int reg_dead_after_loop PARAMS ((rtx, rtx, rtx)); +static void iteration_info PARAMS ((const struct loop *, rtx, rtx *, rtx *)); +static int find_splittable_regs PARAMS ((const struct loop *, + enum unroll_types, rtx, int)); +static int find_splittable_givs PARAMS ((const struct loop *, + struct iv_class *, enum unroll_types, + rtx, int)); +static int reg_dead_after_loop PARAMS ((const struct loop *, rtx)); static rtx fold_rtx_mult_add PARAMS ((rtx, rtx, rtx, enum machine_mode)); static int verify_addresses PARAMS ((struct induction *, rtx, int)); static rtx remap_split_bivs PARAMS ((rtx)); static rtx find_common_reg_term PARAMS ((rtx, rtx)); static rtx subtract_reg_term PARAMS ((rtx, rtx)); -static rtx loop_find_equiv_value PARAMS ((rtx, rtx)); +static rtx loop_find_equiv_value PARAMS ((const struct loop *, rtx)); /* Try to unroll one loop and split induction variables in the loop. - The loop is described by the arguments LOOP_END, INSN_COUNT, and - LOOP_START. END_INSERT_BEFORE indicates where insns should be added - which need to be executed when the loop falls through. STRENGTH_REDUCTION_P - indicates whether information generated in the strength reduction pass - is available. + The loop is described by the arguments LOOP and INSN_COUNT. + END_INSERT_BEFORE indicates where insns should be added which need + to be executed when the loop falls through. STRENGTH_REDUCTION_P + indicates whether information generated in the strength reduction + pass is available. This function is intended to be called from within `strength_reduce' in loop.c. */ @@ -894,7 +895,7 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p) rtx initial_value, final_value, increment; enum machine_mode mode; - if (precondition_loop_p (loop_start, loop_info, + if (precondition_loop_p (loop, &initial_value, &final_value, &increment, &mode)) { @@ -1158,9 +1159,8 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p) if (splitting_not_safe) temp = 0; else - temp = find_splittable_regs (unroll_type, loop_start, loop_end, - end_insert_before, unroll_number, - loop_info->n_iterations); + temp = find_splittable_regs (loop, unroll_type, + end_insert_before, unroll_number); /* find_splittable_regs may have created some new registers, so must reallocate the reg_map with the new larger size, and must realloc @@ -1356,13 +1356,13 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p) reflected in RTX_COST. */ int -precondition_loop_p (loop_start, loop_info, - initial_value, final_value, increment, mode) - rtx loop_start; - struct loop_info *loop_info; +precondition_loop_p (loop, initial_value, final_value, increment, mode) + const struct loop *loop; rtx *initial_value, *final_value, *increment; enum machine_mode *mode; { + rtx loop_start = loop->start; + struct loop_info *loop_info = LOOP_INFO (loop); if (loop_info->n_iterations > 0) { @@ -1423,16 +1423,16 @@ precondition_loop_p (loop_start, loop_info, return 0; } - /* Must ensure that final_value is invariant, so call invariant_p to - check. Before doing so, must check regno against max_reg_before_loop - to make sure that the register is in the range covered by invariant_p. - If it isn't, then it is most likely a biv/giv which by definition are - not invariant. */ + /* Must ensure that final_value is invariant, so call + loop_invariant_p to check. Before doing so, must check regno + against max_reg_before_loop to make sure that the register is in + the range covered by loop_invariant_p. If it isn't, then it is + most likely a biv/giv which by definition are not invariant. */ if ((GET_CODE (loop_info->final_value) == REG && REGNO (loop_info->final_value) >= max_reg_before_loop) || (GET_CODE (loop_info->final_value) == PLUS && REGNO (XEXP (loop_info->final_value, 0)) >= max_reg_before_loop) - || ! invariant_p (loop_info->final_value)) + || ! loop_invariant_p (loop, loop_info->final_value)) { if (loop_dump_stream) fprintf (loop_dump_stream, @@ -2288,21 +2288,23 @@ emit_unrolled_add (dest_reg, src_reg, increment) emit_move_insn (dest_reg, result); } -/* Searches the insns between INSN and LOOP_END. Returns 1 if there +/* Searches the insns between INSN and LOOP->END. Returns 1 if there is a backward branch in that range that branches to somewhere between - LOOP_START and INSN. Returns 0 otherwise. */ + LOOP->START and INSN. Returns 0 otherwise. */ /* ??? This is quadratic algorithm. Could be rewritten to be linear. In practice, this is not a problem, because this function is seldom called, and uses a negligible amount of CPU time on average. */ int -back_branch_in_range_p (insn, loop_start, loop_end) +back_branch_in_range_p (loop, insn) + const struct loop *loop; rtx insn; - rtx loop_start, loop_end; { rtx p, q, target_insn; - rtx orig_loop_end = loop_end; + rtx loop_start = loop->start; + rtx loop_end = loop->end; + rtx orig_loop_end = loop->end; /* Stop before we get to the backward branch at the end of the loop. */ loop_end = prev_nonnote_insn (loop_end); @@ -2392,9 +2394,8 @@ fold_rtx_mult_add (mult1, mult2, add1, mode) if it can be calculated. Otherwise, returns 0. */ rtx -biv_total_increment (bl, loop_start, loop_end) +biv_total_increment (bl) struct iv_class *bl; - rtx loop_start ATTRIBUTE_UNUSED, loop_end ATTRIBUTE_UNUSED; { struct induction *v; rtx result; @@ -2427,14 +2428,11 @@ biv_total_increment (bl, loop_start, loop_end) be calculated. */ static void -iteration_info (iteration_var, initial_value, increment, loop_start, loop_end) +iteration_info (loop, iteration_var, initial_value, increment) + const struct loop *loop; rtx iteration_var, *initial_value, *increment; - rtx loop_start, loop_end; { struct iv_class *bl; -#if 0 - struct induction *v; -#endif /* Clear the result values, in case no answer can be found. */ *initial_value = 0; @@ -2484,7 +2482,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end) bl = reg_biv_class[REGNO (iteration_var)]; *initial_value = bl->initial_value; - *increment = biv_total_increment (bl, loop_start, loop_end); + *increment = biv_total_increment (bl); } else if (REG_IV_TYPE (REGNO (iteration_var)) == GENERAL_INDUCT) { @@ -2498,7 +2496,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end) /* Increment value is mult_val times the increment value of the biv. */ - *increment = biv_total_increment (bl, loop_start, loop_end); + *increment = biv_total_increment (bl); if (*increment) { struct induction *biv_inc; @@ -2564,13 +2562,11 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end) times, since multiplies by small integers (1,2,3,4) are very cheap. */ static int -find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before, - unroll_number, n_iterations) +find_splittable_regs (loop, unroll_type, end_insert_before, unroll_number) + const struct loop *loop; enum unroll_types unroll_type; - rtx loop_start, loop_end; rtx end_insert_before; int unroll_number; - unsigned HOST_WIDE_INT n_iterations; { struct iv_class *bl; struct induction *v; @@ -2578,13 +2574,15 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before, rtx biv_final_value; int biv_splittable; int result = 0; + rtx loop_start = loop->start; + rtx loop_end = loop->end; for (bl = loop_iv_list; bl; bl = bl->next) { /* Biv_total_increment must return a constant value, otherwise we can not calculate the split values. */ - increment = biv_total_increment (bl, loop_start, loop_end); + increment = biv_total_increment (bl); if (! increment || GET_CODE (increment) != CONST_INT) continue; @@ -2600,16 +2598,14 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before, biv_splittable = 1; biv_final_value = 0; if (unroll_type != UNROLL_COMPLETELY - && (uid_loop[INSN_UID (loop_start)]->exit_count - || unroll_type == UNROLL_NAIVE) + && (loop->exit_count || unroll_type == UNROLL_NAIVE) && (uid_luid[REGNO_LAST_UID (bl->regno)] >= INSN_LUID (loop_end) || ! bl->init_insn || INSN_UID (bl->init_insn) >= max_uid_for_loop || (uid_luid[REGNO_FIRST_UID (bl->regno)] < INSN_LUID (bl->init_insn)) || reg_mentioned_p (bl->biv->dest_reg, SET_SRC (bl->init_set))) - && ! (biv_final_value = final_biv_value (bl, loop_start, loop_end, - n_iterations))) + && ! (biv_final_value = final_biv_value (loop, bl))) biv_splittable = 0; /* If any of the insns setting the BIV don't do so with a simple @@ -2641,7 +2637,7 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before, if (GET_CODE (bl->initial_value) == REG && (REGNO (bl->initial_value) == bl->regno || REGNO (bl->initial_value) < FIRST_PSEUDO_REGISTER - || ! invariant_p (bl->initial_value))) + || ! loop_invariant_p (loop, bl->initial_value))) { rtx tem = gen_reg_rtx (bl->biv->mode); @@ -2677,8 +2673,8 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before, depend on it may be splittable if the biv is live outside the loop, and the givs aren't. */ - result += find_splittable_givs (bl, unroll_type, loop_start, loop_end, - increment, unroll_number); + result += find_splittable_givs (loop, bl, unroll_type, increment, + unroll_number); /* If final value is non-zero, then must emit an instruction which sets the value of the biv to the proper value. This is done after @@ -2690,7 +2686,7 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before, loop to ensure that it will always be executed no matter how the loop exits. Otherwise emit the insn after the loop, since this is slightly more efficient. */ - if (! uid_loop[INSN_UID (loop_start)]->exit_count) + if (! loop->exit_count) emit_insn_before (gen_move_insn (bl->biv->src_reg, biv_final_value), end_insert_before); @@ -2758,11 +2754,10 @@ verify_addresses (v, giv_inc, unroll_number) Return the number of instructions that set splittable registers. */ static int -find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, - unroll_number) +find_splittable_givs (loop, bl, unroll_type, increment, unroll_number) + const struct loop *loop; struct iv_class *bl; enum unroll_types unroll_type; - rtx loop_start, loop_end; rtx increment; int unroll_number; { @@ -2796,7 +2791,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, won't reach here if they aren't. */ if (v->giv_type != DEST_ADDR && (! v->always_computable - || back_branch_in_range_p (v->insn, loop_start, loop_end))) + || back_branch_in_range_p (loop, v->insn))) continue; /* The giv increment value must be a constant. */ @@ -2817,8 +2812,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, final_value = 0; if (unroll_type != UNROLL_COMPLETELY - && (uid_loop[INSN_UID (loop_start)]->exit_count - || unroll_type == UNROLL_NAIVE) + && (loop->exit_count || unroll_type == UNROLL_NAIVE) && v->giv_type != DEST_ADDR /* The next part is true if the pseudo is used outside the loop. We assume that this is true for any pseudo created after loop @@ -2833,7 +2827,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, != INSN_UID (XEXP (tem, 0))))) /* Line above always fails if INSN was moved by loop opt. */ || (uid_luid[REGNO_LAST_UID (REGNO (v->dest_reg))] - >= INSN_LUID (loop_end))) + >= INSN_LUID (loop->end))) /* Givs made from biv increments are missed by the above test, so test explicitly for them. */ && (REGNO (v->dest_reg) < first_increment_giv @@ -2891,7 +2885,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, record_base_value (REGNO (tem), bl->biv->add_val, 0); emit_insn_before (gen_move_insn (tem, bl->biv->src_reg), - loop_start); + loop->start); biv_initial_value = tem; } value = fold_rtx_mult_add (v->mult_val, biv_initial_value, @@ -2933,7 +2927,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, rtx tem = gen_reg_rtx (v->mode); record_base_value (REGNO (tem), v->add_val, 0); emit_iv_add_mult (bl->initial_value, v->mult_val, - v->add_val, tem, loop_start); + v->add_val, tem, loop->start); value = tem; } @@ -3082,8 +3076,8 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, to calculate the value from scratch. */ emit_insn_before (gen_rtx_SET (VOIDmode, tem, copy_rtx (v->new_reg)), - loop_start); - if (recog_memoized (PREV_INSN (loop_start)) < 0) + loop->start); + if (recog_memoized (PREV_INSN (loop->start)) < 0) { rtx sequence, ret; @@ -3091,7 +3085,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, value, because the loop may have been preconditioned. We must calculate it from NEW_REG. Try using force_operand instead of emit_iv_add_mult. */ - delete_insn (PREV_INSN (loop_start)); + delete_insn (PREV_INSN (loop->start)); start_sequence (); ret = force_operand (v->new_reg, tem); @@ -3099,7 +3093,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, emit_move_insn (tem, ret); sequence = gen_sequence (); end_sequence (); - emit_insn_before (sequence, loop_start); + emit_insn_before (sequence, loop->start); if (loop_dump_stream) fprintf (loop_dump_stream, @@ -3238,14 +3232,14 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, it can search past if statements and other similar structures. */ static int -reg_dead_after_loop (reg, loop_start, loop_end) - rtx reg, loop_start, loop_end; +reg_dead_after_loop (loop, reg) + const struct loop *loop; + rtx reg; { rtx insn, label; enum rtx_code code; int jump_count = 0; int label_count = 0; - struct loop *loop = uid_loop[INSN_UID (loop_start)]; /* In addition to checking all exits of this loop, we must also check all exits of inner nested loops that would exit this loop. We don't @@ -3259,9 +3253,9 @@ reg_dead_after_loop (reg, loop_start, loop_end) return 0; /* HACK: Must also search the loop fall through exit, create a label_ref - here which points to the loop_end, and append the loop_number_exit_labels + here which points to the loop->end, and append the loop_number_exit_labels list to it. */ - label = gen_rtx_LABEL_REF (VOIDmode, loop_end); + label = gen_rtx_LABEL_REF (VOIDmode, loop->end); LABEL_NEXTREF (label) = loop->exit_labels; for ( ; label; label = LABEL_NEXTREF (label)) @@ -3310,11 +3304,12 @@ reg_dead_after_loop (reg, loop_start, loop_end) the end of the loop. If we can do it, return that value. */ rtx -final_biv_value (bl, loop_start, loop_end, n_iterations) +final_biv_value (loop, bl) + const struct loop *loop; struct iv_class *bl; - rtx loop_start, loop_end; - unsigned HOST_WIDE_INT n_iterations; { + rtx loop_end = loop->end; + unsigned HOST_WIDE_INT n_iterations = LOOP_INFO (loop)->n_iterations; rtx increment, tem; /* ??? This only works for MODE_INT biv's. Reject all others for now. */ @@ -3342,12 +3337,12 @@ final_biv_value (bl, loop_start, loop_end, n_iterations) value of the biv must be invariant. */ if (n_iterations != 0 - && ! uid_loop[INSN_UID (loop_start)]->exit_count - && invariant_p (bl->initial_value)) + && ! loop->exit_count + && loop_invariant_p (loop, bl->initial_value)) { - increment = biv_total_increment (bl, loop_start, loop_end); + increment = biv_total_increment (bl); - if (increment && invariant_p (increment)) + if (increment && 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 @@ -3370,7 +3365,7 @@ final_biv_value (bl, loop_start, loop_end, n_iterations) } /* Check to see if the biv is dead at all loop exits. */ - if (reg_dead_after_loop (bl->biv->src_reg, loop_start, loop_end)) + if (reg_dead_after_loop (loop, bl->biv->src_reg)) { if (loop_dump_stream) fprintf (loop_dump_stream, @@ -3387,15 +3382,16 @@ final_biv_value (bl, loop_start, loop_end, n_iterations) the end of the loop. If we can do it, return that value. */ rtx -final_giv_value (v, loop_start, loop_end, n_iterations) +final_giv_value (loop, v) + const struct loop *loop; struct induction *v; - rtx loop_start, loop_end; - unsigned HOST_WIDE_INT n_iterations; { struct iv_class *bl; rtx insn; rtx increment, tem; rtx insert_before, seq; + rtx loop_end = loop->end; + unsigned HOST_WIDE_INT n_iterations = LOOP_INFO (loop)->n_iterations; bl = reg_biv_class[REGNO (v->src_reg)]; @@ -3422,7 +3418,7 @@ final_giv_value (v, loop_start, loop_end, n_iterations) to be known. */ if (n_iterations != 0 - && ! uid_loop[INSN_UID (loop_start)]->exit_count) + && ! loop->exit_count) { /* ?? It is tempting to use the biv's value here since these insns will be put after the loop, and hence the biv will have its final value @@ -3435,10 +3431,10 @@ final_giv_value (v, loop_start, loop_end, n_iterations) sure that bl->initial_value is still valid then. It will still be valid if it is invariant. */ - increment = biv_total_increment (bl, loop_start, loop_end); + increment = biv_total_increment (bl); - if (increment && invariant_p (increment) - && invariant_p (bl->initial_value)) + if (increment && loop_invariant_p (loop, increment) + && loop_invariant_p (loop, bl->initial_value)) { /* Can calculate the loop exit value of its biv as (n_iterations * increment) + initial_value */ @@ -3495,7 +3491,7 @@ final_giv_value (v, loop_start, loop_end, n_iterations) abort (); /* Check to see if the biv is dead at all loop exits. */ - if (reg_dead_after_loop (v->dest_reg, loop_start, loop_end)) + if (reg_dead_after_loop (loop, v->dest_reg)) { if (loop_dump_stream) fprintf (loop_dump_stream, @@ -3509,15 +3505,16 @@ final_giv_value (v, loop_start, loop_end, n_iterations) } -/* Look back before LOOP_START for then insn that sets REG and return +/* Look back before LOOP->START for then insn that sets REG and return the equivalent constant if there is a REG_EQUAL note otherwise just the SET_SRC of REG. */ static rtx -loop_find_equiv_value (loop_start, reg) - rtx loop_start; +loop_find_equiv_value (loop, reg) + const struct loop *loop; rtx reg; { + rtx loop_start = loop->start; rtx insn, set; rtx ret; @@ -3678,7 +3675,7 @@ loop_iterations (loop) branch, and the insn before tests a register value, make that the iteration variable. */ - comparison = get_condition_for_loop (last_loop_insn); + comparison = get_condition_for_loop (loop, last_loop_insn); if (comparison == 0) { if (loop_dump_stream) @@ -3712,8 +3709,8 @@ loop_iterations (loop) && ! REG_USERVAR_P (iteration_var)) abort (); - iteration_info (iteration_var, &initial_value, &increment, - loop->start, loop->end); + iteration_info (loop, iteration_var, &initial_value, &increment); + if (initial_value == 0) /* iteration_info already printed a message. */ return 0; @@ -3758,12 +3755,14 @@ loop_iterations (loop) its value from the insns before the start of the loop. */ final_value = comparison_value; - if (GET_CODE (comparison_value) == REG && invariant_p (comparison_value)) + if (GET_CODE (comparison_value) == REG + && loop_invariant_p (loop, comparison_value)) { - final_value = loop_find_equiv_value (loop->start, 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 (!invariant_p (final_value)) + if (! loop_invariant_p (loop, final_value)) final_value = comparison_value; } @@ -3820,7 +3819,8 @@ loop_iterations (loop) /* Find what reg1 is equivalent to. Hopefully it will either be reg2 or reg2 plus a constant. */ - temp = loop_find_equiv_value (loop->start, reg1); + temp = loop_find_equiv_value (loop, reg1); + if (find_common_reg_term (temp, reg2)) initial_value = temp; else @@ -3828,7 +3828,8 @@ loop_iterations (loop) /* Find what reg2 is equivalent to. Hopefully it will either be reg1 or reg1 plus a constant. Let's ignore the latter case for now since it is not so common. */ - temp = loop_find_equiv_value (loop->start, reg2); + temp = loop_find_equiv_value (loop, reg2); + if (temp == loop_info->iteration_var) temp = initial_value; if (temp == reg1) @@ -3847,10 +3848,12 @@ loop_iterations (loop) where temp2 = init + const. If the loop has a vtop we can replace initial_value with const. */ - temp = loop_find_equiv_value (loop->start, reg1); + temp = loop_find_equiv_value (loop, reg1); + if (GET_CODE (temp) == MINUS && REG_P (XEXP (temp, 0))) { - rtx temp2 = loop_find_equiv_value (loop->start, XEXP (temp, 0)); + rtx temp2 = loop_find_equiv_value (loop, XEXP (temp, 0)); + if (GET_CODE (temp2) == PLUS && XEXP (temp2, 0) == XEXP (temp, 1)) initial_value = XEXP (temp2, 1); @@ -3897,7 +3900,7 @@ loop_iterations (loop) /* ??? Other RTL, such as (neg (reg)) is possible here, but it isn't clear if it is worthwhile to try to handle such RTL. */ if (GET_CODE (increment) == REG || GET_CODE (increment) == SUBREG) - increment = loop_find_equiv_value (loop->start, increment); + increment = loop_find_equiv_value (loop, increment); if (GET_CODE (increment) != CONST_INT) { |