diff options
Diffstat (limited to 'gcc/unroll.c')
-rw-r--r-- | gcc/unroll.c | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/gcc/unroll.c b/gcc/unroll.c index 2191e0c3f27..7e4483ea495 100644 --- a/gcc/unroll.c +++ b/gcc/unroll.c @@ -1,5 +1,5 @@ /* Try to unroll loops, and split induction variables. - Copyright (C) 1992, 93-95, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1992, 93, 94, 95, 97, 1998 Free Software Foundation, Inc. Contributed by James E. Wilson, Cygnus Support/UC Berkeley. This file is part of GNU CC. @@ -1452,6 +1452,7 @@ init_reg_map (map, maxregnum) to the iv. This procedure reconstructs the pattern computing the iv; verifying that all operands are of the proper form. + PATTERN must be the result of single_set. The return value is the amount that the giv is incremented by. */ static rtx @@ -1629,7 +1630,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, rtx start_label, loop_end, insert_before, copy_notes_from; { rtx insn, pattern; - rtx tem, copy; + rtx set, tem, copy; int dest_reg_was_split, i; #ifdef HAVE_cc0 rtx cc0_insn = 0; @@ -1676,15 +1677,15 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, Do this before splitting the giv, since that may map the SET_DEST to a new register. */ - if (GET_CODE (pattern) == SET - && GET_CODE (SET_DEST (pattern)) == REG - && addr_combined_regs[REGNO (SET_DEST (pattern))]) + if ((set = single_set (insn)) + && GET_CODE (SET_DEST (set)) == REG + && addr_combined_regs[REGNO (SET_DEST (set))]) { struct iv_class *bl; struct induction *v, *tv; - int regno = REGNO (SET_DEST (pattern)); + int regno = REGNO (SET_DEST (set)); - v = addr_combined_regs[REGNO (SET_DEST (pattern))]; + v = addr_combined_regs[REGNO (SET_DEST (set))]; bl = reg_biv_class[REGNO (v->src_reg)]; /* Although the giv_inc amount is not needed here, we must call @@ -1693,7 +1694,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, we might accidentally delete insns generated immediately below by emit_unrolled_add. */ - giv_inc = calculate_giv_inc (pattern, insn, regno); + giv_inc = calculate_giv_inc (set, insn, regno); /* Now find all address giv's that were combined with this giv 'v'. */ @@ -1767,11 +1768,11 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, dest_reg_was_split = 0; - if (GET_CODE (pattern) == SET - && GET_CODE (SET_DEST (pattern)) == REG - && splittable_regs[REGNO (SET_DEST (pattern))]) + if ((set = single_set (insn)) + && GET_CODE (SET_DEST (set)) == REG + && splittable_regs[REGNO (SET_DEST (set))]) { - int regno = REGNO (SET_DEST (pattern)); + int regno = REGNO (SET_DEST (set)); dest_reg_was_split = 1; @@ -1779,9 +1780,9 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, already computed above. */ if (giv_inc == 0) - giv_inc = calculate_giv_inc (pattern, insn, regno); - giv_dest_reg = SET_DEST (pattern); - giv_src_reg = SET_DEST (pattern); + giv_inc = calculate_giv_inc (set, insn, regno); + giv_dest_reg = SET_DEST (set); + giv_src_reg = SET_DEST (set); if (unroll_type == UNROLL_COMPLETELY) { @@ -1977,9 +1978,9 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, /* Can't use the label_map for every insn, since this may be the backward branch, and hence the label was not mapped. */ - if (GET_CODE (pattern) == SET) + if ((set = single_set (copy))) { - tem = SET_SRC (pattern); + tem = SET_SRC (set); if (GET_CODE (tem) == LABEL_REF) label = XEXP (tem, 0); else if (GET_CODE (tem) == IF_THEN_ELSE) @@ -2651,9 +2652,10 @@ verify_addresses (v, giv_inc, unroll_number) rtx last_addr = plus_constant (v->dest_reg, INTVAL (giv_inc) * (unroll_number - 1)); - /* First check to see if either address would fail. */ - if (! validate_change (v->insn, v->location, v->dest_reg, 0) - || ! validate_change (v->insn, v->location, last_addr, 0)) + /* First check to see if either address would fail. Handle the fact + that we have may have a match_dup. */ + if (! validate_replace_rtx (*v->location, v->dest_reg, v->insn) + || ! validate_replace_rtx (*v->location, last_addr, v->insn)) ret = 0; /* Now put things back the way they were before. This will always @@ -2940,6 +2942,10 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, if (v->dest_reg == tem && ! verify_addresses (v, giv_inc, unroll_number)) { + for (v2 = v->next_iv; v2; v2 = v2->next_iv) + if (v2->same_insn == v) + v2->same_insn = 0; + if (loop_dump_stream) fprintf (loop_dump_stream, "Invalid address for giv at insn %d\n", @@ -2986,6 +2992,10 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, if the resulting address would be invalid. */ if (! verify_addresses (v, giv_inc, unroll_number)) { + for (v2 = v->next_iv; v2; v2 = v2->next_iv) + if (v2->same_insn == v) + v2->same_insn = 0; + if (loop_dump_stream) fprintf (loop_dump_stream, "Invalid address for giv at insn %d\n", |