Commit 60fb6df9 by Richard Henderson Committed by Richard Henderson

loop.h (struct induction): Add multi_insn_incr.

        * loop.h (struct induction): Add multi_insn_incr.
        * loop.c (basic_induction_var): New multi_insn_incr argument.
        Set it if we search back through previous insns for the biv.
        (record_biv): New multi_insn_incr argument; fill in struct induction.
        (strength_reduce): Discard an iv with multiple bivs, any of
        which require multiple insns to increment.

From-SVN: r30820
parent 3043b30e
Tue Dec 7 19:22:06 1999 Richard Henderson <rth@cygnus.com>
* loop.h (struct induction): Add multi_insn_incr.
* loop.c (basic_induction_var): New multi_insn_incr argument.
Set it if we search back through previous insns for the biv.
(record_biv): New multi_insn_incr argument; fill in struct induction.
(strength_reduce): Discard an iv with multiple bivs, any of
which require multiple insns to increment.
1999-12-07 Martin v. Lwis <loewis@informatik.hu-berlin.de>
* invoke.texi (C Dialect Options): Remove -flang-c9x, add -std
......
......@@ -310,12 +310,12 @@ static void strength_reduce PROTO((rtx, rtx, rtx, int, rtx, rtx,
static void find_single_use_in_loop PROTO((rtx, rtx, varray_type));
static int valid_initial_value_p PROTO((rtx, rtx, int, rtx));
static void find_mem_givs PROTO((rtx, rtx, int, int, rtx, rtx));
static void record_biv PROTO((struct induction *, rtx, rtx, rtx, rtx, rtx *, int, int));
static void record_biv PROTO((struct induction *, rtx, rtx, rtx, rtx, rtx *, int, int, int));
static void check_final_value PROTO((struct induction *, rtx, rtx,
unsigned HOST_WIDE_INT));
static void record_giv PROTO((struct induction *, rtx, rtx, rtx, rtx, rtx, int, enum g_types, int, int, rtx *, rtx, rtx));
static void update_giv_derive PROTO((rtx));
static int basic_induction_var PROTO((rtx, enum machine_mode, rtx, rtx, rtx *, rtx *, rtx **));
static int basic_induction_var PROTO((rtx, enum machine_mode, rtx, rtx, rtx *, rtx *, rtx **, int *));
static rtx simplify_giv_expr PROTO((rtx, int *));
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 *));
......@@ -3837,9 +3837,11 @@ strength_reduce (scan_start, end, loop_top, insn_count,
&& REGNO (dest_reg) >= FIRST_PSEUDO_REGISTER
&& REG_IV_TYPE (REGNO (dest_reg)) != NOT_BASIC_INDUCT)
{
int multi_insn_incr = 0;
if (basic_induction_var (SET_SRC (set), GET_MODE (SET_SRC (set)),
dest_reg, p, &inc_val, &mult_val,
&location))
&location, &multi_insn_incr))
{
/* It is a possible basic induction variable.
Create and initialize an induction structure for it. */
......@@ -3848,7 +3850,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
= (struct induction *) alloca (sizeof (struct induction));
record_biv (v, p, dest_reg, inc_val, mult_val, location,
not_every_iteration, maybe_multiple);
not_every_iteration, maybe_multiple,
multi_insn_incr);
REG_IV_TYPE (REGNO (dest_reg)) = BASIC_INDUCT;
}
else if (REGNO (dest_reg) < max_reg_before_loop)
......@@ -3976,6 +3979,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
Make a sanity check against n_times_set. */
for (backbl = &loop_iv_list, bl = *backbl; bl; bl = bl->next)
{
int fail = 0;
if (REG_IV_TYPE (bl->regno) != BASIC_INDUCT
/* Above happens if register modified by subreg, etc. */
/* Make sure it is not recognized as a basic induction var: */
......@@ -3983,6 +3988,21 @@ strength_reduce (scan_start, end, loop_top, insn_count,
/* If never incremented, it is invariant that we decided not to
move. So leave it alone. */
|| ! bl->incremented)
fail = 1;
else if (bl->biv_count > 1)
{
/* ??? If we have multiple increments for this BIV, and any of
them take multiple insns to perform the increment, drop the
BIV, since the bit below that converts the extra increments
into GIVs can't handle the multiple insn increment. */
struct induction *v;
for (v = bl->biv; v ; v = v->next_iv)
if (v->multi_insn_incr)
fail = 1;
}
if (fail)
{
if (loop_dump_stream)
fprintf (loop_dump_stream, "Reg %d: biv discarded, %s\n",
......@@ -4453,7 +4473,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
if (loop_dump_stream)
fprintf (loop_dump_stream,
"Increment %d of biv %d converted to giv %d.\n\n",
"Increment %d of biv %d converted to giv %d.\n",
INSN_UID (v->insn), old_regno, new_regno);
}
}
......@@ -5460,7 +5480,7 @@ find_mem_givs (x, insn, not_every_iteration, maybe_multiple, loop_start,
static void
record_biv (v, insn, dest_reg, inc_val, mult_val, location,
not_every_iteration, maybe_multiple)
not_every_iteration, maybe_multiple, multi_insn_incr)
struct induction *v;
rtx insn;
rtx dest_reg;
......@@ -5482,6 +5502,7 @@ record_biv (v, insn, dest_reg, inc_val, mult_val, location,
v->always_computable = ! not_every_iteration;
v->always_executed = ! not_every_iteration;
v->maybe_multiple = maybe_multiple;
v->multi_insn_incr = multi_insn_incr;
/* Add this to the reg's iv_class, creating a class
if this is the first incrementation of the reg. */
......@@ -5589,6 +5610,7 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
v->cant_derive = 0;
v->combined_with = 0;
v->maybe_multiple = maybe_multiple;
v->multi_insn_incr = 0;
v->maybe_dead = 0;
v->derive_adjustment = 0;
v->same = 0;
......@@ -6077,7 +6099,8 @@ update_giv_derive (p)
If we cannot find a biv, we return 0. */
static int
basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val, location)
basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val, location,
multi_insn_incr)
register rtx x;
enum machine_mode mode;
rtx p;
......@@ -6085,6 +6108,7 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val, location)
rtx *inc_val;
rtx *mult_val;
rtx **location;
int *multi_insn_incr;
{
register enum rtx_code code;
rtx *argp, arg;
......@@ -6126,7 +6150,8 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val, location)
value. */
if (SUBREG_PROMOTED_VAR_P (x))
return basic_induction_var (SUBREG_REG (x), GET_MODE (SUBREG_REG (x)),
dest_reg, p, inc_val, mult_val, location);
dest_reg, p, inc_val, mult_val, location,
multi_insn_incr);
return 0;
case REG:
......@@ -6159,8 +6184,12 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val, location)
? GET_MODE (x)
: GET_MODE (SET_SRC (set))),
dest_reg, insn,
inc_val, mult_val, location))
return 1;
inc_val, mult_val, location,
multi_insn_incr))
{
*multi_insn_incr = 1;
return 1;
}
}
/* ... fall through ... */
......@@ -6191,7 +6220,8 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val, location)
case SIGN_EXTEND:
return basic_induction_var (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
dest_reg, p, inc_val, mult_val, location);
dest_reg, p, inc_val, mult_val, location,
multi_insn_incr);
case ASHIFTRT:
/* Similar, since this can be a sign extension. */
......@@ -6208,11 +6238,15 @@ basic_induction_var (x, mode, dest_reg, p, inc_val, mult_val, location)
&& GET_CODE (XEXP (x, 1)) == CONST_INT
&& INTVAL (XEXP (x, 1)) >= 0
&& GET_CODE (SET_SRC (set)) == ASHIFT
&& XEXP (x, 1) == XEXP (SET_SRC (set), 1))
return basic_induction_var (XEXP (SET_SRC (set), 0),
GET_MODE (XEXP (x, 0)),
dest_reg, insn, inc_val, mult_val,
location);
&& XEXP (x, 1) == XEXP (SET_SRC (set), 1)
&& basic_induction_var (XEXP (SET_SRC (set), 0),
GET_MODE (XEXP (x, 0)),
dest_reg, insn, inc_val, mult_val,
location, multi_insn_incr))
{
*multi_insn_incr = 1;
return 1;
}
return 0;
default:
......
......@@ -101,6 +101,7 @@ struct induction
initialized in unrolled loop. */
unsigned shared : 1;
unsigned no_const_addval : 1; /* 1 if add_val does not contain a const. */
unsigned multi_insn_incr : 1; /* 1 if multiple insns updated the biv. */
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
......
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