summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/loop.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2002-05-09 20:02:13 +0000
committerobrien <obrien@FreeBSD.org>2002-05-09 20:02:13 +0000
commitc8f5fc7032940ad6633f932ac40cade82ec4d0cc (patch)
tree29a0f0a6c79a69ecc64f612947a0fe5904311713 /contrib/gcc/loop.c
parentc9ab9ae440a8066b2c2b85b157b1fdadcf09916a (diff)
downloadFreeBSD-src-c8f5fc7032940ad6633f932ac40cade82ec4d0cc.zip
FreeBSD-src-c8f5fc7032940ad6633f932ac40cade82ec4d0cc.tar.gz
Gcc 3.1.0 pre-release from the FSF anoncvs repo on 9-May-2002 15:57:15 EDT.
Diffstat (limited to 'contrib/gcc/loop.c')
-rw-r--r--contrib/gcc/loop.c118
1 files changed, 77 insertions, 41 deletions
diff --git a/contrib/gcc/loop.c b/contrib/gcc/loop.c
index a65595f..d653b5c 100644
--- a/contrib/gcc/loop.c
+++ b/contrib/gcc/loop.c
@@ -235,6 +235,7 @@ FILE *loop_dump_stream;
/* Forward declarations. */
+static void invalidate_loops_containing_label PARAMS ((rtx));
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 *));
@@ -1102,7 +1103,25 @@ scan_loop (loop, flags)
optimizing for code size. */
if (! optimize_size)
- move_movables (loop, movables, threshold, insn_count);
+ {
+ move_movables (loop, movables, threshold, insn_count);
+
+ /* Recalculate regs->array if move_movables has created new
+ registers. */
+ if (max_reg_num () > regs->num)
+ {
+ loop_regs_scan (loop, 0);
+ for (update_start = loop_start;
+ PREV_INSN (update_start)
+ && GET_CODE (PREV_INSN (update_start)) != CODE_LABEL;
+ update_start = PREV_INSN (update_start))
+ ;
+ update_end = NEXT_INSN (loop_end);
+
+ reg_scan_update (update_start, update_end, loop_max_reg);
+ loop_max_reg = max_reg_num ();
+ }
+ }
/* Now candidates that still are negative are those not moved.
Change regs->array[I].set_in_loop to indicate that those are not actually
@@ -2474,6 +2493,8 @@ prescan_loop (loop)
loop_info->unknown_address_altered = 1;
loop_info->has_nonconst_call = 1;
}
+ else if (pure_call_p (insn))
+ loop_info->has_nonconst_call = 1;
loop_info->has_call = 1;
if (can_throw_internal (insn))
loop_info->has_multiple_exit_targets = 1;
@@ -2486,16 +2507,17 @@ prescan_loop (loop)
if (set)
{
+ rtx src = SET_SRC (set);
rtx label1, label2;
- if (GET_CODE (SET_SRC (set)) == IF_THEN_ELSE)
+ if (GET_CODE (src) == IF_THEN_ELSE)
{
- label1 = XEXP (SET_SRC (set), 1);
- label2 = XEXP (SET_SRC (set), 2);
+ label1 = XEXP (src, 1);
+ label2 = XEXP (src, 2);
}
else
{
- label1 = SET_SRC (PATTERN (insn));
+ label1 = src;
label2 = NULL_RTX;
}
@@ -2589,6 +2611,17 @@ prescan_loop (loop)
}
}
+/* Invalidate all loops containing LABEL. */
+
+static void
+invalidate_loops_containing_label (label)
+ rtx label;
+{
+ struct loop *loop;
+ for (loop = uid_loop[INSN_UID (label)]; loop; loop = loop->outer)
+ loop->invalid = 1;
+}
+
/* Scan the function looking for loops. Record the start and end of each loop.
Also mark as invalid loops any loops that contain a setjmp or are branched
to from outside the loop. */
@@ -2675,23 +2708,12 @@ find_and_verify_loops (f, loops)
/* Any loop containing a label used in an initializer must be invalidated,
because it can be jumped into from anywhere. */
-
for (label = forced_labels; label; label = XEXP (label, 1))
- {
- for (loop = uid_loop[INSN_UID (XEXP (label, 0))];
- loop; loop = loop->outer)
- loop->invalid = 1;
- }
+ invalidate_loops_containing_label (XEXP (label, 0));
/* Any loop containing a label used for an exception handler must be
invalidated, because it can be jumped into from anywhere. */
-
- for (label = exception_handler_labels; label; label = XEXP (label, 1))
- {
- for (loop = uid_loop[INSN_UID (XEXP (label, 0))];
- loop; loop = loop->outer)
- loop->invalid = 1;
- }
+ for_each_eh_label (invalidate_loops_containing_label);
/* Now scan all insn's in the function. If any JUMP_INSN branches into a
loop that it is not contained within, that loop is marked invalid.
@@ -2715,11 +2737,7 @@ find_and_verify_loops (f, loops)
{
rtx note = find_reg_note (insn, REG_LABEL, NULL_RTX);
if (note)
- {
- for (loop = uid_loop[INSN_UID (XEXP (note, 0))];
- loop; loop = loop->outer)
- loop->invalid = 1;
- }
+ invalidate_loops_containing_label (XEXP (note, 0));
}
if (GET_CODE (insn) != JUMP_INSN)
@@ -3683,8 +3701,19 @@ remove_constant_addition (x)
HOST_WIDE_INT addval = 0;
rtx exp = *x;
+ /* Avoid clobbering a shared CONST expression. */
if (GET_CODE (exp) == CONST)
- exp = XEXP (exp, 0);
+ {
+ if (GET_CODE (XEXP (exp, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (exp, 0), 0)) == SYMBOL_REF
+ && GET_CODE (XEXP (XEXP (exp, 0), 1)) == CONST_INT)
+ {
+ *x = XEXP (XEXP (exp, 0), 0);
+ return INTVAL (XEXP (XEXP (exp, 0), 1));
+ }
+ return 0;
+ }
+
if (GET_CODE (exp) == CONST_INT)
{
addval = INTVAL (exp);
@@ -5132,6 +5161,11 @@ strength_reduce (loop, flags)
fprintf (loop_dump_stream, "Reg %d: biv eliminated\n",
bl->regno);
}
+ /* See above note wrt final_value. But since we couldn't eliminate
+ the biv, we must set the value after the loop instead of before. */
+ else if (bl->final_value && ! bl->reversed)
+ loop_insn_sink (loop, gen_move_insn (bl->biv->dest_reg,
+ bl->final_value));
}
/* Go through all the instructions in the loop, making all the
@@ -5178,7 +5212,8 @@ strength_reduce (loop, flags)
collected. Always unroll loops that would be as small or smaller
unrolled than when rolled. */
if ((flags & LOOP_UNROLL)
- || (loop_info->n_iterations > 0
+ || (!(flags & LOOP_FIRST_PASS)
+ && loop_info->n_iterations > 0
&& unrolled_insn_copies <= insn_count))
unroll_loop (loop, insn_count, 1);
@@ -6111,13 +6146,13 @@ basic_induction_var (loop, x, mode, dest_reg, p, inc_val, mult_val, location)
return 1;
case SUBREG:
- /* If this is a SUBREG for a promoted variable, check the inner
- value. */
- if (SUBREG_PROMOTED_VAR_P (x))
- return basic_induction_var (loop, SUBREG_REG (x),
- GET_MODE (SUBREG_REG (x)),
- dest_reg, p, inc_val, mult_val, location);
- return 0;
+ /* If what's inside the SUBREG is a BIV, then the SUBREG. This will
+ handle addition of promoted variables.
+ ??? The comment at the start of this function is wrong: promoted
+ variable increments don't look like it says they do. */
+ return basic_induction_var (loop, SUBREG_REG (x),
+ GET_MODE (SUBREG_REG (x)),
+ dest_reg, p, inc_val, mult_val, location);
case REG:
/* If this register is assigned in a previous insn, look at its
@@ -6179,10 +6214,11 @@ basic_induction_var (loop, x, mode, dest_reg, p, inc_val, mult_val, location)
case CONST:
/* 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. */
+ would be a useful iterator anyways. convert_modes aborts if we try to
+ convert a float mode to non-float or vice versa too. */
if (loop->level == 1
- && GET_MODE_CLASS (mode) != MODE_CC
- && GET_MODE_CLASS (GET_MODE (dest_reg)) != MODE_CC)
+ && GET_MODE_CLASS (mode) == GET_MODE_CLASS (GET_MODE (dest_reg))
+ && GET_MODE_CLASS (mode) != MODE_CC)
{
/* Possible bug here? Perhaps we don't know the mode of X. */
*inc_val = convert_modes (GET_MODE (dest_reg), mode, x, 0);
@@ -7626,9 +7662,9 @@ loop_regs_update (loop, seq)
}
else
{
- rtx set = single_set (seq);
- if (set && GET_CODE (SET_DEST (set)) == REG)
- record_base_value (REGNO (SET_DEST (set)), SET_SRC (set), 0);
+ if (GET_CODE (seq) == SET
+ && GET_CODE (SET_DEST (seq)) == REG)
+ record_base_value (REGNO (SET_DEST (seq)), SET_SRC (seq), 0);
}
}
@@ -7654,7 +7690,7 @@ loop_iv_add_mult_emit_before (loop, b, m, a, reg, before_bb, before_insn)
}
/* Use copy_rtx to prevent unexpected sharing of these rtx. */
- seq = gen_add_mult (copy_rtx (b), m, copy_rtx (a), reg);
+ seq = gen_add_mult (copy_rtx (b), copy_rtx (m), copy_rtx (a), reg);
/* Increase the lifetime of any invariants moved further in code. */
update_reg_last_use (a, before_insn);
@@ -7682,7 +7718,7 @@ loop_iv_add_mult_sink (loop, b, m, a, reg)
rtx seq;
/* Use copy_rtx to prevent unexpected sharing of these rtx. */
- seq = gen_add_mult (copy_rtx (b), m, copy_rtx (a), reg);
+ seq = gen_add_mult (copy_rtx (b), copy_rtx (m), copy_rtx (a), reg);
/* Increase the lifetime of any invariants moved further in code.
???? Is this really necessary? */
@@ -7711,7 +7747,7 @@ loop_iv_add_mult_hoist (loop, b, m, a, reg)
rtx seq;
/* Use copy_rtx to prevent unexpected sharing of these rtx. */
- seq = gen_add_mult (copy_rtx (b), m, copy_rtx (a), reg);
+ seq = gen_add_mult (copy_rtx (b), copy_rtx (m), copy_rtx (a), reg);
loop_insn_hoist (loop, seq);
OpenPOWER on IntegriCloud