aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1992-09-19 15:50:23 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1992-09-19 15:50:23 -0400
commit0e91429a56d8c737cd6b6f2e60c62a21de0a31d6 (patch)
tree26bc4d6f408bff72a4efd7284f84e6bdeb86e3fc /gcc
parent98f3b471109aa20dc29832bd8698fe1ef9b410b8 (diff)
downloadgcc-0e91429a56d8c737cd6b6f2e60c62a21de0a31d6.zip
gcc-0e91429a56d8c737cd6b6f2e60c62a21de0a31d6.tar.gz
gcc-0e91429a56d8c737cd6b6f2e60c62a21de0a31d6.tar.bz2
(find_splittable_regs): If any BIV update isn't simple, don't split it.
(final_giv_value): Look for biv updates by matching insns; don't try to reparse the insn. From-SVN: r2181
Diffstat (limited to 'gcc')
-rw-r--r--gcc/unroll.c80
1 files changed, 49 insertions, 31 deletions
diff --git a/gcc/unroll.c b/gcc/unroll.c
index 2bb5900..aa8db72 100644
--- a/gcc/unroll.c
+++ b/gcc/unroll.c
@@ -2179,6 +2179,7 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
int unroll_number;
{
struct iv_class *bl;
+ struct induction *v;
rtx increment, tem;
rtx biv_final_value;
int biv_splittable;
@@ -2216,6 +2217,15 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
&& ! (biv_final_value = final_biv_value (bl, loop_start, loop_end)))
biv_splittable = 0;
+ /* If any of the insns setting the BIV don't do so with a simple
+ PLUS, we don't know how to split it. */
+ for (v = bl->biv; biv_splittable && v; v = v->next_iv)
+ if ((tem = single_set (v->insn)) == 0
+ || GET_CODE (SET_DEST (tem)) != REG
+ || REGNO (SET_DEST (tem)) != bl->regno
+ || GET_CODE (SET_SRC (tem)) != PLUS)
+ biv_splittable = 0;
+
/* 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
handling all of the givs, since some of them may need to use the
@@ -2415,11 +2425,31 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
giv's initial value. Otherwise, save the constant zero for it. */
if (unroll_type == UNROLL_COMPLETELY)
- /* It is not safe to use bl->initial_value here, because it may not
- be invariant. It is safe to use the initial value stored in
- the splittable_regs array. */
- value = fold_rtx_mult_add (v->mult_val, splittable_regs[bl->regno],
- v->add_val, v->mode);
+ {
+ /* It is not safe to use bl->initial_value here, because it may not
+ be invariant. It is safe to use the initial value stored in
+ the splittable_regs array if it is set. In rare cases, it won't
+ be set, so then we do exactly the same thing as
+ find_splittable_regs does to get a safe value. */
+ rtx biv_initial_value;
+
+ if (splittable_regs[bl->regno])
+ biv_initial_value = splittable_regs[bl->regno];
+ else if (GET_CODE (bl->initial_value) != REG
+ || (REGNO (bl->initial_value) != bl->regno
+ && REGNO (bl->initial_value) >= FIRST_PSEUDO_REGISTER))
+ biv_initial_value = bl->initial_value;
+ else
+ {
+ rtx tem = gen_reg_rtx (bl->biv->mode);
+
+ emit_insn_before (gen_move_insn (tem, bl->biv->src_reg),
+ loop_start);
+ biv_initial_value = tem;
+ }
+ value = fold_rtx_mult_add (v->mult_val, biv_initial_value,
+ v->add_val, v->mode);
+ }
else
value = const0_rtx;
@@ -2804,7 +2834,7 @@ final_giv_value (v, loop_start, loop_end)
rtx loop_start, loop_end;
{
struct iv_class *bl;
- rtx reg, insn, pattern;
+ rtx insn;
rtx increment, tem;
enum rtx_code code;
rtx insert_before, seq;
@@ -2868,31 +2898,19 @@ final_giv_value (v, loop_start, loop_end)
for (insn = NEXT_INSN (v->insn); insn != loop_end;
insn = NEXT_INSN (insn))
{
- if (GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) == SET
- && SET_DEST (PATTERN (insn)) == v->src_reg)
- {
- pattern = PATTERN (insn);
- if (GET_CODE (SET_SRC (pattern)) != PLUS)
- {
- /* Sometimes a biv is computed in a temp reg,
- and then copied into the biv reg. */
- pattern = PATTERN (PREV_INSN (insn));
- if (GET_CODE (SET_SRC (pattern)) != PLUS)
- abort ();
- }
- if (GET_CODE (XEXP (SET_SRC (pattern), 0)) != REG
- || REGNO (XEXP (SET_SRC (pattern), 0)) != bl->regno)
- abort ();
-
- start_sequence ();
- tem = expand_binop (GET_MODE (tem), sub_optab, tem,
- XEXP (SET_SRC (pattern), 1), NULL_RTX, 0,
- OPTAB_LIB_WIDEN);
- seq = gen_sequence ();
- end_sequence ();
- emit_insn_before (seq, insert_before);
- }
+ struct induction *biv;
+
+ for (biv = bl->biv; biv; biv = biv->next_iv)
+ if (biv->insn == insn)
+ {
+ start_sequence ();
+ tem = expand_binop (GET_MODE (tem), sub_optab, tem,
+ biv->add_val, NULL_RTX, 0,
+ OPTAB_LIB_WIDEN);
+ seq = gen_sequence ();
+ end_sequence ();
+ emit_insn_before (seq, insert_before);
+ }
}
/* Now calculate the giv's final value. */