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:
J"orn Rennecke 1999-02-24 11:50:54 +00:00 committed by Joern Rennecke
parent ddce352881
commit c99f8c2a3e
4 changed files with 64 additions and 38 deletions

View File

@ -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.

View File

@ -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;
{

View File

@ -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));

View File

@ -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,