Commit 3d88d1cd by Richard Sandiford

[36/77] Use scalar_int_mode in the RTL iv routines

This patch changes the iv modes in rtx_iv from machine_mode
to scalar_int_mode.  It also passes the mode of the iv down
to subroutines; this avoids the previous situation in which
the mode information was sometimes lost and had to be added
by the caller on return.

Some routines already took a mode argument, but the patch
tries to standardise on passing it immediately before the
argument it describes.

gcc/
2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

	* cfgloop.h (rtx_iv): Change type of extend_mode and mode to
	scalar_int_mode.
	(niter_desc): Likewise mode.
	(iv_analyze): Add a mode parameter.
	(biv_p): Likewise.
	(iv_analyze_expr): Pass the mode paraeter before the rtx it describes
	and change its type to scalar_int_mode.
	* loop-iv.c: Update commentary at head of file.
	(iv_constant): Pass the mode paraeter before the rtx it describes
	and change its type to scalar_int_mode.  Remove VOIDmode handling.
	(iv_subreg): Change the type of the mode parameter to scalar_int_mode.
	(iv_extend): Likewise.
	(shorten_into_mode): Likewise.
	(iv_add): Use scalar_int_mode.
	(iv_mult): Likewise.
	(iv_shift): Likewise.
	(canonicalize_iv_subregs): Likewise.
	(get_biv_step_1): Pass the outer_mode parameter before the rtx
	it describes and change its mode to scalar_int_mode.   Also change
	the type of the returned inner_mode to scalar_int_mode.
	(get_biv_step): Likewise, turning outer_mode from a pointer
	into a direct parameter.  Update call to get_biv_step_1.
	(iv_analyze_biv): Add an outer_mode parameter.  Update calls to
	iv_constant and get_biv_step.
	(iv_analyze_expr): Pass the mode parameter before the rtx it describes
	and change its type to scalar_int_mode.  Don't initialise iv->mode
	to VOIDmode and remove later checks for its still being VOIDmode.
	Update calls to iv_analyze_op and iv_analyze_expr.  Check
	is_a <scalar_int_mode> when changing the mode under consideration.
	(iv_analyze_def): Ignore registers that don't have a scalar_int_mode.
	Update call to iv_analyze_expr.
	(iv_analyze_op): Add a mode parameter.  Reject subregs whose
	inner register is not also a scalar_int_mode.  Update call to
	iv_analyze_biv.
	(iv_analyze): Add a mode parameter.  Update call to iv_analyze_op.
	(biv_p): Add a mode parameter.  Update call to iv_analyze_biv.
	(iv_number_of_iterations): Use is_a <scalar_int_mode> instead of
	separate mode class checks.  Update calls to iv_analyze.  Remove
	fix-up of VOIDmodes after iv_analyze_biv.
	* loop-unroll.c (analyze_iv_to_split_insn): Reject registers that
	don't have a scalar_int_mode.  Update call to biv_p.

