From 15fc3eb7a11e19596a10f536e7cc1119b13187da Mon Sep 17 00:00:00 2001 From: "m.hayes" Date: Tue, 25 Jan 2000 22:49:56 +0000 Subject: [PATCH] 2000-01-26 Michael Hayes * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31618 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 33 +++++ gcc/loop.c | 429 ++++++++++++++++++++++++++++++---------------------------- gcc/loop.h | 16 +-- gcc/unroll.c | 205 ++++++++++++++-------------- 4 files changed, 366 insertions(+), 317 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f0c10d9..f3c6842 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,36 @@ +2000-01-26 Michael Hayes + + * 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. + 2000-01-25 Gavin Romig-Koch * config/mips/mips.h (LEGITIMATE_CONSTANT_P): Fix for mips16. diff --git a/gcc/loop.c b/gcc/loop.c index b297504..283e219 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -53,11 +53,6 @@ Boston, MA 02111-1307, USA. */ #include "except.h" #include "toplev.h" -/* Information about the current loop being processed used to compute - the number of loop iterations for loop unrolling and doloop - optimization. */ -static struct loop_info *current_loop_info; - /* Vector mapping INSN_UIDs to luids. The luids are like uids but increase monotonically always. We use them to see whether a jump comes from outside a given loop. */ @@ -239,12 +234,13 @@ static void find_and_verify_loops PARAMS ((rtx, struct loops *)); static void mark_loop_jump PARAMS ((rtx, struct loop *)); static void prescan_loop PARAMS ((struct loop *)); static int reg_in_basic_block_p PARAMS ((rtx, rtx)); -static int consec_sets_invariant_p PARAMS ((rtx, int, rtx)); +static int consec_sets_invariant_p PARAMS ((const struct loop *, + rtx, int, rtx)); static int labels_in_range_p PARAMS ((rtx, int)); static void count_one_set PARAMS ((rtx, rtx, varray_type, rtx *)); static void count_loop_regs_set PARAMS ((rtx, rtx, varray_type, varray_type, - int *, int)); + int *, int)); static void note_addr_stored PARAMS ((rtx, rtx, void *)); static void note_set_pseudo_multiple_uses PARAMS ((rtx, rtx, void *)); static int loop_reg_used_before_p PARAMS ((const struct loop *, rtx, rtx)); @@ -260,37 +256,49 @@ static void combine_movables PARAMS ((struct movable *, int)); static int regs_match_p PARAMS ((rtx, rtx, struct movable *)); static int rtx_equal_for_loop_p PARAMS ((rtx, rtx, struct movable *)); static void add_label_notes PARAMS ((rtx, rtx)); -static void move_movables PARAMS ((struct movable *, int, int, rtx, rtx, int)); -static int count_nonfixed_reads PARAMS ((rtx)); +static void move_movables PARAMS ((struct loop *loop, struct movable *, + int, int, int)); +static int count_nonfixed_reads PARAMS ((const struct loop *, rtx)); static void strength_reduce PARAMS ((struct loop *, int, int, int)); static void find_single_use_in_loop PARAMS ((rtx, rtx, varray_type)); static int valid_initial_value_p PARAMS ((rtx, rtx, int, rtx)); -static void find_mem_givs PARAMS ((rtx, rtx, int, int, rtx, rtx)); -static void record_biv PARAMS ((struct induction *, rtx, rtx, rtx, rtx, rtx *, int, int, int)); -static void check_final_value PARAMS ((struct induction *, rtx, rtx, - unsigned HOST_WIDE_INT)); -static void record_giv PARAMS ((struct induction *, rtx, rtx, rtx, rtx, rtx, int, enum g_types, int, int, rtx *, rtx, rtx)); -static void update_giv_derive PARAMS ((rtx)); -static int basic_induction_var PARAMS ((rtx, enum machine_mode, rtx, rtx, int, rtx *, rtx *, rtx **, int *)); -static rtx simplify_giv_expr PARAMS ((rtx, int *)); -static int general_induction_var PARAMS ((rtx, rtx *, rtx *, rtx *, int, int *)); -static int consec_sets_giv PARAMS ((int, rtx, rtx, rtx, rtx *, rtx *, rtx *)); +static void find_mem_givs PARAMS ((const struct loop *, rtx, rtx, int, int)); +static void record_biv PARAMS ((struct induction *, rtx, rtx, rtx, rtx, rtx *, + int, int, int)); +static void check_final_value PARAMS ((const struct loop *, + struct induction *)); +static void record_giv PARAMS ((const struct loop *, struct induction *, + rtx, rtx, rtx, rtx, rtx, int, enum g_types, + int, int, rtx *)); +static void update_giv_derive PARAMS ((const struct loop *, rtx)); +static int basic_induction_var PARAMS ((const struct loop *, rtx, + enum machine_mode, rtx, rtx, + rtx *, rtx *, rtx **, int *)); +static rtx simplify_giv_expr PARAMS ((const struct loop *, rtx, int *)); +static int general_induction_var PARAMS ((const struct loop *loop, rtx, rtx *, + rtx *, rtx *, int, int *)); +static int consec_sets_giv PARAMS ((const struct loop *, int, rtx, + rtx, rtx, rtx *, rtx *, rtx *)); static int check_dbra_loop PARAMS ((struct loop *, int)); static rtx express_from_1 PARAMS ((rtx, rtx, rtx)); static rtx combine_givs_p PARAMS ((struct induction *, struct induction *)); static void combine_givs PARAMS ((struct iv_class *)); struct recombine_givs_stats; -static int find_life_end PARAMS ((rtx, struct recombine_givs_stats *, rtx, rtx)); -static void recombine_givs PARAMS ((struct iv_class *, rtx, rtx, int)); +static int find_life_end PARAMS ((rtx, struct recombine_givs_stats *, + rtx, rtx)); +static void recombine_givs PARAMS ((const struct loop *, struct iv_class *, + int)); static int product_cheap_p PARAMS ((rtx, rtx)); -static int maybe_eliminate_biv PARAMS ((struct iv_class *, rtx, rtx, int, int, int)); -static int maybe_eliminate_biv_1 PARAMS ((rtx, rtx, struct iv_class *, int, rtx)); +static int maybe_eliminate_biv PARAMS ((const struct loop *, struct iv_class *, + int, int, int)); +static int maybe_eliminate_biv_1 PARAMS ((const struct loop *, rtx, rtx, + struct iv_class *, int, rtx)); static int last_use_this_basic_block PARAMS ((rtx, rtx)); static void record_initial PARAMS ((rtx, rtx, void *)); static void update_reg_last_use PARAMS ((rtx, rtx)); static rtx next_insn_in_loop PARAMS ((const struct loop *, rtx)); static void load_mems_and_recount_loop_regs_set PARAMS ((const struct loop*, - int *)); + int *)); static void load_mems PARAMS ((const struct loop *)); static int insert_loop_mem PARAMS ((rtx *, void *)); static int replace_loop_mem PARAMS ((rtx *, void *)); @@ -546,7 +554,7 @@ loop_optimize (f, dumpfile, unroll_p, bct_p) /* Returns the next insn, in execution order, after INSN. START and END are the NOTE_INSN_LOOP_BEG and NOTE_INSN_LOOP_END for the loop, - respectively. LOOP_TOP, if non-NULL, is the top of the loop in the + respectively. LOOP->TOP, if non-NULL, is the top of the loop in the insn-stream; it is used with loops that are entered near the bottom. */ @@ -590,6 +598,9 @@ scan_loop (loop, unroll_p, bct_p) register int i; rtx loop_start = loop->start; rtx loop_end = loop->end; + /* Additional information about the current loop being processed + that is used to compute the number of loop iterations for loop + unrolling and doloop optimization. */ struct loop_info *loop_info = LOOP_INFO (loop); rtx p; /* 1 if we are scanning insns that could be executed zero times. */ @@ -619,7 +630,6 @@ scan_loop (loop, unroll_p, bct_p) int loop_depth = 0; int nregs; - current_loop_info = loop_info; loop->top = 0; /* Determine whether this loop starts with a jump down to a test at @@ -827,14 +837,14 @@ scan_loop (loop, unroll_p, bct_p) which was not created by the user and not used in an exit test. That behavior is incorrect and was removed. */ ; - else if ((tem = invariant_p (src)) + else if ((tem = loop_invariant_p (loop, src)) && (dependencies == 0 - || (tem2 = invariant_p (dependencies)) != 0) + || (tem2 = loop_invariant_p (loop, dependencies)) != 0) && (VARRAY_INT (set_in_loop, REGNO (SET_DEST (set))) == 1 || (tem1 = consec_sets_invariant_p - (SET_DEST (set), + (loop, SET_DEST (set), VARRAY_INT (set_in_loop, REGNO (SET_DEST (set))), p))) /* If the insn can cause a trap (such as divide by zero), @@ -1109,8 +1119,7 @@ scan_loop (loop, unroll_p, bct_p) optimizing for code size. */ if (! optimize_size) - move_movables (movables, threshold, - insn_count, loop_start, loop_end, nregs); + move_movables (loop, movables, threshold, insn_count, nregs); /* Now candidates that still are negative are those not moved. Change set_in_loop to indicate that those are not actually invariant. */ @@ -1123,7 +1132,8 @@ scan_loop (loop, unroll_p, bct_p) load_mems_and_recount_loop_regs_set (loop, &insn_count); for (update_start = loop_start; - PREV_INSN (update_start) && GET_CODE (PREV_INSN (update_start)) != CODE_LABEL; + PREV_INSN (update_start) + && GET_CODE (PREV_INSN (update_start)) != CODE_LABEL; update_start = PREV_INSN (update_start)) ; update_end = NEXT_INSN (loop_end); @@ -1702,17 +1712,18 @@ add_label_notes (x, insns) other throughout. */ static void -move_movables (movables, threshold, insn_count, loop_start, end, nregs) +move_movables (loop, movables, threshold, insn_count, nregs) + struct loop *loop; struct movable *movables; int threshold; int insn_count; - rtx loop_start; - rtx end; int nregs; { rtx new_start = 0; register struct movable *m; register rtx p; + rtx loop_start = loop->start; + rtx loop_end = loop->end; /* Map of pseudo-register replacements to handle combining when we move several insns that load the same value into different pseudo-registers. */ @@ -1757,11 +1768,11 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs) if (!m->done && (! m->cond - || (1 == invariant_p (m->set_src) + || (1 == loop_invariant_p (loop, m->set_src) && (m->dependencies == 0 - || 1 == invariant_p (m->dependencies)) + || 1 == loop_invariant_p (loop, m->dependencies)) && (m->consec == 0 - || 1 == consec_sets_invariant_p (m->set_dest, + || 1 == consec_sets_invariant_p (loop, m->set_dest, m->consec + 1, m->insn)))) && (! m->forces || m->forces->done)) @@ -2062,7 +2073,7 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs) like this as a result of record_jump_cond. */ if ((temp = find_reg_note (i1, REG_EQUAL, NULL_RTX)) - && ! invariant_p (XEXP (temp, 0))) + && ! loop_invariant_p (loop, XEXP (temp, 0))) remove_note (i1, temp); } @@ -2123,8 +2134,8 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs) We can't use the moved insn because it is out of range in uid_luid. Only the old insns have luids. */ REGNO_FIRST_UID (regno) = INSN_UID (loop_start); - if (uid_luid[REGNO_LAST_UID (regno)] < INSN_LUID (end)) - REGNO_LAST_UID (regno) = INSN_UID (end); + if (uid_luid[REGNO_LAST_UID (regno)] < INSN_LUID (loop_end)) + REGNO_LAST_UID (regno) = INSN_UID (loop_end); /* Combine with this moved insn any other matching movables. */ @@ -2192,7 +2203,7 @@ move_movables (movables, threshold, insn_count, loop_start, end, nregs) /* Go through all the instructions in the loop, making all the register substitutions scheduled in REG_MAP. */ - for (p = new_start; p != end; p = NEXT_INSN (p)) + for (p = new_start; p != loop_end; p = NEXT_INSN (p)) if (GET_CODE (p) == INSN || GET_CODE (p) == JUMP_INSN || GET_CODE (p) == CALL_INSN) { @@ -2274,7 +2285,8 @@ replace_call_address (x, reg, addr) in the rtx X. */ static int -count_nonfixed_reads (x) +count_nonfixed_reads (loop, x) + const struct loop *loop; rtx x; { register enum rtx_code code; @@ -2299,8 +2311,8 @@ count_nonfixed_reads (x) return 0; case MEM: - return ((invariant_p (XEXP (x, 0)) != 1) - + count_nonfixed_reads (XEXP (x, 0))); + return ((loop_invariant_p (loop, XEXP (x, 0)) != 1) + + count_nonfixed_reads (loop, XEXP (x, 0))); default: break; @@ -2311,12 +2323,12 @@ count_nonfixed_reads (x) for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') - value += count_nonfixed_reads (XEXP (x, i)); - else if (fmt[i] == 'E') + value += count_nonfixed_reads (loop, XEXP (x, i)); + if (fmt[i] == 'E') { register int j; for (j = 0; j < XVECLEN (x, i); j++) - value += count_nonfixed_reads (XVECEXP (x, i, j)); + value += count_nonfixed_reads (loop, XVECEXP (x, i, j)); } } return value; @@ -3189,7 +3201,8 @@ note_set_pseudo_multiple_uses (x, y, data) anything stored in `loop_store_mems'. */ int -invariant_p (x) +loop_invariant_p (loop, x) + const struct loop *loop; register rtx x; { register int i; @@ -3238,7 +3251,7 @@ invariant_p (x) && ! current_function_has_nonlocal_goto) return 1; - if (current_loop_info->has_call + if (LOOP_INFO (loop)->has_call && REGNO (x) < FIRST_PSEUDO_REGISTER && call_used_regs[REGNO (x)]) return 0; @@ -3292,7 +3305,7 @@ invariant_p (x) { if (fmt[i] == 'e') { - int tem = invariant_p (XEXP (x, i)); + int tem = loop_invariant_p (loop, XEXP (x, i)); if (tem == 0) return 0; if (tem == 2) @@ -3303,7 +3316,7 @@ invariant_p (x) register int j; for (j = 0; j < XVECLEN (x, i); j++) { - int tem = invariant_p (XVECEXP (x, i, j)); + int tem = loop_invariant_p (loop, XVECEXP (x, i, j)); if (tem == 0) return 0; if (tem == 2) @@ -3328,7 +3341,8 @@ invariant_p (x) and that its source is invariant. */ static int -consec_sets_invariant_p (reg, n_sets, insn) +consec_sets_invariant_p (loop, reg, n_sets, insn) + const struct loop *loop; int n_sets; rtx reg, insn; { @@ -3365,7 +3379,7 @@ consec_sets_invariant_p (reg, n_sets, insn) && GET_CODE (SET_DEST (set)) == REG && REGNO (SET_DEST (set)) == regno) { - this = invariant_p (SET_SRC (set)); + this = loop_invariant_p (loop, SET_SRC (set)); if (this != 0) value |= this; else if ((temp = find_reg_note (p, REG_EQUAL, NULL_RTX))) @@ -3375,7 +3389,7 @@ consec_sets_invariant_p (reg, n_sets, insn) notes are OK. */ this = (CONSTANT_P (XEXP (temp, 0)) || (find_reg_note (p, REG_RETVAL, NULL_RTX) - && invariant_p (XEXP (temp, 0)))); + && loop_invariant_p (loop, XEXP (temp, 0)))); if (this != 0) value |= this; } @@ -3390,7 +3404,7 @@ consec_sets_invariant_p (reg, n_sets, insn) } VARRAY_INT (set_in_loop, regno) = old; - /* If invariant_p ever returned 2, we return 2. */ + /* If loop_invariant_p ever returned 2, we return 2. */ return 1 + (value & 2); } @@ -3420,7 +3434,7 @@ all_sets_invariant_p (reg, insn, table) && GET_CODE (SET_DEST (PATTERN (p))) == REG && REGNO (SET_DEST (PATTERN (p))) == regno) { - if (!invariant_p (SET_SRC (PATTERN (p)), table)) + if (! loop_invariant_p (loop, SET_SRC (PATTERN (p)), table)) return 0; } } @@ -3575,11 +3589,10 @@ count_loop_regs_set (from, to, may_not_move, single_usage, count_ptr, nregs) free (last_set); } -/* Given a loop that is bounded by LOOP_START and LOOP_END - and that is entered at LOOP_SCAN_START, - return 1 if the register set in SET contained in insn INSN is used by - any insn that precedes INSN in cyclic order starting - from the loop entry point. +/* Given a loop that is bounded by LOOP->START and LOOP->END and that + is entered at LOOP->SCAN_START, return 1 if the register set in SET + contained in insn INSN is used by any insn that precedes INSN in + cyclic order starting from the loop entry point. We don't want to use INSN_LUID here because if we restrict INSN to those that have a valid INSN_LUID, it means we cannot move an invariant out @@ -3685,13 +3698,7 @@ static rtx addr_placeholder; valid index in several tables including n_times_set and regno_last_uid. This does not cause a problem here, because the added registers cannot be givs outside of their loop, and hence will never be reconsidered. - But scan_loop must check regnos to make sure they are in bounds. - - LOOP_SCAN_START is the first instruction in the loop, as the loop would - actually be executed. END is the NOTE_INSN_LOOP_END. LOOP_TOP is - the first instruction in the loop, as it is layed out in the - instruction stream. LOOP_START is the NOTE_INSN_LOOP_BEG. - LOOP_CONT is the NOTE_INSN_LOOP_CONT. */ + But scan_loop must check regnos to make sure they are in bounds. */ static void strength_reduce (loop, insn_count, unroll_p, bct_p) @@ -3741,7 +3748,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) /* If loop_scan_start points to the loop exit test, we have to be wary of subversive use of gotos inside expression statements. */ if (prev_nonnote_insn (loop_scan_start) != prev_nonnote_insn (loop_start)) - maybe_multiple = back_branch_in_range_p (loop_scan_start, loop_start, loop_end); + maybe_multiple = back_branch_in_range_p (loop, loop_scan_start); VARRAY_INT_INIT (reg_iv_type, max_reg_before_loop, "reg_iv_type"); VARRAY_GENERIC_PTR_INIT (reg_iv_info, max_reg_before_loop, "reg_iv_info"); @@ -3780,9 +3787,9 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) { int multi_insn_incr = 0; - if (basic_induction_var (SET_SRC (set), GET_MODE (SET_SRC (set)), - dest_reg, p, loop->level, - &inc_val, &mult_val, + if (basic_induction_var (loop, SET_SRC (set), + GET_MODE (SET_SRC (set)), + dest_reg, p, &inc_val, &mult_val, &location, &multi_insn_incr)) { /* It is a possible basic induction variable. @@ -3860,9 +3867,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) matter. Check to see if the target of this branch is on the loop->exits_labels list. */ - for (label = uid_loop[INSN_UID (loop_start)]->exit_labels; - label; - label = LABEL_NEXTREF (label)) + for (label = loop->exit_labels; label; label = LABEL_NEXTREF (label)) if (XEXP (label, 0) == JUMP_LABEL (p)) break; @@ -3999,7 +4004,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p) != 0 && next_real_insn (JUMP_LABEL (p)) == next_real_insn (loop_end) - && (test = get_condition_for_loop (p)) != 0 + && (test = get_condition_for_loop (loop, p)) != 0 && GET_CODE (XEXP (test, 0)) == REG && REGNO (XEXP (test, 0)) < max_reg_before_loop && (bl = reg_biv_class[REGNO (XEXP (test, 0))]) != 0 @@ -4080,8 +4085,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) && GET_CODE (src) == PLUS && GET_CODE (XEXP (src, 0)) == REG && CONSTANT_P (XEXP (src, 1)) - && ((increment = biv_total_increment (bl, loop_start, loop_end)) - != NULL_RTX)) + && ((increment = biv_total_increment (bl)) != NULL_RTX)) { int regno = REGNO (XEXP (src, 0)); @@ -4093,8 +4097,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) /* Now, can we transform this biv into a giv? */ if (bl2 && bl2->biv_count == 1 - && rtx_equal_p (increment, - biv_total_increment (bl2, loop_start, loop_end)) + && rtx_equal_p (increment, biv_total_increment (bl2)) /* init_insn is only set to insns that are before loop_start without any intervening labels. */ && ! reg_set_between_p (bl2->biv->src_reg, @@ -4114,7 +4117,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) &SET_SRC (single_set (bl->biv->insn)), copy_rtx (src), 0)) { - rtx dominator = uid_loop[INSN_UID (loop_start)]->cont_dominator; + rtx dominator = loop->cont_dominator; rtx giv = bl->biv->src_reg; rtx giv_insn = bl->biv->insn; rtx after_giv = NEXT_INSN (giv_insn); @@ -4467,11 +4470,11 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) continue; if (/* SET_SRC is a giv. */ - (general_induction_var (SET_SRC (set), &src_reg, &add_val, + (general_induction_var (loop, SET_SRC (set), &src_reg, &add_val, &mult_val, 0, &benefit) /* Equivalent expression is a giv. */ || ((regnote = find_reg_note (p, REG_EQUAL, NULL_RTX)) - && general_induction_var (XEXP (regnote, 0), &src_reg, + && general_induction_var (loop, XEXP (regnote, 0), &src_reg, &add_val, &mult_val, 0, &benefit))) /* Don't try to handle any regs made by loop optimization. @@ -4482,7 +4485,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) /* This must be the only place where the register is set. */ && (VARRAY_INT (n_times_set, REGNO (dest_reg)) == 1 /* or all sets must be consecutive and make a giv. */ - || (benefit = consec_sets_giv (benefit, p, + || (benefit = consec_sets_giv (loop, benefit, p, src_reg, dest_reg, &add_val, &mult_val, &last_consec_insn)))) @@ -4498,9 +4501,9 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) if (VARRAY_INT (n_times_set, REGNO (dest_reg)) != 1) p = last_consec_insn; - record_giv (v, p, src_reg, dest_reg, mult_val, add_val, benefit, - DEST_REG, not_every_iteration, maybe_multiple, - NULL_PTR, loop_start, loop_end); + record_giv (loop, v, p, src_reg, dest_reg, mult_val, add_val, + benefit, DEST_REG, not_every_iteration, + maybe_multiple, NULL_PTR); } } @@ -4510,15 +4513,15 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) /* This resulted in worse code on a VAX 8600. I wonder if it still does. */ if (GET_CODE (p) == INSN) - find_mem_givs (PATTERN (p), p, not_every_iteration, maybe_multiple, - loop_start, loop_end); + find_mem_givs (loop, PATTERN (p), p, not_every_iteration, + maybe_multiple); #endif /* Update the status of whether giv can derive other givs. This can change when we pass a label or an insn that updates a biv. */ if (GET_CODE (p) == INSN || GET_CODE (p) == JUMP_INSN || GET_CODE (p) == CODE_LABEL) - update_giv_derive (p); + update_giv_derive (loop, p); /* Past CODE_LABEL, we get to insns that may be executed multiple times. The only way we can be sure that they can't is if every @@ -4582,9 +4585,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) matter. Check to see if the target of this branch is on the loop->exits_labels list. */ - for (label = uid_loop[INSN_UID (loop_start)]->exit_labels; - label; - label = LABEL_NEXTREF (label)) + for (label = loop->exit_labels; label; label = LABEL_NEXTREF (label)) if (XEXP (label, 0) == JUMP_LABEL (p)) break; @@ -4643,7 +4644,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) for (v = bl->giv; v; v = v->next_iv) if (! v->replaceable && ! v->not_replaceable) - check_final_value (v, loop_start, loop_end, loop_info->n_iterations); + check_final_value (loop, v); } /* Try to prove that the loop counter variable (if any) is always @@ -4692,14 +4693,13 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) && ! bl->nonneg #endif && ! reg_mentioned_p (bl->biv->dest_reg, SET_SRC (bl->init_set))) - || ((final_value = final_biv_value (bl, loop_start, loop_end, - loop_info->n_iterations)) + || ((final_value = final_biv_value (loop, bl)) #ifdef HAVE_decrement_and_branch_until_zero && ! bl->nonneg #endif )) - bl->eliminable = maybe_eliminate_biv (bl, loop_start, loop_end, 0, - threshold, insn_count); + bl->eliminable = maybe_eliminate_biv (loop, bl, 0, threshold, + insn_count); else { if (loop_dump_stream) @@ -4863,7 +4863,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) VARRAY_GROW (reg_iv_type, nregs); VARRAY_GROW (reg_iv_info, nregs); } - recombine_givs (bl, loop_start, loop_end, unroll_p); + recombine_givs (loop, bl, unroll_p); /* Reduce each giv that we decided to reduce. */ @@ -5096,7 +5096,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) 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) insert_before = loop_start; else insert_before = end_insert_before; @@ -5164,9 +5164,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) doing so in the rare cases where it can occur. */ if (all_reduced == 1 && bl->eliminable - && maybe_eliminate_biv (bl, loop_start, loop_end, 1, - threshold, insn_count)) - + && maybe_eliminate_biv (loop, bl, 1, threshold, insn_count)) { /* ?? If we created a new test to bypass the loop entirely, or otherwise drop straight in, based on this test, then @@ -5188,7 +5186,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p) 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) insert_before = loop_start; else insert_before = end_insert_before; @@ -5328,12 +5326,11 @@ valid_initial_value_p (x, insn, call_seen, loop_start) more thanonce in each loop iteration. */ static void -find_mem_givs (x, insn, not_every_iteration, maybe_multiple, loop_start, - loop_end) +find_mem_givs (loop, x, insn, not_every_iteration, maybe_multiple) + const struct loop *loop; rtx x; rtx insn; int not_every_iteration, maybe_multiple; - rtx loop_start, loop_end; { register int i, j; register enum rtx_code code; @@ -5371,16 +5368,16 @@ find_mem_givs (x, insn, not_every_iteration, maybe_multiple, loop_start, it comes time to combine a set of related DEST_ADDR GIVs, since this one would not be seen. */ - if (general_induction_var (XEXP (x, 0), &src_reg, &add_val, + if (general_induction_var (loop, XEXP (x, 0), &src_reg, &add_val, &mult_val, 1, &benefit)) { /* Found one; record it. */ struct induction *v = (struct induction *) oballoc (sizeof (struct induction)); - record_giv (v, insn, src_reg, addr_placeholder, mult_val, + record_giv (loop, v, insn, src_reg, addr_placeholder, mult_val, add_val, benefit, DEST_ADDR, not_every_iteration, - maybe_multiple, &XEXP (x, 0), loop_start, loop_end); + maybe_multiple, &XEXP (x, 0)); v->mem_mode = GET_MODE (x); } @@ -5396,12 +5393,12 @@ find_mem_givs (x, insn, not_every_iteration, maybe_multiple, loop_start, fmt = GET_RTX_FORMAT (code); for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) if (fmt[i] == 'e') - find_mem_givs (XEXP (x, i), insn, not_every_iteration, maybe_multiple, - loop_start, loop_end); + find_mem_givs (loop, XEXP (x, i), insn, not_every_iteration, + maybe_multiple); else if (fmt[i] == 'E') for (j = 0; j < XVECLEN (x, i); j++) - find_mem_givs (XVECEXP (x, i, j), insn, not_every_iteration, - maybe_multiple, loop_start, loop_end); + find_mem_givs (loop, XVECEXP (x, i, j), insn, not_every_iteration, + maybe_multiple); } /* Fill in the data about one biv update. @@ -5524,9 +5521,9 @@ record_biv (v, insn, dest_reg, inc_val, mult_val, location, LOCATION points to the place where this giv's value appears in INSN. */ static void -record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit, - type, not_every_iteration, maybe_multiple, location, loop_start, - loop_end) +record_giv (loop, v, insn, src_reg, dest_reg, mult_val, add_val, benefit, + type, not_every_iteration, maybe_multiple, location) + const struct loop *loop; struct induction *v; rtx insn; rtx src_reg; @@ -5536,7 +5533,6 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit, enum g_types type; int not_every_iteration, maybe_multiple; rtx *location; - rtx loop_start, loop_end; { struct induction *b; struct iv_class *bl; @@ -5637,7 +5633,8 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit, if (REGNO_FIRST_UID (REGNO (dest_reg)) == INSN_UID (insn) /* Previous line always fails if INSN was moved by loop opt. */ - && uid_luid[REGNO_LAST_UID (REGNO (dest_reg))] < INSN_LUID (loop_end) + && uid_luid[REGNO_LAST_UID (REGNO (dest_reg))] + < INSN_LUID (loop->end) && (! not_every_iteration || last_use_this_basic_block (dest_reg, insn))) { @@ -5674,7 +5671,7 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit, biv update to before it, then this giv is not replaceable. */ if (v->replaceable) for (b = bl->biv; b; b = b->next_iv) - if (back_branch_in_range_p (b->insn, loop_start, loop_end)) + if (back_branch_in_range_p (loop, b->insn)) { v->replaceable = 0; v->not_replaceable = 1; @@ -5772,10 +5769,9 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit, have been identified. */ static void -check_final_value (v, loop_start, loop_end, n_iterations) +check_final_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 final_value = 0; @@ -5802,7 +5798,7 @@ check_final_value (v, loop_start, loop_end, n_iterations) v->replaceable = 0; #endif - if ((final_value = final_giv_value (v, loop_start, loop_end, n_iterations)) + if ((final_value = final_giv_value (loop, v)) && (v->always_computable || last_use_this_basic_block (v->dest_reg, v->insn))) { int biv_increment_seen = 0; @@ -5834,8 +5830,8 @@ check_final_value (v, loop_start, loop_end, n_iterations) while (1) { p = NEXT_INSN (p); - if (p == loop_end) - p = NEXT_INSN (loop_start); + if (p == loop->end) + p = NEXT_INSN (loop->start); if (p == v->insn) break; @@ -5868,17 +5864,17 @@ check_final_value (v, loop_start, loop_end, n_iterations) while (1) { p = NEXT_INSN (p); - if (p == loop_end) - p = NEXT_INSN (loop_start); + if (p == loop->end) + p = NEXT_INSN (loop->start); if (p == last_giv_use) break; if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p) && LABEL_NAME (JUMP_LABEL (p)) && ((loop_insn_first_p (JUMP_LABEL (p), v->insn) - && loop_insn_first_p (loop_start, JUMP_LABEL (p))) + && loop_insn_first_p (loop->start, JUMP_LABEL (p))) || (loop_insn_first_p (last_giv_use, JUMP_LABEL (p)) - && loop_insn_first_p (JUMP_LABEL (p), loop_end)))) + && loop_insn_first_p (JUMP_LABEL (p), loop->end)))) { v->replaceable = 0; v->not_replaceable = 1; @@ -5914,7 +5910,8 @@ check_final_value (v, loop_start, loop_end, n_iterations) The cases we look at are when a label or an update to a biv is passed. */ static void -update_giv_derive (p) +update_giv_derive (loop, p) + const struct loop *loop; rtx p; { struct iv_class *bl; @@ -5982,14 +5979,16 @@ update_giv_derive (p) tem = 0; if (biv->mult_val == const1_rtx) - tem = simplify_giv_expr (gen_rtx_MULT (giv->mode, + tem = simplify_giv_expr (loop, + gen_rtx_MULT (giv->mode, biv->add_val, giv->mult_val), &dummy); if (tem && giv->derive_adjustment) tem = simplify_giv_expr - (gen_rtx_PLUS (giv->mode, tem, giv->derive_adjustment), + (loop, + gen_rtx_PLUS (giv->mode, tem, giv->derive_adjustment), &dummy); if (tem) @@ -6042,13 +6041,13 @@ update_giv_derive (p) If we cannot find a biv, we return 0. */ static int -basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val, +basic_induction_var (loop, x, mode, dest_reg, p, inc_val, mult_val, location, multi_insn_incr) + const struct loop *loop; register rtx x; enum machine_mode mode; rtx dest_reg; rtx p; - int level; rtx *inc_val; rtx *mult_val; rtx **location; @@ -6081,7 +6080,7 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val, return 0; arg = *argp; - if (invariant_p (arg) != 1) + if (loop_invariant_p (loop, arg) != 1) return 0; *inc_val = convert_modes (GET_MODE (dest_reg), GET_MODE (x), arg, 0); @@ -6093,9 +6092,9 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val, /* If this is a SUBREG for a promoted variable, check the inner value. */ if (SUBREG_PROMOTED_VAR_P (x)) - return basic_induction_var (SUBREG_REG (x), GET_MODE (SUBREG_REG (x)), - dest_reg, p, level, - inc_val, mult_val, location, + return basic_induction_var (loop, SUBREG_REG (x), + GET_MODE (SUBREG_REG (x)), + dest_reg, p, inc_val, mult_val, location, multi_insn_incr); return 0; @@ -6124,11 +6123,11 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val, && (GET_MODE_CLASS (GET_MODE (SET_DEST (set))) == MODE_INT) && SUBREG_REG (SET_DEST (set)) == x)) - && basic_induction_var (SET_SRC (set), + && basic_induction_var (loop, SET_SRC (set), (GET_MODE (SET_SRC (set)) == VOIDmode ? GET_MODE (x) : GET_MODE (SET_SRC (set))), - dest_reg, insn, level, + dest_reg, insn, inc_val, mult_val, location, multi_insn_incr)) { @@ -6143,7 +6142,7 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val, as a biv of the outer loop, causing code to be moved INTO the inner loop. */ case MEM: - if (invariant_p (x) != 1) + if (loop_invariant_p (loop, x) != 1) return 0; case CONST_INT: case SYMBOL_REF: @@ -6151,7 +6150,7 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val, /* convert_modes aborts if we try to convert to or from CCmode, so just exclude that case. It is very unlikely that a condition code value would be a useful iterator anyways. */ - if (level == 0 + if (loop->level == 1 && GET_MODE_CLASS (mode) != MODE_CC && GET_MODE_CLASS (GET_MODE (dest_reg)) != MODE_CC) { @@ -6164,9 +6163,9 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val, return 0; case SIGN_EXTEND: - return basic_induction_var (XEXP (x, 0), GET_MODE (XEXP (x, 0)), - dest_reg, p, level, inc_val, mult_val, - location, multi_insn_incr); + return basic_induction_var (loop, XEXP (x, 0), GET_MODE (XEXP (x, 0)), + dest_reg, p, inc_val, mult_val, location, + multi_insn_incr); case ASHIFTRT: /* Similar, since this can be a sign extension. */ @@ -6184,9 +6183,9 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val, && INTVAL (XEXP (x, 1)) >= 0 && GET_CODE (SET_SRC (set)) == ASHIFT && XEXP (x, 1) == XEXP (SET_SRC (set), 1) - && basic_induction_var (XEXP (SET_SRC (set), 0), + && basic_induction_var (loop, XEXP (SET_SRC (set), 0), GET_MODE (XEXP (x, 0)), - dest_reg, insn, level, inc_val, mult_val, + dest_reg, insn, inc_val, mult_val, location, multi_insn_incr)) { *multi_insn_incr = 1; @@ -6214,7 +6213,8 @@ basic_induction_var (x, mode, dest_reg, p, level, inc_val, mult_val, such that the value of X is biv * mult + add; */ static int -general_induction_var (x, src_reg, add_val, mult_val, is_addr, pbenefit) +general_induction_var (loop, x, src_reg, add_val, mult_val, is_addr, pbenefit) + const struct loop *loop; rtx x; rtx *src_reg; rtx *add_val; @@ -6226,14 +6226,14 @@ general_induction_var (x, src_reg, add_val, mult_val, is_addr, pbenefit) char *storage; /* If this is an invariant, forget it, it isn't a giv. */ - if (invariant_p (x) == 1) + if (loop_invariant_p (loop, x) == 1) return 0; /* See if the expression could be a giv and get its form. Mark our place on the obstack in case we don't find a giv. */ storage = (char *) oballoc (0); *pbenefit = 0; - x = simplify_giv_expr (x, pbenefit); + x = simplify_giv_expr (loop, x, pbenefit); if (x == 0) { obfree (storage); @@ -6336,7 +6336,8 @@ static int cmp_combine_givs_stats PARAMS ((const PTR, const PTR)); static int cmp_recombine_givs_stats PARAMS ((const PTR, const PTR)); static rtx -simplify_giv_expr (x, benefit) +simplify_giv_expr (loop, x, benefit) + const struct loop *loop; rtx x; int *benefit; { @@ -6354,8 +6355,8 @@ simplify_giv_expr (x, benefit) switch (GET_CODE (x)) { case PLUS: - arg0 = simplify_giv_expr (XEXP (x, 0), benefit); - arg1 = simplify_giv_expr (XEXP (x, 1), benefit); + arg0 = simplify_giv_expr (loop, XEXP (x, 0), benefit); + arg1 = simplify_giv_expr (loop, XEXP (x, 1), benefit); if (arg0 == 0 || arg1 == 0) return NULL_RTX; @@ -6401,7 +6402,8 @@ simplify_giv_expr (x, benefit) case PLUS: /* (a + invar_1) + invar_2. Associate. */ return - simplify_giv_expr (gen_rtx_PLUS (mode, + simplify_giv_expr (loop, + gen_rtx_PLUS (mode, XEXP (arg0, 0), gen_rtx_PLUS (mode, XEXP (arg0, 1), @@ -6427,7 +6429,8 @@ simplify_giv_expr (x, benefit) if (GET_CODE (arg1) == PLUS) return - simplify_giv_expr (gen_rtx_PLUS (mode, + simplify_giv_expr (loop, + gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, arg0, XEXP (arg1, 0)), XEXP (arg1, 1)), @@ -6440,7 +6443,8 @@ simplify_giv_expr (x, benefit) if (!rtx_equal_p (arg0, arg1)) return NULL_RTX; - return simplify_giv_expr (gen_rtx_MULT (mode, + return simplify_giv_expr (loop, + gen_rtx_MULT (mode, XEXP (arg0, 0), gen_rtx_PLUS (mode, XEXP (arg0, 1), @@ -6449,7 +6453,8 @@ simplify_giv_expr (x, benefit) case MINUS: /* Handle "a - b" as "a + b * (-1)". */ - return simplify_giv_expr (gen_rtx_PLUS (mode, + return simplify_giv_expr (loop, + gen_rtx_PLUS (mode, XEXP (x, 0), gen_rtx_MULT (mode, XEXP (x, 1), @@ -6457,8 +6462,8 @@ simplify_giv_expr (x, benefit) benefit); case MULT: - arg0 = simplify_giv_expr (XEXP (x, 0), benefit); - arg1 = simplify_giv_expr (XEXP (x, 1), benefit); + arg0 = simplify_giv_expr (loop, XEXP (x, 0), benefit); + arg1 = simplify_giv_expr (loop, XEXP (x, 1), benefit); if (arg0 == 0 || arg1 == 0) return NULL_RTX; @@ -6511,7 +6516,8 @@ simplify_giv_expr (x, benefit) case MULT: /* (a * invar_1) * invar_2. Associate. */ - return simplify_giv_expr (gen_rtx_MULT (mode, + return simplify_giv_expr (loop, + gen_rtx_MULT (mode, XEXP (arg0, 0), gen_rtx_MULT (mode, XEXP (arg0, 1), @@ -6520,7 +6526,8 @@ simplify_giv_expr (x, benefit) case PLUS: /* (a + invar_1) * invar_2. Distribute. */ - return simplify_giv_expr (gen_rtx_PLUS (mode, + return simplify_giv_expr (loop, + gen_rtx_PLUS (mode, gen_rtx_MULT (mode, XEXP (arg0, 0), arg1), @@ -6539,7 +6546,8 @@ simplify_giv_expr (x, benefit) return 0; return - simplify_giv_expr (gen_rtx_MULT (mode, + simplify_giv_expr (loop, + gen_rtx_MULT (mode, XEXP (x, 0), GEN_INT ((HOST_WIDE_INT) 1 << INTVAL (XEXP (x, 1)))), @@ -6547,12 +6555,14 @@ simplify_giv_expr (x, benefit) case NEG: /* "-a" is "a * (-1)" */ - return simplify_giv_expr (gen_rtx_MULT (mode, XEXP (x, 0), constm1_rtx), + return simplify_giv_expr (loop, + gen_rtx_MULT (mode, XEXP (x, 0), constm1_rtx), benefit); case NOT: /* "~a" is "-a - 1". Silly, but easy. */ - return simplify_giv_expr (gen_rtx_MINUS (mode, + return simplify_giv_expr (loop, + gen_rtx_MINUS (mode, gen_rtx_NEG (mode, XEXP (x, 0)), const1_rtx), benefit); @@ -6587,14 +6597,14 @@ simplify_giv_expr (x, benefit) if (v->derive_adjustment) tem = gen_rtx_MINUS (mode, tem, v->derive_adjustment); - return simplify_giv_expr (tem, benefit); + return simplify_giv_expr (loop, tem, benefit); } default: /* 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 (invariant_p (x) == 1) + if (loop_invariant_p (loop, x) == 1) { struct movable *m; @@ -6606,7 +6616,8 @@ simplify_giv_expr (x, benefit) /* If we match another movable, we must use that, as this one is going away. */ if (m->match) - return simplify_giv_expr (m->match->set_dest, benefit); + return simplify_giv_expr (loop, m->match->set_dest, + benefit); /* If consec is non-zero, this is a member of a group of instructions that were moved together. We handle this @@ -6640,7 +6651,7 @@ simplify_giv_expr (x, benefit) || GET_CODE (tem) == CONST_INT || GET_CODE (tem) == SYMBOL_REF) { - tem = simplify_giv_expr (tem, benefit); + tem = simplify_giv_expr (loop, tem, benefit); if (tem) return tem; } @@ -6649,7 +6660,8 @@ simplify_giv_expr (x, benefit) && GET_CODE (XEXP (XEXP (tem, 0), 0)) == SYMBOL_REF && GET_CODE (XEXP (XEXP (tem, 0), 1)) == CONST_INT) { - tem = simplify_giv_expr (XEXP (tem, 0), benefit); + tem = simplify_giv_expr (loop, XEXP (tem, 0), + benefit); if (tem) return tem; } @@ -6667,7 +6679,7 @@ simplify_giv_expr (x, benefit) if (GET_CODE (x) == USE) x = XEXP (x, 0); - if (invariant_p (x) == 1) + if (loop_invariant_p (loop, x) == 1) { if (GET_CODE (x) == CONST_INT) return x; @@ -6753,8 +6765,9 @@ sge_plus (mode, x, y) *MULT_VAL and *ADD_VAL. */ static int -consec_sets_giv (first_benefit, p, src_reg, dest_reg, +consec_sets_giv (loop, first_benefit, p, src_reg, dest_reg, add_val, mult_val, last_consec_insn) + const struct loop *loop; int first_benefit; rtx p; rtx src_reg; @@ -6803,11 +6816,11 @@ consec_sets_giv (first_benefit, p, src_reg, dest_reg, && (set = single_set (p)) && GET_CODE (SET_DEST (set)) == REG && SET_DEST (set) == dest_reg - && (general_induction_var (SET_SRC (set), &src_reg, + && (general_induction_var (loop, SET_SRC (set), &src_reg, add_val, mult_val, 0, &benefit) /* Giv created by equivalent expression. */ || ((temp = find_reg_note (p, REG_EQUAL, NULL_RTX)) - && general_induction_var (XEXP (temp, 0), &src_reg, + && general_induction_var (loop, XEXP (temp, 0), &src_reg, add_val, mult_val, 0, &benefit))) && src_reg == v->src_reg) { @@ -7380,9 +7393,9 @@ find_life_end (x, stats, insn, biv) This tends to shorten giv lifetimes, and helps the next step: try to derive givs from other givs. */ static void -recombine_givs (bl, loop_start, loop_end, unroll_p) +recombine_givs (loop, bl, unroll_p) + const struct loop *loop; struct iv_class *bl; - rtx loop_start, loop_end; int unroll_p; { struct induction *v, **giv_array, *last_giv; @@ -7535,7 +7548,7 @@ recombine_givs (bl, loop_start, loop_end, unroll_p) else { stats[i].end_luid = uid_luid[REGNO_LAST_UID (regno)]; - if (stats[i].end_luid > INSN_LUID (loop_end)) + if (stats[i].end_luid > INSN_LUID (loop->end)) { stats[i].end_luid = -1; ends_need_computing++; @@ -7550,12 +7563,12 @@ recombine_givs (bl, loop_start, loop_end, unroll_p) if (ends_need_computing) { rtx biv = bl->biv->src_reg; - rtx p = loop_end; + rtx p = loop->end; do { - if (p == loop_start) - p = loop_end; + if (p == loop->start) + p = loop->end; p = PREV_INSN (p); if (GET_RTX_CLASS (GET_CODE (p)) != 'i') continue; @@ -7641,8 +7654,8 @@ recombine_givs (bl, loop_start, loop_end, unroll_p) derived giv would defeat the purpose of reducing register pressure. ??? We could arrange to move the insn. */ - && ((unsigned) stats[i].end_luid - INSN_LUID (loop_start) - > (unsigned) stats[i].start_luid - INSN_LUID (loop_start)) + && ((unsigned) stats[i].end_luid - INSN_LUID (loop->start) + > (unsigned) stats[i].start_luid - INSN_LUID (loop->start)) && rtx_equal_p (last_giv->mult_val, v->mult_val) /* ??? Could handle libcalls, but would need more logic. */ && ! find_reg_note (v->insn, REG_RETVAL, NULL_RTX) @@ -7860,7 +7873,7 @@ check_dbra_loop (loop, insn_count) register value, try to optimize it. Otherwise, we can't do anything. */ jump = PREV_INSN (loop_end); - comparison = get_condition_for_loop (jump); + comparison = get_condition_for_loop (loop, jump); if (comparison == 0) return 0; @@ -7931,7 +7944,7 @@ check_dbra_loop (loop, insn_count) if (GET_CODE (p) != JUMP_INSN) continue; - before_comparison = get_condition_for_loop (p); + before_comparison = get_condition_for_loop (loop, p); if (before_comparison && XEXP (before_comparison, 0) == bl->biv->dest_reg && GET_CODE (before_comparison) == LT @@ -7969,8 +7982,7 @@ check_dbra_loop (loop, insn_count) which is reversible. */ int reversible_mem_store = 1; - if (bl->giv_count == 0 - && ! uid_loop[INSN_UID (loop_start)]->exit_count) + if (bl->giv_count == 0 && ! loop->exit_count) { rtx bivreg = regno_reg_rtx[bl->regno]; @@ -8018,7 +8030,7 @@ check_dbra_loop (loop, insn_count) { for (p = loop_start; p != loop_end; p = NEXT_INSN (p)) if (GET_RTX_CLASS (GET_CODE (p)) == 'i') - num_nonfixed_reads += count_nonfixed_reads (PATTERN (p)); + num_nonfixed_reads += count_nonfixed_reads (loop, PATTERN (p)); /* If the loop has a single store, and the destination address is invariant, then we can't reverse the loop, because this address @@ -8033,7 +8045,9 @@ check_dbra_loop (loop, insn_count) reversible_mem_store = (! unknown_address_altered && ! unknown_constant_address_altered - && ! invariant_p (XEXP (XEXP (loop_store_mems, 0), 0))); + && ! loop_invariant_p (loop, + XEXP (XEXP (loop_store_mems, 0), + 0))); /* If the store depends on a register that is set after the store, it depends on the initial value, and is thus not @@ -8115,7 +8129,7 @@ check_dbra_loop (loop, insn_count) ??? 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 (!invariant_p (comparison_value)) + if (! loop_invariant_p (loop, comparison_value)) return 0; if (GET_CODE (comparison_value) == CONST_INT) @@ -8403,7 +8417,6 @@ check_dbra_loop (loop, insn_count) /* Verify whether the biv BL appears to be eliminable, based on the insns in the loop that refer to it. - LOOP_START is the first insn of the loop, and END is the end insn. If ELIMINATE_P is non-zero, actually do the elimination. @@ -8412,15 +8425,15 @@ check_dbra_loop (loop, insn_count) start of the loop. */ static int -maybe_eliminate_biv (bl, loop_start, loop_end, eliminate_p, threshold, - insn_count) +maybe_eliminate_biv (loop, bl, eliminate_p, threshold, insn_count) + const struct loop *loop; struct iv_class *bl; - rtx loop_start; - rtx loop_end; int eliminate_p; int threshold, insn_count; { rtx reg = bl->biv->dest_reg; + rtx loop_start = loop->start; + rtx loop_end = loop->end; rtx p; /* Scan all insns in the loop, stopping if we find one that uses the @@ -8454,7 +8467,8 @@ maybe_eliminate_biv (bl, loop_start, loop_end, eliminate_p, threshold, } if ((code == INSN || code == JUMP_INSN || code == CALL_INSN) && reg_mentioned_p (reg, PATTERN (p)) - && ! maybe_eliminate_biv_1 (PATTERN (p), p, bl, eliminate_p, where)) + && ! maybe_eliminate_biv_1 (loop, PATTERN (p), p, bl, + eliminate_p, where)) { if (loop_dump_stream) fprintf (loop_dump_stream, @@ -8558,7 +8572,8 @@ biv_elimination_giv_has_0_offset (biv, giv, insn) the loop. */ static int -maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where) +maybe_eliminate_biv_1 (loop, x, insn, bl, eliminate_p, where) + const struct loop *loop; rtx x, insn; struct iv_class *bl; int eliminate_p; @@ -8777,7 +8792,7 @@ maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where) } else if (GET_CODE (arg) == REG || GET_CODE (arg) == MEM) { - if (invariant_p (arg) == 1) + if (loop_invariant_p (loop, arg) == 1) { /* Look for giv with constant positive mult_val and nonconst add_val. Insert insns to compute new compare value. @@ -8884,14 +8899,14 @@ maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where) switch (fmt[i]) { case 'e': - if (! maybe_eliminate_biv_1 (XEXP (x, i), insn, bl, + if (! maybe_eliminate_biv_1 (loop, XEXP (x, i), insn, bl, eliminate_p, where)) return 0; break; case 'E': for (j = XVECLEN (x, i) - 1; j >= 0; j--) - if (! maybe_eliminate_biv_1 (XVECEXP (x, i, j), insn, bl, + if (! maybe_eliminate_biv_1 (loop, XVECEXP (x, i, j), insn, bl, eliminate_p, where)) return 0; break; @@ -9250,14 +9265,15 @@ get_condition (jump, earliest) unless both operands are invariants. */ rtx -get_condition_for_loop (x) +get_condition_for_loop (loop, x) + const struct loop *loop; rtx x; { rtx comparison = get_condition (x, NULL_PTR); if (comparison == 0 - || ! invariant_p (XEXP (comparison, 0)) - || invariant_p (XEXP (comparison, 1))) + || ! loop_invariant_p (loop, XEXP (comparison, 0)) + || loop_invariant_p (loop, XEXP (comparison, 1))) return comparison; return gen_rtx_fmt_ee (swap_condition (GET_CODE (comparison)), VOIDmode, @@ -9762,7 +9778,7 @@ load_mems (loop) rtx mem_list_entry; if (MEM_VOLATILE_P (mem) - || invariant_p (XEXP (mem, 0)) != 1) + || loop_invariant_p (loop, XEXP (mem, 0)) != 1) /* There's no telling whether or not MEM is modified. */ loop_mems[i].optimize = 0; @@ -9874,7 +9890,7 @@ load_mems (loop) int j; rtx set; - /* Load the memory immediately before START, which is + /* Load the memory immediately before LOOP->START, which is the NOTE_LOOP_BEG. */ set = gen_move_insn (reg, mem); emit_insn_before (set, loop->start); @@ -9963,8 +9979,7 @@ note_reg_stored (x, setter, arg) /* Try to replace every occurrence of pseudo REGNO with REPLACEMENT. There must be exactly one insn that sets this pseudo; it will be deleted if all replacements succeed and we can prove that the register - is not used after the loop. - The arguments SCAN_START, LOOP_TOP and END are as in load_mems. */ + is not used after the loop. */ static void try_copy_prop (loop, replacement, regno) const struct loop *loop; diff --git a/gcc/loop.h b/gcc/loop.h index 10a7131..8fbde21 100644 --- a/gcc/loop.h +++ b/gcc/loop.h @@ -230,23 +230,21 @@ extern int first_increment_giv, last_increment_giv; /* Forward declarations for non-static functions declared in loop.c and unroll.c. */ -int invariant_p PARAMS ((rtx)); -rtx get_condition_for_loop PARAMS ((rtx)); +int loop_invariant_p PARAMS ((const struct loop *, rtx)); +rtx get_condition_for_loop PARAMS ((const struct loop *, rtx)); void emit_iv_add_mult PARAMS ((rtx, rtx, rtx, rtx, rtx)); rtx express_from PARAMS ((struct induction *, struct induction *)); void unroll_loop PARAMS ((struct loop *, int, rtx, int)); -rtx biv_total_increment PARAMS ((struct iv_class *, rtx, rtx)); +rtx biv_total_increment PARAMS ((struct iv_class *)); unsigned HOST_WIDE_INT loop_iterations PARAMS ((struct loop *)); -int precondition_loop_p PARAMS ((rtx, struct loop_info *, +int precondition_loop_p PARAMS ((const struct loop *, rtx *, rtx *, rtx *, enum machine_mode *mode)); -rtx final_biv_value PARAMS ((struct iv_class *, rtx, rtx, - unsigned HOST_WIDE_INT)); -rtx final_giv_value PARAMS ((struct induction *, rtx, rtx, - unsigned HOST_WIDE_INT)); +rtx final_biv_value PARAMS ((const struct loop *, struct iv_class *)); +rtx final_giv_value PARAMS ((const struct loop *, struct induction *)); void emit_unrolled_add PARAMS ((rtx, rtx, rtx)); -int back_branch_in_range_p PARAMS ((rtx, rtx, rtx)); +int back_branch_in_range_p PARAMS ((const struct loop *, rtx)); int loop_insn_first_p PARAMS ((rtx, rtx)); 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) { -- 2.7.4