mirror of git://gcc.gnu.org/git/gcc.git
loop.c (check_ext_dependent_givs): Pass const struct loop * instead of struct loop_info * as argument.
* loop.c (check_ext_dependent_givs): Pass const struct loop * instead of struct loop_info * as argument. Accept BIVs with increment +/- 1 provided there is a friendly exit test against a loop-invariant value. (strength_reduce): Adapt call to check_ext_dependent_givs. From-SVN: r69489
This commit is contained in:
parent
1129e7f414
commit
03988cac58
|
|
@ -1,3 +1,11 @@
|
||||||
|
2003-07-16 Ulrich Weigand <uweigand@de.ibm.com>
|
||||||
|
|
||||||
|
* loop.c (check_ext_dependent_givs): Pass const struct loop *
|
||||||
|
instead of struct loop_info * as argument. Accept BIVs with
|
||||||
|
increment +/- 1 provided there is a friendly exit test against
|
||||||
|
a loop-invariant value.
|
||||||
|
(strength_reduce): Adapt call to check_ext_dependent_givs.
|
||||||
|
|
||||||
2003-07-16 J"orn Rennecke <joern.rennecke@superh.com>
|
2003-07-16 J"orn Rennecke <joern.rennecke@superh.com>
|
||||||
Con Bradley <con.bradley@superh.com>
|
Con Bradley <con.bradley@superh.com>
|
||||||
|
|
||||||
|
|
|
||||||
46
gcc/loop.c
46
gcc/loop.c
|
|
@ -293,7 +293,7 @@ static void record_giv (const struct loop *, struct induction *, rtx, rtx,
|
||||||
rtx, rtx, rtx, rtx, int, enum g_types, int, int,
|
rtx, rtx, rtx, rtx, int, enum g_types, int, int,
|
||||||
rtx *);
|
rtx *);
|
||||||
static void update_giv_derive (const struct loop *, rtx);
|
static void update_giv_derive (const struct loop *, rtx);
|
||||||
static void check_ext_dependent_givs (struct iv_class *, struct loop_info *);
|
static void check_ext_dependent_givs (const struct loop *, struct iv_class *);
|
||||||
static int basic_induction_var (const struct loop *, rtx, enum machine_mode,
|
static int basic_induction_var (const struct loop *, rtx, enum machine_mode,
|
||||||
rtx, rtx, rtx *, rtx *, rtx **);
|
rtx, rtx, rtx *, rtx *, rtx **);
|
||||||
static rtx simplify_giv_expr (const struct loop *, rtx, rtx *, int *);
|
static rtx simplify_giv_expr (const struct loop *, rtx, rtx *, int *);
|
||||||
|
|
@ -5143,7 +5143,7 @@ strength_reduce (struct loop *loop, int flags)
|
||||||
|
|
||||||
/* Check each extension dependent giv in this class to see if its
|
/* Check each extension dependent giv in this class to see if its
|
||||||
root biv is safe from wrapping in the interior mode. */
|
root biv is safe from wrapping in the interior mode. */
|
||||||
check_ext_dependent_givs (bl, loop_info);
|
check_ext_dependent_givs (loop, bl);
|
||||||
|
|
||||||
/* Combine all giv's for this iv_class. */
|
/* Combine all giv's for this iv_class. */
|
||||||
combine_givs (regs, bl);
|
combine_givs (regs, bl);
|
||||||
|
|
@ -7286,8 +7286,9 @@ combine_givs_p (struct induction *g1, struct induction *g2)
|
||||||
make the giv illegal. */
|
make the giv illegal. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
check_ext_dependent_givs (struct iv_class *bl, struct loop_info *loop_info)
|
check_ext_dependent_givs (const struct loop *loop, struct iv_class *bl)
|
||||||
{
|
{
|
||||||
|
struct loop_info *loop_info = LOOP_INFO (loop);
|
||||||
int ze_ok = 0, se_ok = 0, info_ok = 0;
|
int ze_ok = 0, se_ok = 0, info_ok = 0;
|
||||||
enum machine_mode biv_mode = GET_MODE (bl->biv->src_reg);
|
enum machine_mode biv_mode = GET_MODE (bl->biv->src_reg);
|
||||||
HOST_WIDE_INT start_val;
|
HOST_WIDE_INT start_val;
|
||||||
|
|
@ -7298,9 +7299,6 @@ check_ext_dependent_givs (struct iv_class *bl, struct loop_info *loop_info)
|
||||||
|
|
||||||
/* Make sure the iteration data is available. We must have
|
/* Make sure the iteration data is available. We must have
|
||||||
constants in order to be certain of no overflow. */
|
constants in order to be certain of no overflow. */
|
||||||
/* ??? An unknown iteration count with an increment of +-1
|
|
||||||
combined with friendly exit tests of against an invariant
|
|
||||||
value is also amenable to optimization. Not implemented. */
|
|
||||||
if (loop_info->n_iterations > 0
|
if (loop_info->n_iterations > 0
|
||||||
&& bl->initial_value
|
&& bl->initial_value
|
||||||
&& GET_CODE (bl->initial_value) == CONST_INT
|
&& GET_CODE (bl->initial_value) == CONST_INT
|
||||||
|
|
@ -7367,6 +7365,37 @@ check_ext_dependent_givs (struct iv_class *bl, struct loop_info *loop_info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we know the BIV is compared at run-time against an
|
||||||
|
invariant value, and the increment is +/- 1, we may also
|
||||||
|
be able to prove that the BIV cannot overflow. */
|
||||||
|
else if (bl->biv->src_reg == loop_info->iteration_var
|
||||||
|
&& loop_info->comparison_value
|
||||||
|
&& loop_invariant_p (loop, loop_info->comparison_value)
|
||||||
|
&& (incr = biv_total_increment (bl))
|
||||||
|
&& GET_CODE (incr) == CONST_INT)
|
||||||
|
{
|
||||||
|
/* If the increment is +1, and the exit test is a <,
|
||||||
|
the BIV cannot overflow. (For <=, we have the
|
||||||
|
problematic case that the comparison value might
|
||||||
|
be the maximum value of the range.) */
|
||||||
|
if (INTVAL (incr) == 1)
|
||||||
|
{
|
||||||
|
if (loop_info->comparison_code == LT)
|
||||||
|
se_ok = ze_ok = 1;
|
||||||
|
else if (loop_info->comparison_code == LTU)
|
||||||
|
ze_ok = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Likewise for increment -1 and exit test >. */
|
||||||
|
if (INTVAL (incr) == -1)
|
||||||
|
{
|
||||||
|
if (loop_info->comparison_code == GT)
|
||||||
|
se_ok = ze_ok = 1;
|
||||||
|
else if (loop_info->comparison_code == GTU)
|
||||||
|
ze_ok = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Invalidate givs that fail the tests. */
|
/* Invalidate givs that fail the tests. */
|
||||||
for (v = bl->giv; v; v = v->next_iv)
|
for (v = bl->giv; v; v = v->next_iv)
|
||||||
if (v->ext_dependent)
|
if (v->ext_dependent)
|
||||||
|
|
@ -7388,8 +7417,9 @@ check_ext_dependent_givs (struct iv_class *bl, struct loop_info *loop_info)
|
||||||
signed or unsigned, so to safely truncate we must satisfy
|
signed or unsigned, so to safely truncate we must satisfy
|
||||||
both. The initial check here verifies the BIV itself;
|
both. The initial check here verifies the BIV itself;
|
||||||
once that is successful we may check its range wrt the
|
once that is successful we may check its range wrt the
|
||||||
derived GIV. */
|
derived GIV. This works only if we were able to determine
|
||||||
if (se_ok && ze_ok)
|
constant start and end values above. */
|
||||||
|
if (se_ok && ze_ok && info_ok)
|
||||||
{
|
{
|
||||||
enum machine_mode outer_mode = GET_MODE (v->ext_dependent);
|
enum machine_mode outer_mode = GET_MODE (v->ext_dependent);
|
||||||
unsigned HOST_WIDE_INT max = GET_MODE_MASK (outer_mode) >> 1;
|
unsigned HOST_WIDE_INT max = GET_MODE_MASK (outer_mode) >> 1;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue