summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog33
-rw-r--r--gcc/loop.c429
-rw-r--r--gcc/loop.h16
-rw-r--r--gcc/unroll.c205
4 files changed, 366 insertions, 317 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f0c10d9de37..f3c6842f509 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,36 @@
+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.
+
2000-01-25 Gavin Romig-Koch <gavin@cygnus.com>
* config/mips/mips.h (LEGITIMATE_CONSTANT_P): Fix for mips16.
diff --git a/gcc/loop.c b/gcc/loop.c
index b297504d2f3..283e2194431 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 10a7131685a..8fbde2146ac 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 f325ceaacfb..7f3658eb262 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)
{