Commit 302670f3 by Michael Hayes Committed by Michael Hayes

loop.h (struct loop_info): Define new structure.

	* loop.h (struct loop_info): Define new structure.
	(precondition_loop_p): Added prototype.
	(unroll_loop): Added new argument loop_info to prototype.
	(final_biv_value, final_giv_value): Added new argument n_iterations
	to prototype.
	* loop.c (strength_reduce): Declare new structure loop_iteration_info
	and new pointer loop_info.
	(loop_n_iterations): Replace global variable by element in
	loop_info structure.
	(check_final_value): New argument n_iterations.
	(insert_bct): New argument loop_info.
	(loop_unroll_factor): Replace global array by element in
	loop_info structure.
	(loop_optimize): Remove code to allocate and initialise
	loop_unroll_factor_array.
	* unroll.c (precondition_loop_p):  No longer static since
	used by branch on count optimization.
	(precondition_loop_p, unroll_loop): New argument loop_info.
	(final_biv_value, final_giv_value, find_splittable_regs): New
	argument n_iterations.
	(loop_iteration_var, loop_initial_value, loop_increment,
	loop_final_value, loop_comparison_code, loop_unroll_factor):
	Replaced global variables by loop_info structure.
	(loop_unroll_factor): Replace global array by element in
	loop_info structure.

