diff options
author | amylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-02-03 12:48:48 +0000 |
---|---|---|
committer | amylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-02-03 12:48:48 +0000 |
commit | 3a7923efe1b5bf98ba371307d3d56c859ae5da67 (patch) | |
tree | 2745f7a520daf446daec4f2acf8993d311d58f60 /gcc/unroll.c | |
parent | 15fe599b11d86f1a5497a0325c4535aded4dd140 (diff) | |
download | gcc-3a7923efe1b5bf98ba371307d3d56c859ae5da67.tar.gz |
* loop.h (express_from): Declare.
(struct induction): Replace derived flag with derived_from pointer.
* loop.c (strength_reduce, record_giv, recombine_givs): Likewise.
(express_from): No longer static.
* unroll.c (find_splittable_givs): Replace derived with derived_from.
When processing an address giv with which another giv has been
combined that has also been derived from a third giv, handle like
having combined with the third giv.
Set splittable_regs_updates appropriately for derived givs.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@25007 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/unroll.c')
-rw-r--r-- | gcc/unroll.c | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/gcc/unroll.c b/gcc/unroll.c index 0d1787c0e52..341b8059882 100644 --- a/gcc/unroll.c +++ b/gcc/unroll.c @@ -1794,6 +1794,10 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, giv_dest_reg = SET_DEST (set); if (derived_regs[regno]) { + /* ??? This relies on SET_SRC (SET) to be of + the form (plus (reg) (const_int)), and thus + forces recombine_givs to restrict the kind + of giv derivations it does before unrolling. */ giv_src_reg = XEXP (SET_SRC (set), 0); giv_inc = XEXP (SET_SRC (set), 1); } @@ -2830,7 +2834,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, } splittable_regs[REGNO (v->new_reg)] = value; - derived_regs[REGNO (v->new_reg)] = v->derived; + derived_regs[REGNO (v->new_reg)] = v->derived_from != 0; } else { @@ -2886,17 +2890,36 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, Emit insn to initialize its value before loop start. */ rtx tem = gen_reg_rtx (v->mode); + struct induction *same = v->same; + rtx new_reg = v->new_reg; record_base_value (REGNO (tem), v->add_val, 0); + if (same && same->derived_from) + { + /* calculate_giv_inc doesn't work for derived givs. + copy_loop_body works around the problem for the + DEST_REG givs themselves, but it can't handle + DEST_ADDR givs that have been combined with + derived a derived DEST_REG giv. + So Handle V as if the giv from which V->SAME has + been derived has been combined with V. + recombine_givs only derives givs from givs that + are reduced the ordinary, so we need not worry + about same->derived_from being in turn derived. */ + + same = same->derived_from; + new_reg = express_from (same, v); + } + /* If the address giv has a constant in its new_reg value, then this constant can be pulled out and put in value, instead of being part of the initialization code. */ - if (GET_CODE (v->new_reg) == PLUS - && GET_CODE (XEXP (v->new_reg, 1)) == CONST_INT) + if (GET_CODE (new_reg) == PLUS + && GET_CODE (XEXP (new_reg, 1)) == CONST_INT) { v->dest_reg - = plus_constant (tem, INTVAL (XEXP (v->new_reg,1))); + = plus_constant (tem, INTVAL (XEXP (new_reg, 1))); /* Only succeed if this will give valid addresses. Try to validate both the first and the last @@ -2907,9 +2930,9 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, /* Save the negative of the eliminated const, so that we can calculate the dest_reg's increment value later. */ - v->const_adjust = - INTVAL (XEXP (v->new_reg, 1)); + v->const_adjust = - INTVAL (XEXP (new_reg, 1)); - v->new_reg = XEXP (v->new_reg, 0); + new_reg = XEXP (new_reg, 0); if (loop_dump_stream) fprintf (loop_dump_stream, "Eliminating constant from giv %d\n", @@ -2938,6 +2961,9 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, INSN_UID (v->insn)); continue; } + + v->new_reg = new_reg; + v->same = same; /* We set this after the address check, to guarantee that the register will be initialized. */ @@ -2992,6 +3018,15 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, INSN_UID (v->insn)); continue; } + if (v->same && v->same->derived_from) + { + /* Handle V as if the giv from which V->SAME has + been derived has been combined with V. */ + + v->same = v->same->derived_from; + v->new_reg = express_from (v->same, v); + } + } /* Store the value of dest_reg into the insn. This sharing @@ -3014,7 +3049,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, Make sure that it's giv is marked as splittable here. */ splittable_regs[REGNO (v->new_reg)] = value; - derived_regs[REGNO (v->new_reg)] = v->derived; + derived_regs[REGNO (v->new_reg)] = v->derived_from != 0; /* Make it appear to depend upon itself, so that the giv will be properly split in the main loop above. */ @@ -3058,6 +3093,11 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, if (! v->ignore) count = reg_biv_class[REGNO (v->src_reg)]->biv_count; + if (count > 1 && v->derived_from) + /* In this case, there is one set where the giv insn was and one + set each after each biv increment. (Most are likely dead.) */ + count++; + splittable_regs_updates[REGNO (v->new_reg)] = count; } |