summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/loop.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2001-01-03 17:16:04 +0000
committerobrien <obrien@FreeBSD.org>2001-01-03 17:16:04 +0000
commite103926ab58446425b46d5df55c940db3abeff84 (patch)
tree46177f22832f755e34be042b91555eedf10b4f66 /contrib/gcc/loop.c
parentd566d0a5f8c3f4d187ecbf8096628e9ae9dd3567 (diff)
downloadFreeBSD-src-e103926ab58446425b46d5df55c940db3abeff84.zip
FreeBSD-src-e103926ab58446425b46d5df55c940db3abeff84.tar.gz
Enlist the FreeBSD-CURRENT users as testers of GCC 2.95.3 Release Candidate #1
Diffstat (limited to 'contrib/gcc/loop.c')
-rw-r--r--contrib/gcc/loop.c127
1 files changed, 100 insertions, 27 deletions
diff --git a/contrib/gcc/loop.c b/contrib/gcc/loop.c
index 497ac36..d7242ed 100644
--- a/contrib/gcc/loop.c
+++ b/contrib/gcc/loop.c
@@ -2773,6 +2773,7 @@ find_and_verify_loops (f)
{
rtx p;
rtx our_next = next_real_insn (insn);
+ rtx last_insn_to_move = NEXT_INSN (insn);
int dest_loop;
int outer_loop = -1;
@@ -2824,21 +2825,39 @@ find_and_verify_loops (f)
&& INSN_UID (JUMP_LABEL (p)) != 0
&& condjump_p (p)
&& ! simplejump_p (p)
- && next_real_insn (JUMP_LABEL (p)) == our_next)
+ && next_real_insn (JUMP_LABEL (p)) == our_next
+ /* If it's not safe to move the sequence, then we
+ mustn't try. */
+ && insns_safe_to_move_p (p, NEXT_INSN (insn),
+ &last_insn_to_move))
{
rtx target
= JUMP_LABEL (insn) ? JUMP_LABEL (insn) : get_last_insn ();
int target_loop_num = uid_loop_num[INSN_UID (target)];
- rtx loc;
+ rtx loc, loc2;
for (loc = target; loc; loc = PREV_INSN (loc))
if (GET_CODE (loc) == BARRIER
+ /* Don't move things inside a tablejump. */
+ && ((loc2 = next_nonnote_insn (loc)) == 0
+ || GET_CODE (loc2) != CODE_LABEL
+ || (loc2 = next_nonnote_insn (loc2)) == 0
+ || GET_CODE (loc2) != JUMP_INSN
+ || (GET_CODE (PATTERN (loc2)) != ADDR_VEC
+ && GET_CODE (PATTERN (loc2)) != ADDR_DIFF_VEC))
&& uid_loop_num[INSN_UID (loc)] == target_loop_num)
break;
if (loc == 0)
for (loc = target; loc; loc = NEXT_INSN (loc))
if (GET_CODE (loc) == BARRIER
+ /* Don't move things inside a tablejump. */
+ && ((loc2 = next_nonnote_insn (loc)) == 0
+ || GET_CODE (loc2) != CODE_LABEL
+ || (loc2 = next_nonnote_insn (loc2)) == 0
+ || GET_CODE (loc2) != JUMP_INSN
+ || (GET_CODE (PATTERN (loc2)) != ADDR_VEC
+ && GET_CODE (PATTERN (loc2)) != ADDR_DIFF_VEC))
&& uid_loop_num[INSN_UID (loc)] == target_loop_num)
break;
@@ -2879,11 +2898,13 @@ find_and_verify_loops (f)
/* Include the BARRIER after INSN and copy the
block after LOC. */
- new_label = squeeze_notes (new_label, NEXT_INSN (insn));
- reorder_insns (new_label, NEXT_INSN (insn), loc);
+ new_label = squeeze_notes (new_label,
+ last_insn_to_move);
+ reorder_insns (new_label, last_insn_to_move, loc);
/* All those insns are now in TARGET_LOOP_NUM. */
- for (q = new_label; q != NEXT_INSN (NEXT_INSN (insn));
+ for (q = new_label;
+ q != NEXT_INSN (last_insn_to_move);
q = NEXT_INSN (q))
uid_loop_num[INSN_UID (q)] = target_loop_num;
@@ -5678,6 +5699,7 @@ check_final_value (v, loop_start, loop_end, n_iterations)
or all uses follow that insn in the same basic block),
- its final value can be calculated (this condition is different
than the one above in record_giv)
+ - it's not used before it's set
- no assignments to the biv occur during the giv's lifetime. */
#if 0
@@ -5689,7 +5711,7 @@ check_final_value (v, loop_start, loop_end, n_iterations)
if ((final_value = final_giv_value (v, loop_start, loop_end, n_iterations))
&& (v->always_computable || last_use_this_basic_block (v->dest_reg, v->insn)))
{
- int biv_increment_seen = 0;
+ int biv_increment_seen = 0, before_giv_insn = 0;
rtx p = v->insn;
rtx last_giv_use;
@@ -5719,26 +5741,35 @@ check_final_value (v, loop_start, loop_end, n_iterations)
{
p = NEXT_INSN (p);
if (p == loop_end)
- p = NEXT_INSN (loop_start);
+ {
+ before_giv_insn = 1;
+ p = NEXT_INSN (loop_start);
+ }
if (p == v->insn)
break;
if (GET_CODE (p) == INSN || GET_CODE (p) == JUMP_INSN
|| GET_CODE (p) == CALL_INSN)
{
- if (biv_increment_seen)
+ /* It is possible for the BIV increment to use the GIV if we
+ have a cycle. Thus we must be sure to check each insn for
+ both BIV and GIV uses, and we must check for BIV uses
+ first. */
+
+ if (! biv_increment_seen
+ && reg_set_p (v->src_reg, PATTERN (p)))
+ biv_increment_seen = 1;
+
+ if (reg_mentioned_p (v->dest_reg, PATTERN (p)))
{
- if (reg_mentioned_p (v->dest_reg, PATTERN (p)))
+ if (biv_increment_seen || before_giv_insn)
{
v->replaceable = 0;
v->not_replaceable = 1;
break;
}
+ last_giv_use = p;
}
- else if (reg_set_p (v->src_reg, PATTERN (p)))
- biv_increment_seen = 1;
- else if (reg_mentioned_p (v->dest_reg, PATTERN (p)))
- last_giv_use = p;
}
}
@@ -5983,6 +6014,7 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val, location)
insn = p;
while (1)
{
+ rtx dest;
do {
insn = PREV_INSN (insn);
} while (insn && GET_CODE (insn) == NOTE
@@ -5994,20 +6026,26 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val, location)
if (set == 0)
break;
- if ((SET_DEST (set) == x
- || (GET_CODE (SET_DEST (set)) == SUBREG
- && (GET_MODE_SIZE (GET_MODE (SET_DEST (set)))
- <= UNITS_PER_WORD)
- && (GET_MODE_CLASS (GET_MODE (SET_DEST (set)))
- == MODE_INT)
- && SUBREG_REG (SET_DEST (set)) == x))
- && basic_induction_var (SET_SRC (set),
- (GET_MODE (SET_SRC (set)) == VOIDmode
- ? GET_MODE (x)
- : GET_MODE (SET_SRC (set))),
- dest_reg, insn,
- inc_val, mult_val, location))
- return 1;
+ dest = SET_DEST (set);
+ if (dest == x
+ || (GET_CODE (dest) == SUBREG
+ && (GET_MODE_SIZE (GET_MODE (dest)) <= UNITS_PER_WORD)
+ && (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT)
+ && SUBREG_REG (dest) == x))
+ return basic_induction_var (SET_SRC (set),
+ (GET_MODE (SET_SRC (set)) == VOIDmode
+ ? GET_MODE (x)
+ : GET_MODE (SET_SRC (set))),
+ dest_reg, insn,
+ inc_val, mult_val, location);
+
+ while (GET_CODE (dest) == SIGN_EXTRACT
+ || GET_CODE (dest) == ZERO_EXTRACT
+ || GET_CODE (dest) == SUBREG
+ || GET_CODE (dest) == STRICT_LOW_PART)
+ dest = XEXP (dest, 0);
+ if (dest == x)
+ break;
}
/* ... fall through ... */
@@ -8155,6 +8193,40 @@ check_dbra_loop (loop_end, insn_count, loop_start, loop_info)
bl->nonneg = 1;
}
+ /* No insn may reference both the reversed and another biv or it
+ will fail (see comment near the top of the loop reversal
+ code).
+ Earlier on, we have verified that the biv has no use except
+ counting, or it is the only biv in this function.
+ However, the code that computes no_use_except_counting does
+ not verify reg notes. It's possible to have an insn that
+ references another biv, and has a REG_EQUAL note with an
+ expression based on the reversed biv. To avoid this case,
+ remove all REG_EQUAL notes based on the reversed biv
+ here. */
+ for (p = loop_start; p != loop_end; p = NEXT_INSN (p))
+ if (GET_RTX_CLASS (GET_CODE (p)) == 'i')
+ {
+ rtx *pnote;
+ rtx set = single_set (p);
+ /* If this is a set of a GIV based on the reversed biv, any
+ REG_EQUAL notes should still be correct. */
+ if (! set
+ || GET_CODE (SET_DEST (set)) != REG
+ || (size_t) REGNO (SET_DEST (set)) >= reg_iv_type->num_elements
+ || REG_IV_TYPE (REGNO (SET_DEST (set))) != GENERAL_INDUCT
+ || REG_IV_INFO (REGNO (SET_DEST (set)))->src_reg != bl->biv->src_reg)
+ for (pnote = &REG_NOTES (p); *pnote;)
+ {
+ if (REG_NOTE_KIND (*pnote) == REG_EQUAL
+ && reg_mentioned_p (regno_reg_rtx[bl->regno],
+ XEXP (*pnote, 0)))
+ *pnote = XEXP (*pnote, 1);
+ else
+ pnote = &XEXP (*pnote, 1);
+ }
+ }
+
/* Mark that this biv has been reversed. Each giv which depends
on this biv, and which is also live past the end of the loop
will have to be fixed up. */
@@ -9314,6 +9386,7 @@ instrument_loop_bct (loop_start, loop_end, loop_num_iterations)
emit_jump_insn_before (gen_decrement_and_branch_on_count (counter_reg,
start_label),
loop_end);
+ JUMP_LABEL (prev_nonnote_insn (loop_end)) = start_label;
LABEL_NUSES (start_label)++;
}
OpenPOWER on IntegriCloud