From-SVN: r23884
parent a7060368
Thu Nov 26 18:05:04 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
* loop.h (struct loop_info): Define new structure.
(precondition_loop_p): Added prototype.
(unroll_loop): Added new argument loop_info to prototype.
(final_biv_value, final_giv_value): Added new argument n_iterations
to prototype.
* loop.c (strength_reduce): Declare new structure loop_iteration_info
and new pointer loop_info.
(loop_n_iterations): Replace global variable by element in
loop_info structure.
(check_final_value): New argument n_iterations.
(insert_bct): New argument loop_info.
(loop_unroll_factor): Replace global array by element in
loop_info structure.
(loop_optimize): Remove code to allocate and initialise
loop_unroll_factor_array.
* unroll.c (precondition_loop_p): No longer static since
used by branch on count optimization.
(precondition_loop_p, unroll_loop): New argument loop_info.
(final_biv_value, final_giv_value, find_splittable_regs): New
argument n_iterations.
(loop_iteration_var, loop_initial_value, loop_increment,
loop_final_value, loop_comparison_code, loop_unroll_factor):
Replaced global variables by loop_info structure.
(loop_unroll_factor): Replace global array by element in
loop_info structure.
Thu Nov 26 17:49:29 1998 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
* loop.c (check_dbra_loop): Update JUMP_LABEL field of jump insn
......
......@@ -88,14 +88,6 @@ int *loop_outer_loop;
int *loop_used_count_register;
#endif /* HAVE_decrement_and_branch_on_count */
/* For each loop, keep track of its unrolling factor.
Potential values:
0: unrolled
1: not unrolled.
-1: completely unrolled
>0: holds the unroll exact factor. */
int *loop_unroll_factor;
/* Indexed by loop number, contains a nonzero value if the "loop" isn't
really a loop (an insn outside the loop branches into it). */
......@@ -118,14 +110,6 @@ rtx *loop_number_exit_labels;
int *loop_number_exit_count;
/* Holds the number of loop iterations. It is zero if the number could not be
calculated. Must be unsigned since the number of iterations can
be as high as 2^wordsize-1. For loops with a wider iterator, this number
will be zero if the number of loop iterations is too large for an
unsigned integer to hold. */
unsigned HOST_WIDE_INT loop_n_iterations;
/* Nonzero if there is a subroutine call in the current loop. */
static int loop_has_call;
......@@ -320,7 +304,8 @@ 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, rtx, rtx));
static void record_biv PROTO((struct induction *, rtx, rtx, rtx, rtx, int, int));
static void check_final_value PROTO((struct induction *, rtx, rtx));
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, rtx *, rtx, rtx));
static void update_giv_derive PROTO((rtx));
static int basic_induction_var PROTO((rtx, enum machine_mode, rtx, rtx, rtx *, rtx *));
......@@ -365,7 +350,7 @@ typedef struct rtx_pair {
#ifdef HAVE_decrement_and_branch_on_count
/* Test whether BCT applicable and safe. */
static void insert_bct PROTO((rtx, rtx));
static void insert_bct PROTO((rtx, rtx, struct loop_info *));
/* Auxiliary function that inserts the BCT pattern into the loop. */
static void instrument_loop_bct PROTO((rtx, rtx, rtx));
......@@ -478,12 +463,6 @@ loop_optimize (f, dumpfile, unroll_p, bct_p)
loop_number_exit_labels = (rtx *) alloca (max_loop_num * sizeof (rtx));
loop_number_exit_count = (int *) alloca (max_loop_num * sizeof (int));
/* This is initialized by the unrolling code, so we go ahead
and clear them just in case we are not performing loop
unrolling. */
loop_unroll_factor = (int *) alloca (max_loop_num *sizeof (int));
bzero ((char *) loop_unroll_factor, max_loop_num * sizeof (int));
#ifdef HAVE_decrement_and_branch_on_count
/* Allocate for BCT optimization */
loop_used_count_register = (int *) alloca (max_loop_num * sizeof (int));
......@@ -3573,6 +3552,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
rtx test;
rtx end_insert_before;
int loop_depth = 0;
struct loop_info loop_iteration_info;
struct loop_info *loop_info = &loop_iteration_info;
reg_iv_type = (enum iv_mode *) alloca (max_reg_before_loop
* sizeof (enum iv_mode));
......@@ -3771,7 +3752,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
/* Can still unroll the loop anyways, but indicate that there is no
strength reduction info available. */
if (unroll_p)
unroll_loop (loop_end, insn_count, loop_start, end_insert_before, 0);
unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
loop_info, 0);
return;
}
......@@ -4040,7 +4022,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
be called after all giv's have been identified, since otherwise it may
fail if the iteration variable is a giv. */
loop_n_iterations = loop_iterations (loop_start, loop_end);
loop_iterations (loop_start, loop_end, loop_info);
/* Now for each giv for which we still don't know whether or not it is
replaceable, check to see if it is replaceable because its final value
......@@ -4053,7 +4035,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
for (v = bl->giv; v; v = v->next_iv)
if (! v->replaceable && ! v->not_replaceable)
check_final_value (v, loop_start, loop_end);
check_final_value (v, loop_start, loop_end, loop_info->n_iterations);
}
/* Try to prove that the loop counter variable (if any) is always
......@@ -4099,7 +4081,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
&& ! bl->nonneg
#endif
&& ! reg_mentioned_p (bl->biv->dest_reg, SET_SRC (bl->init_set)))
|| ((final_value = final_biv_value (bl, loop_start, loop_end))
|| ((final_value = final_biv_value (bl, loop_start, loop_end,
loop_info->n_iterations))
#ifdef HAVE_decrement_and_branch_until_zero
&& ! bl->nonneg
#endif
......@@ -4562,13 +4545,14 @@ strength_reduce (scan_start, end, loop_top, insn_count,
collected. */
if (unroll_p)
unroll_loop (loop_end, insn_count, loop_start, end_insert_before, 1);
unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
loop_info, 1);
#ifdef HAVE_decrement_and_branch_on_count
/* Instrument the loop with BCT insn. */
if (HAVE_decrement_and_branch_on_count && bct_p
&& flag_branch_on_count_reg)
insert_bct (loop_start, loop_end);
insert_bct (loop_start, loop_end, loop_info);
#endif /* HAVE_decrement_and_branch_on_count */
if (loop_dump_stream)
......@@ -5058,9 +5042,10 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
have been identified. */
static void
check_final_value (v, loop_start, loop_end)
check_final_value (v, loop_start, loop_end, n_iterations)
struct induction *v;
rtx loop_start, loop_end;
unsigned HOST_WIDE_INT n_iterations;
{
struct iv_class *bl;
rtx final_value = 0;
......@@ -5087,7 +5072,7 @@ check_final_value (v, loop_start, loop_end)
v->replaceable = 0;
#endif
if ((final_value = final_giv_value (v, loop_start, loop_end))
if ((final_value = final_giv_value (v, loop_start, loop_end, n_iterations))
&& (v->always_computable || last_use_this_basic_block (v->dest_reg, v->insn)))
{
int biv_increment_seen = 0;
......@@ -7965,8 +7950,9 @@ get_condition_for_loop (x)
*/
static void
insert_bct (loop_start, loop_end)
insert_bct (loop_start, loop_end, loop_info)
rtx loop_start, loop_end;
struct loop_info *loop_info;
{
int i;
unsigned HOST_WIDE_INT n_iterations;
......@@ -7982,7 +7968,7 @@ insert_bct (loop_start, loop_end)
int loop_num = uid_loop_num [INSN_UID (loop_start)];
/* It's impossible to instrument a competely unrolled loop. */
if (loop_unroll_factor [loop_num] == -1)
if (loop_info->unroll_number == -1)
return;
/* Make sure that the count register is not in use. */
......@@ -8040,10 +8026,10 @@ insert_bct (loop_start, loop_end)
}
/* Account for loop unrolling in instrumented iteration count. */
if (loop_unroll_factor [loop_num] > 1)
n_iterations = loop_n_iterations / loop_unroll_factor [loop_num];
if (loop_info->unroll_number > 1)
n_iterations = loop_info->n_iterations / loop_info->unroll_number;
else
n_iterations = loop_n_iterations;
n_iterations = loop_info->n_iterations;
if (n_iterations != 0 && n_iterations < 3)
{
......@@ -8071,7 +8057,7 @@ insert_bct (loop_start, loop_end)
at compile time. In this case we generate run_time calculation
of the number of iterations. */
if (loop_iteration_var == 0)
if (loop_info->iteration_var == 0)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
......@@ -8080,8 +8066,8 @@ insert_bct (loop_start, loop_end)
return;
}
if (GET_MODE_CLASS (GET_MODE (loop_iteration_var)) != MODE_INT
|| GET_MODE_SIZE (GET_MODE (loop_iteration_var)) != UNITS_PER_WORD)
if (GET_MODE_CLASS (GET_MODE (loop_info->iteration_var)) != MODE_INT
|| GET_MODE_SIZE (GET_MODE (loop_info->iteration_var)) != UNITS_PER_WORD)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
......@@ -8091,7 +8077,7 @@ insert_bct (loop_start, loop_end)
}
/* With runtime bounds, if the compare is of the form '!=' we give up */
if (loop_comparison_code == NE)
if (loop_info->comparison_code == NE)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
......
......@@ -143,6 +143,43 @@ struct iv_class {
biv controls. */
};
/* Information required to calculate the number of loop iterations.
This is set by loop_iterations. */
struct loop_info
{
/* Register or constant initial loop value. */
rtx initial_value;
/* Register or constant value used for comparison test. */
rtx comparison_value;
/* Register or constant approximate final value. */
rtx final_value;
/* Register or constant initial loop value with term common to
final_value removed. */
rtx initial_equiv_value;
/* Register or constant final loop value with term common to
initial_value removed. */
rtx final_equiv_value;
/* Register corresponding to iteration variable. */
rtx iteration_var;
/* Constant loop increment. */
rtx increment;
enum rtx_code comparison_code;
/* Holds the number of loop iterations. It is zero if the number
could not be calculated. Must be unsigned since the number of
iterations can be as high as 2^wordsize - 1. For loops with a
wider iterator, this number will be zero if the number of loop
iterations is too large for an unsigned integer to hold. */
unsigned HOST_WIDE_INT n_iterations;
/* The loop unrolling factor.
Potential values:
0: unrolled
1: not unrolled.
-1: completely unrolled
>0: holds the unroll exact factor. */
int unroll_number;
};
/* Definitions used by the basic induction variable discovery code. */
enum iv_mode { UNKNOWN_INDUCT, BASIC_INDUCT, NOT_BASIC_INDUCT,
GENERAL_INDUCT };
......@@ -155,7 +192,6 @@ extern int *uid_loop_num;
extern int *loop_outer_loop;
extern rtx *loop_number_exit_labels;
extern int *loop_number_exit_count;
extern unsigned HOST_WIDE_INT loop_n_iterations;
extern int max_reg_before_loop;
extern FILE *loop_dump_stream;
......@@ -175,21 +211,18 @@ void emit_iv_add_mult PROTO((rtx, rtx, rtx, rtx, rtx));
void find_loop_tree_blocks PROTO((void));
void unroll_block_trees PROTO((void));
void unroll_loop PROTO((rtx, int, rtx, rtx, int));
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));
rtx final_biv_value PROTO((struct iv_class *, rtx, rtx));
rtx final_giv_value PROTO((struct induction *, rtx, rtx));
unsigned HOST_WIDE_INT loop_iterations PROTO((rtx, rtx, struct loop_info *));
int precondition_loop_p PROTO((rtx, struct loop_info *,
rtx *, rtx *, rtx *));
rtx final_biv_value PROTO((struct iv_class *, rtx, rtx,
unsigned HOST_WIDE_INT));
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));
extern int *loop_unroll_factor;
extern int *loop_unroll_number;
#ifdef HAVE_decrement_and_branch_on_count
extern rtx loop_iteration_var;
extern rtx loop_initial_value;
extern rtx loop_increment;
extern rtx loop_final_value;
extern enum rtx_code loop_comparison_code;
#endif /* HAVE_decrement_and_branch_on_count */
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