From-SVN: r251488
parent c7ad039d
...@@ -421,10 +421,10 @@ struct rtx_iv ...@@ -421,10 +421,10 @@ struct rtx_iv
rtx delta, mult; rtx delta, mult;
/* The mode it is extended to. */ /* The mode it is extended to. */
machine_mode extend_mode; scalar_int_mode extend_mode;
/* The mode the variable iterates in. */ /* The mode the variable iterates in. */
machine_mode mode; scalar_int_mode mode;
/* Whether the first iteration needs to be handled specially. */ /* Whether the first iteration needs to be handled specially. */
unsigned first_special : 1; unsigned first_special : 1;
...@@ -465,19 +465,19 @@ struct GTY(()) niter_desc ...@@ -465,19 +465,19 @@ struct GTY(()) niter_desc
bool signed_p; bool signed_p;
/* The mode in that niter_expr should be computed. */ /* The mode in that niter_expr should be computed. */
machine_mode mode; scalar_int_mode mode;
/* The number of iterations of the loop. */ /* The number of iterations of the loop. */
rtx niter_expr; rtx niter_expr;
}; };
extern void iv_analysis_loop_init (struct loop *); extern void iv_analysis_loop_init (struct loop *);
extern bool iv_analyze (rtx_insn *, rtx, struct rtx_iv *); extern bool iv_analyze (rtx_insn *, scalar_int_mode, rtx, struct rtx_iv *);
extern bool iv_analyze_result (rtx_insn *, rtx, struct rtx_iv *); extern bool iv_analyze_result (rtx_insn *, rtx, struct rtx_iv *);
extern bool iv_analyze_expr (rtx_insn *, rtx, machine_mode, extern bool iv_analyze_expr (rtx_insn *, scalar_int_mode, rtx,
struct rtx_iv *); struct rtx_iv *);
extern rtx get_iv_value (struct rtx_iv *, rtx); extern rtx get_iv_value (struct rtx_iv *, rtx);
extern bool biv_p (rtx_insn *, rtx); extern bool biv_p (rtx_insn *, scalar_int_mode, rtx);
extern void find_simple_exit (struct loop *, struct niter_desc *); extern void find_simple_exit (struct loop *, struct niter_desc *);
extern void iv_analysis_done (void); extern void iv_analysis_done (void);
......
...@@ -35,16 +35,17 @@ along with GCC; see the file COPYING3. If not see ...@@ -35,16 +35,17 @@ along with GCC; see the file COPYING3. If not see
The available functions are: The available functions are:
iv_analyze (insn, reg, iv): Stores the description of the induction variable iv_analyze (insn, mode, reg, iv): Stores the description of the induction
corresponding to the use of register REG in INSN to IV. Returns true if variable corresponding to the use of register REG in INSN to IV, given
REG is an induction variable in INSN. false otherwise. that REG has mode MODE. Returns true if REG is an induction variable
If use of REG is not found in INSN, following insns are scanned (so that in INSN. false otherwise. If a use of REG is not found in INSN,
we may call this function on insn returned by get_condition). the following insns are scanned (so that we may call this function
on insns returned by get_condition).
iv_analyze_result (insn, def, iv): Stores to IV the description of the iv iv_analyze_result (insn, def, iv): Stores to IV the description of the iv
corresponding to DEF, which is a register defined in INSN. corresponding to DEF, which is a register defined in INSN.
iv_analyze_expr (insn, rhs, mode, iv): Stores to IV the description of iv iv_analyze_expr (insn, mode, expr, iv): Stores to IV the description of iv
corresponding to expression EXPR evaluated at INSN. All registers used bu corresponding to expression EXPR evaluated at INSN. All registers used bu
EXPR must also be used in INSN. EXPR must also be used in INSN. MODE is the mode of EXPR.
*/ */
#include "config.h" #include "config.h"
...@@ -133,7 +134,7 @@ biv_entry_hasher::equal (const biv_entry *b, const rtx_def *r) ...@@ -133,7 +134,7 @@ biv_entry_hasher::equal (const biv_entry *b, const rtx_def *r)
static hash_table<biv_entry_hasher> *bivs; static hash_table<biv_entry_hasher> *bivs;
static bool iv_analyze_op (rtx_insn *, rtx, struct rtx_iv *); static bool iv_analyze_op (rtx_insn *, scalar_int_mode, rtx, struct rtx_iv *);
/* Return the RTX code corresponding to the IV extend code EXTEND. */ /* Return the RTX code corresponding to the IV extend code EXTEND. */
static inline enum rtx_code static inline enum rtx_code
...@@ -383,11 +384,8 @@ iv_get_reaching_def (rtx_insn *insn, rtx reg, df_ref *def) ...@@ -383,11 +384,8 @@ iv_get_reaching_def (rtx_insn *insn, rtx reg, df_ref *def)
consistency with other iv manipulation functions that may fail). */ consistency with other iv manipulation functions that may fail). */
static bool static bool
iv_constant (struct rtx_iv *iv, rtx cst, machine_mode mode) iv_constant (struct rtx_iv *iv, scalar_int_mode mode, rtx cst)
{ {
if (mode == VOIDmode)
mode = GET_MODE (cst);
iv->mode = mode; iv->mode = mode;
iv->base = cst; iv->base = cst;
iv->step = const0_rtx; iv->step = const0_rtx;
...@@ -403,7 +401,7 @@ iv_constant (struct rtx_iv *iv, rtx cst, machine_mode mode) ...@@ -403,7 +401,7 @@ iv_constant (struct rtx_iv *iv, rtx cst, machine_mode mode)
/* Evaluates application of subreg to MODE on IV. */ /* Evaluates application of subreg to MODE on IV. */
static bool static bool
iv_subreg (struct rtx_iv *iv, machine_mode mode) iv_subreg (struct rtx_iv *iv, scalar_int_mode mode)
{ {
/* If iv is invariant, just calculate the new value. */ /* If iv is invariant, just calculate the new value. */
if (iv->step == const0_rtx if (iv->step == const0_rtx
...@@ -445,7 +443,7 @@ iv_subreg (struct rtx_iv *iv, machine_mode mode) ...@@ -445,7 +443,7 @@ iv_subreg (struct rtx_iv *iv, machine_mode mode)
/* Evaluates application of EXTEND to MODE on IV. */ /* Evaluates application of EXTEND to MODE on IV. */
static bool static bool
iv_extend (struct rtx_iv *iv, enum iv_extend_code extend, machine_mode mode) iv_extend (struct rtx_iv *iv, enum iv_extend_code extend, scalar_int_mode mode)
{ {
/* If iv is invariant, just calculate the new value. */ /* If iv is invariant, just calculate the new value. */
if (iv->step == const0_rtx if (iv->step == const0_rtx
...@@ -508,7 +506,7 @@ iv_neg (struct rtx_iv *iv) ...@@ -508,7 +506,7 @@ iv_neg (struct rtx_iv *iv)
static bool static bool
iv_add (struct rtx_iv *iv0, struct rtx_iv *iv1, enum rtx_code op) iv_add (struct rtx_iv *iv0, struct rtx_iv *iv1, enum rtx_code op)
{ {
machine_mode mode; scalar_int_mode mode;
rtx arg; rtx arg;
/* Extend the constant to extend_mode of the other operand if necessary. */ /* Extend the constant to extend_mode of the other operand if necessary. */
...@@ -578,7 +576,7 @@ iv_add (struct rtx_iv *iv0, struct rtx_iv *iv1, enum rtx_code op) ...@@ -578,7 +576,7 @@ iv_add (struct rtx_iv *iv0, struct rtx_iv *iv1, enum rtx_code op)
static bool static bool
iv_mult (struct rtx_iv *iv, rtx mby) iv_mult (struct rtx_iv *iv, rtx mby)
{ {
machine_mode mode = iv->extend_mode; scalar_int_mode mode = iv->extend_mode;
if (GET_MODE (mby) != VOIDmode if (GET_MODE (mby) != VOIDmode
&& GET_MODE (mby) != mode) && GET_MODE (mby) != mode)
...@@ -603,7 +601,7 @@ iv_mult (struct rtx_iv *iv, rtx mby) ...@@ -603,7 +601,7 @@ iv_mult (struct rtx_iv *iv, rtx mby)
static bool static bool
iv_shift (struct rtx_iv *iv, rtx mby) iv_shift (struct rtx_iv *iv, rtx mby)
{ {
machine_mode mode = iv->extend_mode; scalar_int_mode mode = iv->extend_mode;
if (GET_MODE (mby) != VOIDmode if (GET_MODE (mby) != VOIDmode
&& GET_MODE (mby) != mode) && GET_MODE (mby) != mode)
...@@ -628,9 +626,9 @@ iv_shift (struct rtx_iv *iv, rtx mby) ...@@ -628,9 +626,9 @@ iv_shift (struct rtx_iv *iv, rtx mby)
at get_biv_step. */ at get_biv_step. */
static bool static bool
get_biv_step_1 (df_ref def, rtx reg, get_biv_step_1 (df_ref def, scalar_int_mode outer_mode, rtx reg,
rtx *inner_step, machine_mode *inner_mode, rtx *inner_step, scalar_int_mode *inner_mode,
enum iv_extend_code *extend, machine_mode outer_mode, enum iv_extend_code *extend,
rtx *outer_step) rtx *outer_step)
{ {
rtx set, rhs, op0 = NULL_RTX, op1 = NULL_RTX; rtx set, rhs, op0 = NULL_RTX, op1 = NULL_RTX;
...@@ -732,8 +730,8 @@ get_biv_step_1 (df_ref def, rtx reg, ...@@ -732,8 +730,8 @@ get_biv_step_1 (df_ref def, rtx reg,
*inner_mode = outer_mode; *inner_mode = outer_mode;
*outer_step = const0_rtx; *outer_step = const0_rtx;
} }
else if (!get_biv_step_1 (next_def, reg, else if (!get_biv_step_1 (next_def, outer_mode, reg,
inner_step, inner_mode, extend, outer_mode, inner_step, inner_mode, extend,
outer_step)) outer_step))
return false; return false;
...@@ -793,19 +791,17 @@ get_biv_step_1 (df_ref def, rtx reg, ...@@ -793,19 +791,17 @@ get_biv_step_1 (df_ref def, rtx reg,
LAST_DEF is the definition of REG that dominates loop latch. */ LAST_DEF is the definition of REG that dominates loop latch. */
static bool static bool
get_biv_step (df_ref last_def, rtx reg, rtx *inner_step, get_biv_step (df_ref last_def, scalar_int_mode outer_mode, rtx reg,
machine_mode *inner_mode, enum iv_extend_code *extend, rtx *inner_step, scalar_int_mode *inner_mode,
machine_mode *outer_mode, rtx *outer_step) enum iv_extend_code *extend, rtx *outer_step)
{ {
*outer_mode = GET_MODE (reg); if (!get_biv_step_1 (last_def, outer_mode, reg,
inner_step, inner_mode, extend,
if (!get_biv_step_1 (last_def, reg,
inner_step, inner_mode, extend, *outer_mode,
outer_step)) outer_step))
return false; return false;
gcc_assert ((*inner_mode == *outer_mode) != (*extend != IV_UNKNOWN_EXTEND)); gcc_assert ((*inner_mode == outer_mode) != (*extend != IV_UNKNOWN_EXTEND));
gcc_assert (*inner_mode != *outer_mode || *outer_step == const0_rtx); gcc_assert (*inner_mode != outer_mode || *outer_step == const0_rtx);
return true; return true;
} }
...@@ -850,13 +846,13 @@ record_biv (rtx def, struct rtx_iv *iv) ...@@ -850,13 +846,13 @@ record_biv (rtx def, struct rtx_iv *iv)
} }
/* Determines whether DEF is a biv and if so, stores its description /* Determines whether DEF is a biv and if so, stores its description
to *IV. */ to *IV. OUTER_MODE is the mode of DEF. */
static bool static bool
iv_analyze_biv (rtx def, struct rtx_iv *iv) iv_analyze_biv (scalar_int_mode outer_mode, rtx def, struct rtx_iv *iv)
{ {
rtx inner_step, outer_step; rtx inner_step, outer_step;
machine_mode inner_mode, outer_mode; scalar_int_mode inner_mode;
enum iv_extend_code extend; enum iv_extend_code extend;
df_ref last_def; df_ref last_def;
...@@ -872,7 +868,7 @@ iv_analyze_biv (rtx def, struct rtx_iv *iv) ...@@ -872,7 +868,7 @@ iv_analyze_biv (rtx def, struct rtx_iv *iv)
if (!CONSTANT_P (def)) if (!CONSTANT_P (def))
return false; return false;
return iv_constant (iv, def, VOIDmode); return iv_constant (iv, outer_mode, def);
} }
if (!latch_dominating_def (def, &last_def)) if (!latch_dominating_def (def, &last_def))
...@@ -883,7 +879,7 @@ iv_analyze_biv (rtx def, struct rtx_iv *iv) ...@@ -883,7 +879,7 @@ iv_analyze_biv (rtx def, struct rtx_iv *iv)
} }
if (!last_def) if (!last_def)
return iv_constant (iv, def, VOIDmode); return iv_constant (iv, outer_mode, def);
if (analyzed_for_bivness_p (def, iv)) if (analyzed_for_bivness_p (def, iv))
{ {
...@@ -892,8 +888,8 @@ iv_analyze_biv (rtx def, struct rtx_iv *iv) ...@@ -892,8 +888,8 @@ iv_analyze_biv (rtx def, struct rtx_iv *iv)
return iv->base != NULL_RTX; return iv->base != NULL_RTX;
} }
if (!get_biv_step (last_def, def, &inner_step, &inner_mode, &extend, if (!get_biv_step (last_def, outer_mode, def, &inner_step, &inner_mode,
&outer_mode, &outer_step)) &extend, &outer_step))
{ {
iv->base = NULL_RTX; iv->base = NULL_RTX;
goto end; goto end;
...@@ -930,16 +926,15 @@ iv_analyze_biv (rtx def, struct rtx_iv *iv) ...@@ -930,16 +926,15 @@ iv_analyze_biv (rtx def, struct rtx_iv *iv)
The mode of the induction variable is MODE. */ The mode of the induction variable is MODE. */
bool bool
iv_analyze_expr (rtx_insn *insn, rtx rhs, machine_mode mode, iv_analyze_expr (rtx_insn *insn, scalar_int_mode mode, rtx rhs,
struct rtx_iv *iv) struct rtx_iv *iv)
{ {
rtx mby = NULL_RTX; rtx mby = NULL_RTX;
rtx op0 = NULL_RTX, op1 = NULL_RTX; rtx op0 = NULL_RTX, op1 = NULL_RTX;
struct rtx_iv iv0, iv1; struct rtx_iv iv0, iv1;
enum rtx_code code = GET_CODE (rhs); enum rtx_code code = GET_CODE (rhs);
machine_mode omode = mode; scalar_int_mode omode = mode;
iv->mode = VOIDmode;
iv->base = NULL_RTX; iv->base = NULL_RTX;
iv->step = NULL_RTX; iv->step = NULL_RTX;
...@@ -948,18 +943,7 @@ iv_analyze_expr (rtx_insn *insn, rtx rhs, machine_mode mode, ...@@ -948,18 +943,7 @@ iv_analyze_expr (rtx_insn *insn, rtx rhs, machine_mode mode,
if (CONSTANT_P (rhs) if (CONSTANT_P (rhs)
|| REG_P (rhs) || REG_P (rhs)
|| code == SUBREG) || code == SUBREG)
{ return iv_analyze_op (insn, mode, rhs, iv);
if (!iv_analyze_op (insn, rhs, iv))
return false;
if (iv->mode == VOIDmode)
{
iv->mode = mode;
iv->extend_mode = mode;
}
return true;
}
switch (code) switch (code)
{ {
...@@ -971,7 +955,9 @@ iv_analyze_expr (rtx_insn *insn, rtx rhs, machine_mode mode, ...@@ -971,7 +955,9 @@ iv_analyze_expr (rtx_insn *insn, rtx rhs, machine_mode mode,
case ZERO_EXTEND: case ZERO_EXTEND:
case NEG: case NEG:
op0 = XEXP (rhs, 0); op0 = XEXP (rhs, 0);
omode = GET_MODE (op0); /* We don't know how many bits there are in a sign-extended constant. */
if (!is_a <scalar_int_mode> (GET_MODE (op0), &omode))
return false;
break; break;
case PLUS: case PLUS:
...@@ -1001,11 +987,11 @@ iv_analyze_expr (rtx_insn *insn, rtx rhs, machine_mode mode, ...@@ -1001,11 +987,11 @@ iv_analyze_expr (rtx_insn *insn, rtx rhs, machine_mode mode,
} }
if (op0 if (op0
&& !iv_analyze_expr (insn, op0, omode, &iv0)) && !iv_analyze_expr (insn, omode, op0, &iv0))
return false; return false;
if (op1 if (op1
&& !iv_analyze_expr (insn, op1, omode, &iv1)) && !iv_analyze_expr (insn, omode, op1, &iv1))
return false; return false;
switch (code) switch (code)
...@@ -1075,11 +1061,11 @@ iv_analyze_def (df_ref def, struct rtx_iv *iv) ...@@ -1075,11 +1061,11 @@ iv_analyze_def (df_ref def, struct rtx_iv *iv)
return iv->base != NULL_RTX; return iv->base != NULL_RTX;
} }
iv->mode = VOIDmode;
iv->base = NULL_RTX; iv->base = NULL_RTX;
iv->step = NULL_RTX; iv->step = NULL_RTX;
if (!REG_P (reg)) scalar_int_mode mode;
if (!REG_P (reg) || !is_a <scalar_int_mode> (GET_MODE (reg), &mode))
return false; return false;
set = single_set (insn); set = single_set (insn);
...@@ -1096,7 +1082,7 @@ iv_analyze_def (df_ref def, struct rtx_iv *iv) ...@@ -1096,7 +1082,7 @@ iv_analyze_def (df_ref def, struct rtx_iv *iv)
else else
rhs = SET_SRC (set); rhs = SET_SRC (set);
iv_analyze_expr (insn, rhs, GET_MODE (reg), iv); iv_analyze_expr (insn, mode, rhs, iv);
record_iv (def, iv); record_iv (def, iv);
if (dump_file) if (dump_file)
...@@ -1112,10 +1098,11 @@ iv_analyze_def (df_ref def, struct rtx_iv *iv) ...@@ -1112,10 +1098,11 @@ iv_analyze_def (df_ref def, struct rtx_iv *iv)
return iv->base != NULL_RTX; return iv->base != NULL_RTX;
} }
/* Analyzes operand OP of INSN and stores the result to *IV. */ /* Analyzes operand OP of INSN and stores the result to *IV. MODE is the
mode of OP. */
static bool static bool
iv_analyze_op (rtx_insn *insn, rtx op, struct rtx_iv *iv) iv_analyze_op (rtx_insn *insn, scalar_int_mode mode, rtx op, struct rtx_iv *iv)
{ {
df_ref def = NULL; df_ref def = NULL;
enum iv_grd_result res; enum iv_grd_result res;
...@@ -1132,13 +1119,15 @@ iv_analyze_op (rtx_insn *insn, rtx op, struct rtx_iv *iv) ...@@ -1132,13 +1119,15 @@ iv_analyze_op (rtx_insn *insn, rtx op, struct rtx_iv *iv)
res = GRD_INVARIANT; res = GRD_INVARIANT;
else if (GET_CODE (op) == SUBREG) else if (GET_CODE (op) == SUBREG)
{ {
if (!subreg_lowpart_p (op)) scalar_int_mode inner_mode;
if (!subreg_lowpart_p (op)
|| !is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &inner_mode))
return false; return false;
if (!iv_analyze_op (insn, SUBREG_REG (op), iv)) if (!iv_analyze_op (insn, inner_mode, SUBREG_REG (op), iv))
return false; return false;
return iv_subreg (iv, GET_MODE (op)); return iv_subreg (iv, mode);
} }
else else
{ {
...@@ -1153,7 +1142,7 @@ iv_analyze_op (rtx_insn *insn, rtx op, struct rtx_iv *iv) ...@@ -1153,7 +1142,7 @@ iv_analyze_op (rtx_insn *insn, rtx op, struct rtx_iv *iv)
if (res == GRD_INVARIANT) if (res == GRD_INVARIANT)
{ {
iv_constant (iv, op, VOIDmode); iv_constant (iv, mode, op);
if (dump_file) if (dump_file)
{ {
...@@ -1165,15 +1154,16 @@ iv_analyze_op (rtx_insn *insn, rtx op, struct rtx_iv *iv) ...@@ -1165,15 +1154,16 @@ iv_analyze_op (rtx_insn *insn, rtx op, struct rtx_iv *iv)
} }
if (res == GRD_MAYBE_BIV) if (res == GRD_MAYBE_BIV)
return iv_analyze_biv (op, iv); return iv_analyze_biv (mode, op, iv);
return iv_analyze_def (def, iv); return iv_analyze_def (def, iv);
} }
/* Analyzes value VAL at INSN and stores the result to *IV. */ /* Analyzes value VAL at INSN and stores the result to *IV. MODE is the
mode of VAL. */
bool bool
iv_analyze (rtx_insn *insn, rtx val, struct rtx_iv *iv) iv_analyze (rtx_insn *insn, scalar_int_mode mode, rtx val, struct rtx_iv *iv)
{ {
rtx reg; rtx reg;
...@@ -1192,7 +1182,7 @@ iv_analyze (rtx_insn *insn, rtx val, struct rtx_iv *iv) ...@@ -1192,7 +1182,7 @@ iv_analyze (rtx_insn *insn, rtx val, struct rtx_iv *iv)
insn = NEXT_INSN (insn); insn = NEXT_INSN (insn);
} }
return iv_analyze_op (insn, val, iv); return iv_analyze_op (insn, mode, val, iv);
} }
/* Analyzes definition of DEF in INSN and stores the result to IV. */ /* Analyzes definition of DEF in INSN and stores the result to IV. */
...@@ -1210,11 +1200,13 @@ iv_analyze_result (rtx_insn *insn, rtx def, struct rtx_iv *iv) ...@@ -1210,11 +1200,13 @@ iv_analyze_result (rtx_insn *insn, rtx def, struct rtx_iv *iv)
} }
/* Checks whether definition of register REG in INSN is a basic induction /* Checks whether definition of register REG in INSN is a basic induction
variable. IV analysis must have been initialized (via a call to variable. MODE is the mode of REG.
IV analysis must have been initialized (via a call to
iv_analysis_loop_init) for this function to produce a result. */ iv_analysis_loop_init) for this function to produce a result. */
bool bool
biv_p (rtx_insn *insn, rtx reg) biv_p (rtx_insn *insn, scalar_int_mode mode, rtx reg)
{ {
struct rtx_iv iv; struct rtx_iv iv;
df_ref def, last_def; df_ref def, last_def;
...@@ -1229,7 +1221,7 @@ biv_p (rtx_insn *insn, rtx reg) ...@@ -1229,7 +1221,7 @@ biv_p (rtx_insn *insn, rtx reg)
if (last_def != def) if (last_def != def)
return false; return false;
if (!iv_analyze_biv (reg, &iv)) if (!iv_analyze_biv (mode, reg, &iv))
return false; return false;
return iv.step != const0_rtx; return iv.step != const0_rtx;
...@@ -2078,7 +2070,7 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr) ...@@ -2078,7 +2070,7 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
is SIGNED_P to DESC. */ is SIGNED_P to DESC. */
static void static void
shorten_into_mode (struct rtx_iv *iv, machine_mode mode, shorten_into_mode (struct rtx_iv *iv, scalar_int_mode mode,
enum rtx_code cond, bool signed_p, struct niter_desc *desc) enum rtx_code cond, bool signed_p, struct niter_desc *desc)
{ {
rtx mmin, mmax, cond_over, cond_under; rtx mmin, mmax, cond_over, cond_under;
...@@ -2140,7 +2132,7 @@ static bool ...@@ -2140,7 +2132,7 @@ static bool
canonicalize_iv_subregs (struct rtx_iv *iv0, struct rtx_iv *iv1, canonicalize_iv_subregs (struct rtx_iv *iv0, struct rtx_iv *iv1,
enum rtx_code cond, struct niter_desc *desc) enum rtx_code cond, struct niter_desc *desc)
{ {
machine_mode comp_mode; scalar_int_mode comp_mode;
bool signed_p; bool signed_p;
/* If the ivs behave specially in the first iteration, or are /* If the ivs behave specially in the first iteration, or are
...@@ -2318,7 +2310,8 @@ iv_number_of_iterations (struct loop *loop, rtx_insn *insn, rtx condition, ...@@ -2318,7 +2310,8 @@ iv_number_of_iterations (struct loop *loop, rtx_insn *insn, rtx condition,
struct rtx_iv iv0, iv1; struct rtx_iv iv0, iv1;
rtx assumption, may_not_xform; rtx assumption, may_not_xform;
enum rtx_code cond; enum rtx_code cond;
machine_mode mode, comp_mode; machine_mode nonvoid_mode;
scalar_int_mode comp_mode;
rtx mmin, mmax, mode_mmin, mode_mmax; rtx mmin, mmax, mode_mmin, mode_mmax;
uint64_t s, size, d, inv, max, up, down; uint64_t s, size, d, inv, max, up, down;
int64_t inc, step_val; int64_t inc, step_val;
...@@ -2343,28 +2336,24 @@ iv_number_of_iterations (struct loop *loop, rtx_insn *insn, rtx condition, ...@@ -2343,28 +2336,24 @@ iv_number_of_iterations (struct loop *loop, rtx_insn *insn, rtx condition,
cond = GET_CODE (condition); cond = GET_CODE (condition);
gcc_assert (COMPARISON_P (condition)); gcc_assert (COMPARISON_P (condition));
mode = GET_MODE (XEXP (condition, 0)); nonvoid_mode = GET_MODE (XEXP (condition, 0));
if (mode == VOIDmode) if (nonvoid_mode == VOIDmode)
mode = GET_MODE (XEXP (condition, 1)); nonvoid_mode = GET_MODE (XEXP (condition, 1));
/* The constant comparisons should be folded. */ /* The constant comparisons should be folded. */
gcc_assert (mode != VOIDmode); gcc_assert (nonvoid_mode != VOIDmode);
/* We only handle integers or pointers. */ /* We only handle integers or pointers. */
if (GET_MODE_CLASS (mode) != MODE_INT scalar_int_mode mode;
&& GET_MODE_CLASS (mode) != MODE_PARTIAL_INT) if (!is_a <scalar_int_mode> (nonvoid_mode, &mode))
goto fail; goto fail;
op0 = XEXP (condition, 0); op0 = XEXP (condition, 0);
if (!iv_analyze (insn, op0, &iv0)) if (!iv_analyze (insn, mode, op0, &iv0))
goto fail; goto fail;
if (iv0.extend_mode == VOIDmode)
iv0.mode = iv0.extend_mode = mode;
op1 = XEXP (condition, 1); op1 = XEXP (condition, 1);
if (!iv_analyze (insn, op1, &iv1)) if (!iv_analyze (insn, mode, op1, &iv1))
goto fail; goto fail;
if (iv1.extend_mode == VOIDmode)
iv1.mode = iv1.extend_mode = mode;
if (GET_MODE_BITSIZE (iv0.extend_mode) > HOST_BITS_PER_WIDE_INT if (GET_MODE_BITSIZE (iv0.extend_mode) > HOST_BITS_PER_WIDE_INT
|| GET_MODE_BITSIZE (iv1.extend_mode) > HOST_BITS_PER_WIDE_INT) || GET_MODE_BITSIZE (iv1.extend_mode) > HOST_BITS_PER_WIDE_INT)
......
...@@ -1509,6 +1509,7 @@ analyze_iv_to_split_insn (rtx_insn *insn) ...@@ -1509,6 +1509,7 @@ analyze_iv_to_split_insn (rtx_insn *insn)
rtx set, dest; rtx set, dest;
struct rtx_iv iv; struct rtx_iv iv;
struct iv_to_split *ivts; struct iv_to_split *ivts;
scalar_int_mode mode;
bool ok; bool ok;
/* For now we just split the basic induction variables. Later this may be /* For now we just split the basic induction variables. Later this may be
...@@ -1518,10 +1519,10 @@ analyze_iv_to_split_insn (rtx_insn *insn) ...@@ -1518,10 +1519,10 @@ analyze_iv_to_split_insn (rtx_insn *insn)
return NULL; return NULL;
dest = SET_DEST (set); dest = SET_DEST (set);
if (!REG_P (dest)) if (!REG_P (dest) || !is_a <scalar_int_mode> (GET_MODE (dest), &mode))
return NULL; return NULL;
if (!biv_p (insn, dest)) if (!biv_p (insn, mode, dest))
return NULL; return NULL;
ok = iv_analyze_result (insn, dest, &iv); ok = iv_analyze_result (insn, dest, &iv);
......
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