loop.h (express_from): Declare.
* 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. From-SVN: r25007
This commit is contained in:
parent
6ebec6eed4
commit
4d87f7a77c
4 changed files with 68 additions and 16 deletions
|
@ -1,3 +1,15 @@
|
|||
Wed Feb 3 20:44:59 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
|
||||
|
||||
* 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.
|
||||
|
||||
Wed Feb 3 15:26:58 1999 Gavin Romig-Koch <gavin@cygnus.com>
|
||||
|
||||
* config/mips/mips.md (div_trap_mips16): Remove nop's after branches.
|
||||
|
|
13
gcc/loop.c
13
gcc/loop.c
|
@ -320,7 +320,6 @@ static int general_induction_var PROTO((rtx, rtx *, rtx *, rtx *, int, int *));
|
|||
static int consec_sets_giv PROTO((int, rtx, rtx, rtx, rtx *, rtx *, rtx *));
|
||||
static int check_dbra_loop PROTO((rtx, int, rtx, struct loop_info *));
|
||||
static rtx express_from_1 PROTO((rtx, rtx, rtx));
|
||||
static rtx express_from PROTO((struct induction *, struct induction *));
|
||||
static rtx combine_givs_p PROTO((struct induction *, struct induction *));
|
||||
static void combine_givs PROTO((struct iv_class *));
|
||||
struct recombine_givs_stats;
|
||||
|
@ -4180,7 +4179,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
|
|||
v->auto_inc_opt = 0;
|
||||
v->unrolled = 0;
|
||||
v->shared = 0;
|
||||
v->derived = 0;
|
||||
v->derived_from = 0;
|
||||
v->always_computable = 1;
|
||||
v->always_executed = 1;
|
||||
v->replaceable = 1;
|
||||
|
@ -4622,7 +4621,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
|
|||
|
||||
v->new_reg = gen_reg_rtx (v->mode);
|
||||
|
||||
if (v->derived)
|
||||
if (v->derived_from)
|
||||
{
|
||||
PATTERN (v->insn)
|
||||
= replace_rtx (PATTERN (v->insn), v->dest_reg, v->new_reg);
|
||||
|
@ -5273,7 +5272,7 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
|
|||
v->auto_inc_opt = 0;
|
||||
v->unrolled = 0;
|
||||
v->shared = 0;
|
||||
v->derived = 0;
|
||||
v->derived_from = 0;
|
||||
v->last_use = 0;
|
||||
|
||||
/* The v->always_computable field is used in update_giv_derive, to
|
||||
|
@ -6632,7 +6631,7 @@ express_from_1 (a, b, mult)
|
|||
return NULL_RTX;
|
||||
}
|
||||
|
||||
static rtx
|
||||
rtx
|
||||
express_from (g1, g2)
|
||||
struct induction *g1, *g2;
|
||||
{
|
||||
|
@ -7290,7 +7289,7 @@ recombine_givs (bl, loop_start, loop_end, unroll_p)
|
|||
rtx sum;
|
||||
|
||||
v = giv_array[stats[i].giv_number];
|
||||
if (v->giv_type != DEST_REG || v->derived || v->same)
|
||||
if (v->giv_type != DEST_REG || v->derived_from || v->same)
|
||||
continue;
|
||||
if (! last_giv)
|
||||
{
|
||||
|
@ -7347,7 +7346,7 @@ recombine_givs (bl, loop_start, loop_end, unroll_p)
|
|||
gen_rtx_SET (GET_MODE (v->dest_reg),
|
||||
v->dest_reg, sum), 0))
|
||||
{
|
||||
v->derived = 1;
|
||||
v->derived_from = last_giv;
|
||||
v->new_reg = v->dest_reg;
|
||||
life_end = stats[i].end_luid;
|
||||
|
||||
|
|
|
@ -101,8 +101,6 @@ struct induction
|
|||
initialized in unrolled loop. */
|
||||
unsigned shared : 1;
|
||||
unsigned no_const_addval : 1; /* 1 if add_val does not contain a const. */
|
||||
unsigned derived : 1; /* For a giv, 1 if we decided to derive this
|
||||
giv from another one. */
|
||||
int lifetime; /* Length of life of this giv */
|
||||
rtx derive_adjustment; /* If nonzero, is an adjustment to be
|
||||
subtracted from add_val when this giv
|
||||
|
@ -115,6 +113,8 @@ struct induction
|
|||
struct induction *same; /* If this giv has been combined with another
|
||||
giv, this points to the base giv. The base
|
||||
giv will have COMBINED_WITH non-zero. */
|
||||
struct induction *derived_from;/* For a giv, if we decided to derive this
|
||||
giv from another one. */
|
||||
HOST_WIDE_INT const_adjust; /* Used by loop unrolling, when an address giv
|
||||
is split, and a constant is eliminated from
|
||||
the address, the -constant is stored here
|
||||
|
@ -226,6 +226,7 @@ extern int first_increment_giv, last_increment_giv;
|
|||
int invariant_p PROTO((rtx));
|
||||
rtx get_condition_for_loop PROTO((rtx));
|
||||
void emit_iv_add_mult PROTO((rtx, rtx, rtx, rtx, rtx));
|
||||
rtx express_from PROTO((struct induction *, struct induction *));
|
||||
|
||||
/* Forward declarations for non-static functions declared in stmt.c. */
|
||||
void find_loop_tree_blocks PROTO((void));
|
||||
|
|
54
gcc/unroll.c
54
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue