loop.h (loop_insn_first_p): Declare.
* loop.h (loop_insn_first_p): Declare. * loop.c (loop_insn_first_p): No longer static. * unroll.c (iteration_info) Fix comparison to reg_iv_type->num_elements. Before accessing reg_biv_class, check index against max_reg_before_loop. Fix and enable code for giv iterators. (loop_iterations): Compare with reg_iv_type->num_elements instead of with max_reg_before_loop. From-SVN: r25401
This commit is contained in:
parent
ddce352881
commit
c99f8c2a3e
@ -1,3 +1,15 @@
|
||||
Wed Feb 24 19:47:56 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
|
||||
|
||||
* loop.h (loop_insn_first_p): Declare.
|
||||
* loop.c (loop_insn_first_p): No longer static.
|
||||
* unroll.c (iteration_info) Fix comparison to
|
||||
reg_iv_type->num_elements.
|
||||
Before accessing reg_biv_class, check index against
|
||||
max_reg_before_loop.
|
||||
Fix and enable code for giv iterators.
|
||||
(loop_iterations): Compare with reg_iv_type->num_elements instead
|
||||
of with max_reg_before_loop.
|
||||
|
||||
Wed Feb 24 19:17:11 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
|
||||
|
||||
* unroll.c (unroll_loop): Avoid out-of-bounds index for local_regno.
|
||||
|
@ -376,8 +376,6 @@ static int indirect_jump_in_function_p PROTO((rtx));
|
||||
|
||||
static int compute_luids PROTO((rtx, rtx, int));
|
||||
|
||||
static int loop_insn_first_p PROTO((rtx, rtx));
|
||||
|
||||
static int biv_elimination_giv_has_0_offset PROTO((struct induction *,
|
||||
struct induction *, rtx));
|
||||
|
||||
@ -8112,7 +8110,7 @@ maybe_eliminate_biv (bl, loop_start, end, eliminate_p, threshold, insn_count)
|
||||
This is like insn_first_p, except that we use the luid information if
|
||||
available. */
|
||||
|
||||
static int
|
||||
int
|
||||
loop_insn_first_p (insn, reference)
|
||||
rtx insn, reference;
|
||||
{
|
||||
|
@ -228,10 +228,6 @@ 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));
|
||||
void unroll_block_trees PROTO((void));
|
||||
|
||||
void unroll_loop PROTO((rtx, int, rtx, rtx, struct loop_info *, int));
|
||||
rtx biv_total_increment PROTO((struct iv_class *, rtx, rtx));
|
||||
unsigned HOST_WIDE_INT loop_iterations PROTO((rtx, rtx, struct loop_info *));
|
||||
@ -244,7 +240,10 @@ rtx final_giv_value PROTO((struct induction *, rtx, rtx,
|
||||
unsigned HOST_WIDE_INT));
|
||||
void emit_unrolled_add PROTO((rtx, rtx, rtx));
|
||||
int back_branch_in_range_p PROTO((rtx, rtx, rtx));
|
||||
int loop_insn_first_p PROTO((rtx, rtx));
|
||||
|
||||
extern int *loop_unroll_number;
|
||||
|
||||
|
||||
/* Forward declarations for non-static functions declared in stmt.c. */
|
||||
void find_loop_tree_blocks PROTO((void));
|
||||
void unroll_block_trees PROTO((void));
|
||||
|
77
gcc/unroll.c
77
gcc/unroll.c
@ -1404,10 +1404,9 @@ precondition_loop_p (loop_start, loop_info,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ??? Note that if iteration_info is modifed to allow GIV iterators
|
||||
such as "while (i-- > 0)", the initial value will be one too small.
|
||||
In this case, loop_iteration_var could be used to determine
|
||||
the correct initial value, provided the loop has not been reversed.
|
||||
/* Note that iteration_info biases the initial value for GIV iterators
|
||||
such as "while (i-- > 0)" so that we can calculate the number of
|
||||
iterations just like for BIV iterators.
|
||||
|
||||
Also note that the absolute values of initial_value and
|
||||
final_value are unimportant as only their difference is used for
|
||||
@ -2364,7 +2363,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
|
||||
|
||||
/* If this is a new register, can't handle it since we don't have any
|
||||
reg_iv_type entry for it. */
|
||||
if ((unsigned) REGNO (iteration_var) > reg_iv_type->num_elements)
|
||||
if ((unsigned) REGNO (iteration_var) >= reg_iv_type->num_elements)
|
||||
{
|
||||
if (loop_dump_stream)
|
||||
fprintf (loop_dump_stream,
|
||||
@ -2392,6 +2391,12 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
|
||||
}
|
||||
else if (REG_IV_TYPE (REGNO (iteration_var)) == BASIC_INDUCT)
|
||||
{
|
||||
/* When reg_iv_type / reg_iv_info is resized for biv increments
|
||||
that are turned into givs, reg_biv_class is not resized.
|
||||
So check here that we don't make an out-of-bounds access. */
|
||||
if (REGNO (iteration_var) >= max_reg_before_loop)
|
||||
abort ();
|
||||
|
||||
/* Grab initial value, only useful if it is a constant. */
|
||||
bl = reg_biv_class[REGNO (iteration_var)];
|
||||
*initial_value = bl->initial_value;
|
||||
@ -2400,34 +2405,46 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end)
|
||||
}
|
||||
else if (REG_IV_TYPE (REGNO (iteration_var)) == GENERAL_INDUCT)
|
||||
{
|
||||
#if 1
|
||||
/* ??? The code below does not work because the incorrect number of
|
||||
iterations is calculated when the biv is incremented after the giv
|
||||
is set (which is the usual case). This can probably be accounted
|
||||
for by biasing the initial_value by subtracting the amount of the
|
||||
increment that occurs between the giv set and the giv test. However,
|
||||
a giv as an iterator is very rare, so it does not seem worthwhile
|
||||
to handle this. */
|
||||
/* ??? An example failure is: i = 6; do {;} while (i++ < 9). */
|
||||
if (loop_dump_stream)
|
||||
fprintf (loop_dump_stream,
|
||||
"Loop unrolling: Giv iterators are not handled.\n");
|
||||
return;
|
||||
#else
|
||||
/* Initial value is mult_val times the biv's initial value plus
|
||||
add_val. Only useful if it is a constant. */
|
||||
v = REG_IV_INFO (REGNO (iteration_var));
|
||||
HOST_WIDE_INT offset = 0;
|
||||
struct induction *v = REG_IV_INFO (REGNO (iteration_var));
|
||||
|
||||
if (REGNO (v->src_reg) >= max_reg_before_loop)
|
||||
abort ();
|
||||
|
||||
bl = reg_biv_class[REGNO (v->src_reg)];
|
||||
*initial_value = fold_rtx_mult_add (v->mult_val, bl->initial_value,
|
||||
v->add_val, v->mode);
|
||||
|
||||
/* Increment value is mult_val times the increment value of the biv. */
|
||||
|
||||
*increment = biv_total_increment (bl, loop_start, loop_end);
|
||||
if (*increment)
|
||||
*increment = fold_rtx_mult_add (v->mult_val, *increment, const0_rtx,
|
||||
v->mode);
|
||||
#endif
|
||||
{
|
||||
struct induction *biv_inc;
|
||||
|
||||
*increment
|
||||
= fold_rtx_mult_add (v->mult_val, *increment, const0_rtx, v->mode);
|
||||
/* The caller assumes that one full increment has occured at the
|
||||
first loop test. But that's not true when the biv is incremented
|
||||
after the giv is set (which is the usual case), e.g.:
|
||||
i = 6; do {;} while (i++ < 9) .
|
||||
Therefore, we bias the initial value by subtracting the amount of
|
||||
the increment that occurs between the giv set and the giv test. */
|
||||
for (biv_inc = bl->biv; biv_inc; biv_inc = biv_inc->next_iv)
|
||||
{
|
||||
if (loop_insn_first_p (v->insn, biv_inc->insn))
|
||||
offset -= INTVAL (biv_inc->add_val);
|
||||
}
|
||||
offset *= INTVAL (v->mult_val);
|
||||
}
|
||||
if (loop_dump_stream)
|
||||
fprintf (loop_dump_stream,
|
||||
"Loop unrolling: Giv iterator, initial value bias %ld.\n",
|
||||
(long) offset);
|
||||
/* Initial value is mult_val times the biv's initial value plus
|
||||
add_val. Only useful if it is a constant. */
|
||||
*initial_value
|
||||
= fold_rtx_mult_add (v->mult_val,
|
||||
plus_constant (bl->initial_value, offset),
|
||||
v->add_val, v->mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3626,10 +3643,10 @@ loop_iterations (loop_start, loop_end, loop_info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Loop iterations is always called before any new registers are created
|
||||
now, so this should never occur. */
|
||||
/* The only new registers that care created before loop iterations are
|
||||
givs made from biv increments, so this should never occur. */
|
||||
|
||||
if (REGNO (iteration_var) >= max_reg_before_loop)
|
||||
if ((unsigned) REGNO (iteration_var) >= reg_iv_type->num_elements)
|
||||
abort ();
|
||||
|
||||
iteration_info (iteration_var, &initial_value, &increment,
|
||||
|
Loading…
Reference in New Issue
Block a user