Commit 4d87f7a7 by J"orn Rennecke Committed by Joern Rennecke

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
parent 6ebec6ee
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> 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. * config/mips/mips.md (div_trap_mips16): Remove nop's after branches.
......
...@@ -320,7 +320,6 @@ static int general_induction_var PROTO((rtx, rtx *, rtx *, rtx *, int, int *)); ...@@ -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 consec_sets_giv PROTO((int, rtx, rtx, rtx, rtx *, rtx *, rtx *));
static int check_dbra_loop PROTO((rtx, int, rtx, struct loop_info *)); 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_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 rtx combine_givs_p PROTO((struct induction *, struct induction *));
static void combine_givs PROTO((struct iv_class *)); static void combine_givs PROTO((struct iv_class *));
struct recombine_givs_stats; struct recombine_givs_stats;
...@@ -4180,7 +4179,7 @@ strength_reduce (scan_start, end, loop_top, insn_count, ...@@ -4180,7 +4179,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
v->auto_inc_opt = 0; v->auto_inc_opt = 0;
v->unrolled = 0; v->unrolled = 0;
v->shared = 0; v->shared = 0;
v->derived = 0; v->derived_from = 0;
v->always_computable = 1; v->always_computable = 1;
v->always_executed = 1; v->always_executed = 1;
v->replaceable = 1; v->replaceable = 1;
...@@ -4622,7 +4621,7 @@ strength_reduce (scan_start, end, loop_top, insn_count, ...@@ -4622,7 +4621,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
v->new_reg = gen_reg_rtx (v->mode); v->new_reg = gen_reg_rtx (v->mode);
if (v->derived) if (v->derived_from)
{ {
PATTERN (v->insn) PATTERN (v->insn)
= replace_rtx (PATTERN (v->insn), v->dest_reg, v->new_reg); = 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, ...@@ -5273,7 +5272,7 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
v->auto_inc_opt = 0; v->auto_inc_opt = 0;
v->unrolled = 0; v->unrolled = 0;
v->shared = 0; v->shared = 0;
v->derived = 0; v->derived_from = 0;
v->last_use = 0; v->last_use = 0;
/* The v->always_computable field is used in update_giv_derive, to /* The v->always_computable field is used in update_giv_derive, to
...@@ -6632,7 +6631,7 @@ express_from_1 (a, b, mult) ...@@ -6632,7 +6631,7 @@ express_from_1 (a, b, mult)
return NULL_RTX; return NULL_RTX;
} }
static rtx rtx
express_from (g1, g2) express_from (g1, g2)
struct induction *g1, *g2; struct induction *g1, *g2;
{ {
...@@ -7290,7 +7289,7 @@ recombine_givs (bl, loop_start, loop_end, unroll_p) ...@@ -7290,7 +7289,7 @@ recombine_givs (bl, loop_start, loop_end, unroll_p)
rtx sum; rtx sum;
v = giv_array[stats[i].giv_number]; 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; continue;
if (! last_giv) if (! last_giv)
{ {
...@@ -7347,7 +7346,7 @@ recombine_givs (bl, loop_start, loop_end, unroll_p) ...@@ -7347,7 +7346,7 @@ recombine_givs (bl, loop_start, loop_end, unroll_p)
gen_rtx_SET (GET_MODE (v->dest_reg), gen_rtx_SET (GET_MODE (v->dest_reg),
v->dest_reg, sum), 0)) v->dest_reg, sum), 0))
{ {
v->derived = 1; v->derived_from = last_giv;
v->new_reg = v->dest_reg; v->new_reg = v->dest_reg;
life_end = stats[i].end_luid; life_end = stats[i].end_luid;
......
...@@ -101,8 +101,6 @@ struct induction ...@@ -101,8 +101,6 @@ struct induction
initialized in unrolled loop. */ initialized in unrolled loop. */
unsigned shared : 1; unsigned shared : 1;
unsigned no_const_addval : 1; /* 1 if add_val does not contain a const. */ 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 */ int lifetime; /* Length of life of this giv */
rtx derive_adjustment; /* If nonzero, is an adjustment to be rtx derive_adjustment; /* If nonzero, is an adjustment to be
subtracted from add_val when this giv subtracted from add_val when this giv
...@@ -115,6 +113,8 @@ struct induction ...@@ -115,6 +113,8 @@ struct induction
struct induction *same; /* If this giv has been combined with another struct induction *same; /* If this giv has been combined with another
giv, this points to the base giv. The base giv, this points to the base giv. The base
giv will have COMBINED_WITH non-zero. */ 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 HOST_WIDE_INT const_adjust; /* Used by loop unrolling, when an address giv
is split, and a constant is eliminated from is split, and a constant is eliminated from
the address, the -constant is stored here the address, the -constant is stored here
...@@ -226,6 +226,7 @@ extern int first_increment_giv, last_increment_giv; ...@@ -226,6 +226,7 @@ extern int first_increment_giv, last_increment_giv;
int invariant_p PROTO((rtx)); int invariant_p PROTO((rtx));
rtx get_condition_for_loop PROTO((rtx)); rtx get_condition_for_loop PROTO((rtx));
void emit_iv_add_mult PROTO((rtx, rtx, rtx, rtx, 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. */ /* Forward declarations for non-static functions declared in stmt.c. */
void find_loop_tree_blocks PROTO((void)); void find_loop_tree_blocks PROTO((void));
......
...@@ -1794,6 +1794,10 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, ...@@ -1794,6 +1794,10 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
giv_dest_reg = SET_DEST (set); giv_dest_reg = SET_DEST (set);
if (derived_regs[regno]) 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_src_reg = XEXP (SET_SRC (set), 0);
giv_inc = XEXP (SET_SRC (set), 1); giv_inc = XEXP (SET_SRC (set), 1);
} }
...@@ -2830,7 +2834,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, ...@@ -2830,7 +2834,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
} }
splittable_regs[REGNO (v->new_reg)] = value; 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 else
{ {
...@@ -2886,17 +2890,36 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, ...@@ -2886,17 +2890,36 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
Emit insn to initialize its value before loop start. */ Emit insn to initialize its value before loop start. */
rtx tem = gen_reg_rtx (v->mode); 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); 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, /* If the address giv has a constant in its new_reg value,
then this constant can be pulled out and put in value, then this constant can be pulled out and put in value,
instead of being part of the initialization code. */ instead of being part of the initialization code. */
if (GET_CODE (v->new_reg) == PLUS if (GET_CODE (new_reg) == PLUS
&& GET_CODE (XEXP (v->new_reg, 1)) == CONST_INT) && GET_CODE (XEXP (new_reg, 1)) == CONST_INT)
{ {
v->dest_reg 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. /* Only succeed if this will give valid addresses.
Try to validate both the first and the last Try to validate both the first and the last
...@@ -2907,9 +2930,9 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, ...@@ -2907,9 +2930,9 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
/* Save the negative of the eliminated const, so /* Save the negative of the eliminated const, so
that we can calculate the dest_reg's increment that we can calculate the dest_reg's increment
value later. */ 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) if (loop_dump_stream)
fprintf (loop_dump_stream, fprintf (loop_dump_stream,
"Eliminating constant from giv %d\n", "Eliminating constant from giv %d\n",
...@@ -2938,6 +2961,9 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, ...@@ -2938,6 +2961,9 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
INSN_UID (v->insn)); INSN_UID (v->insn));
continue; continue;
} }
v->new_reg = new_reg;
v->same = same;
/* We set this after the address check, to guarantee that /* We set this after the address check, to guarantee that
the register will be initialized. */ the register will be initialized. */
...@@ -2992,6 +3018,15 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, ...@@ -2992,6 +3018,15 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
INSN_UID (v->insn)); INSN_UID (v->insn));
continue; 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 /* 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, ...@@ -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. */ Make sure that it's giv is marked as splittable here. */
splittable_regs[REGNO (v->new_reg)] = value; 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 /* Make it appear to depend upon itself, so that the
giv will be properly split in the main loop above. */ 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, ...@@ -3058,6 +3093,11 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
if (! v->ignore) if (! v->ignore)
count = reg_biv_class[REGNO (v->src_reg)]->biv_count; 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; splittable_regs_updates[REGNO (v->new_reg)] = count;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment