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> 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 * loop.c (check_dbra_loop): Update JUMP_LABEL field of jump insn
......
...@@ -88,14 +88,6 @@ int *loop_outer_loop; ...@@ -88,14 +88,6 @@ int *loop_outer_loop;
int *loop_used_count_register; int *loop_used_count_register;
#endif /* HAVE_decrement_and_branch_on_count */ #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 /* Indexed by loop number, contains a nonzero value if the "loop" isn't
really a loop (an insn outside the loop branches into it). */ really a loop (an insn outside the loop branches into it). */
...@@ -118,14 +110,6 @@ rtx *loop_number_exit_labels; ...@@ -118,14 +110,6 @@ rtx *loop_number_exit_labels;
int *loop_number_exit_count; 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. */ /* Nonzero if there is a subroutine call in the current loop. */
static int loop_has_call; static int loop_has_call;
...@@ -320,7 +304,8 @@ static void find_single_use_in_loop PROTO((rtx, rtx, varray_type)); ...@@ -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 int valid_initial_value_p PROTO((rtx, rtx, int, rtx));
static void find_mem_givs PROTO((rtx, rtx, int, rtx, 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 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 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 void update_giv_derive PROTO((rtx));
static int basic_induction_var PROTO((rtx, enum machine_mode, rtx, rtx, rtx *, rtx *)); static int basic_induction_var PROTO((rtx, enum machine_mode, rtx, rtx, rtx *, rtx *));
...@@ -365,7 +350,7 @@ typedef struct rtx_pair { ...@@ -365,7 +350,7 @@ typedef struct rtx_pair {
#ifdef HAVE_decrement_and_branch_on_count #ifdef HAVE_decrement_and_branch_on_count
/* Test whether BCT applicable and safe. */ /* 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. */ /* Auxiliary function that inserts the BCT pattern into the loop. */
static void instrument_loop_bct PROTO((rtx, rtx, rtx)); static void instrument_loop_bct PROTO((rtx, rtx, rtx));
...@@ -478,12 +463,6 @@ loop_optimize (f, dumpfile, unroll_p, bct_p) ...@@ -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_labels = (rtx *) alloca (max_loop_num * sizeof (rtx));
loop_number_exit_count = (int *) alloca (max_loop_num * sizeof (int)); 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 #ifdef HAVE_decrement_and_branch_on_count
/* Allocate for BCT optimization */ /* Allocate for BCT optimization */
loop_used_count_register = (int *) alloca (max_loop_num * sizeof (int)); loop_used_count_register = (int *) alloca (max_loop_num * sizeof (int));
...@@ -3573,6 +3552,8 @@ strength_reduce (scan_start, end, loop_top, insn_count, ...@@ -3573,6 +3552,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
rtx test; rtx test;
rtx end_insert_before; rtx end_insert_before;
int loop_depth = 0; 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 reg_iv_type = (enum iv_mode *) alloca (max_reg_before_loop
* sizeof (enum iv_mode)); * sizeof (enum iv_mode));
...@@ -3771,7 +3752,8 @@ strength_reduce (scan_start, end, loop_top, insn_count, ...@@ -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 /* Can still unroll the loop anyways, but indicate that there is no
strength reduction info available. */ strength reduction info available. */
if (unroll_p) 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; return;
} }
...@@ -4040,7 +4022,7 @@ strength_reduce (scan_start, end, loop_top, insn_count, ...@@ -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 be called after all giv's have been identified, since otherwise it may
fail if the iteration variable is a giv. */ 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 /* 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 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, ...@@ -4053,7 +4035,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
for (v = bl->giv; v; v = v->next_iv) for (v = bl->giv; v; v = v->next_iv)
if (! v->replaceable && ! v->not_replaceable) 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 /* 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, ...@@ -4099,7 +4081,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
&& ! bl->nonneg && ! bl->nonneg
#endif #endif
&& ! reg_mentioned_p (bl->biv->dest_reg, SET_SRC (bl->init_set))) && ! 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 #ifdef HAVE_decrement_and_branch_until_zero
&& ! bl->nonneg && ! bl->nonneg
#endif #endif
...@@ -4562,13 +4545,14 @@ strength_reduce (scan_start, end, loop_top, insn_count, ...@@ -4562,13 +4545,14 @@ strength_reduce (scan_start, end, loop_top, insn_count,
collected. */ collected. */
if (unroll_p) 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 #ifdef HAVE_decrement_and_branch_on_count
/* Instrument the loop with BCT insn. */ /* Instrument the loop with BCT insn. */
if (HAVE_decrement_and_branch_on_count && bct_p if (HAVE_decrement_and_branch_on_count && bct_p
&& flag_branch_on_count_reg) && 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 */ #endif /* HAVE_decrement_and_branch_on_count */
if (loop_dump_stream) if (loop_dump_stream)
...@@ -5058,9 +5042,10 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit, ...@@ -5058,9 +5042,10 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
have been identified. */ have been identified. */
static void static void
check_final_value (v, loop_start, loop_end) check_final_value (v, loop_start, loop_end, n_iterations)
struct induction *v; struct induction *v;
rtx loop_start, loop_end; rtx loop_start, loop_end;
unsigned HOST_WIDE_INT n_iterations;
{ {
struct iv_class *bl; struct iv_class *bl;
rtx final_value = 0; rtx final_value = 0;
...@@ -5087,7 +5072,7 @@ check_final_value (v, loop_start, loop_end) ...@@ -5087,7 +5072,7 @@ check_final_value (v, loop_start, loop_end)
v->replaceable = 0; v->replaceable = 0;
#endif #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))) && (v->always_computable || last_use_this_basic_block (v->dest_reg, v->insn)))
{ {
int biv_increment_seen = 0; int biv_increment_seen = 0;
...@@ -7965,8 +7950,9 @@ get_condition_for_loop (x) ...@@ -7965,8 +7950,9 @@ get_condition_for_loop (x)
*/ */
static void static void
insert_bct (loop_start, loop_end) insert_bct (loop_start, loop_end, loop_info)
rtx loop_start, loop_end; rtx loop_start, loop_end;
struct loop_info *loop_info;
{ {
int i; int i;
unsigned HOST_WIDE_INT n_iterations; unsigned HOST_WIDE_INT n_iterations;
...@@ -7982,7 +7968,7 @@ insert_bct (loop_start, loop_end) ...@@ -7982,7 +7968,7 @@ insert_bct (loop_start, loop_end)
int loop_num = uid_loop_num [INSN_UID (loop_start)]; int loop_num = uid_loop_num [INSN_UID (loop_start)];
/* It's impossible to instrument a competely unrolled loop. */ /* It's impossible to instrument a competely unrolled loop. */
if (loop_unroll_factor [loop_num] == -1) if (loop_info->unroll_number == -1)
return; return;
/* Make sure that the count register is not in use. */ /* Make sure that the count register is not in use. */
...@@ -8040,10 +8026,10 @@ insert_bct (loop_start, loop_end) ...@@ -8040,10 +8026,10 @@ insert_bct (loop_start, loop_end)
} }
/* Account for loop unrolling in instrumented iteration count. */ /* Account for loop unrolling in instrumented iteration count. */
if (loop_unroll_factor [loop_num] > 1) if (loop_info->unroll_number > 1)
n_iterations = loop_n_iterations / loop_unroll_factor [loop_num]; n_iterations = loop_info->n_iterations / loop_info->unroll_number;
else else
n_iterations = loop_n_iterations; n_iterations = loop_info->n_iterations;
if (n_iterations != 0 && n_iterations < 3) if (n_iterations != 0 && n_iterations < 3)
{ {
...@@ -8071,7 +8057,7 @@ insert_bct (loop_start, loop_end) ...@@ -8071,7 +8057,7 @@ insert_bct (loop_start, loop_end)
at compile time. In this case we generate run_time calculation at compile time. In this case we generate run_time calculation
of the number of iterations. */ of the number of iterations. */
if (loop_iteration_var == 0) if (loop_info->iteration_var == 0)
{ {
if (loop_dump_stream) if (loop_dump_stream)
fprintf (loop_dump_stream, fprintf (loop_dump_stream,
...@@ -8080,8 +8066,8 @@ insert_bct (loop_start, loop_end) ...@@ -8080,8 +8066,8 @@ insert_bct (loop_start, loop_end)
return; return;
} }
if (GET_MODE_CLASS (GET_MODE (loop_iteration_var)) != MODE_INT if (GET_MODE_CLASS (GET_MODE (loop_info->iteration_var)) != MODE_INT
|| GET_MODE_SIZE (GET_MODE (loop_iteration_var)) != UNITS_PER_WORD) || GET_MODE_SIZE (GET_MODE (loop_info->iteration_var)) != UNITS_PER_WORD)
{ {
if (loop_dump_stream) if (loop_dump_stream)
fprintf (loop_dump_stream, fprintf (loop_dump_stream,
...@@ -8091,7 +8077,7 @@ insert_bct (loop_start, loop_end) ...@@ -8091,7 +8077,7 @@ insert_bct (loop_start, loop_end)
} }
/* With runtime bounds, if the compare is of the form '!=' we give up */ /* 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) if (loop_dump_stream)
fprintf (loop_dump_stream, fprintf (loop_dump_stream,
......
...@@ -143,6 +143,43 @@ struct iv_class { ...@@ -143,6 +143,43 @@ struct iv_class {
biv controls. */ 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. */ /* Definitions used by the basic induction variable discovery code. */
enum iv_mode { UNKNOWN_INDUCT, BASIC_INDUCT, NOT_BASIC_INDUCT, enum iv_mode { UNKNOWN_INDUCT, BASIC_INDUCT, NOT_BASIC_INDUCT,
GENERAL_INDUCT }; GENERAL_INDUCT };
...@@ -155,7 +192,6 @@ extern int *uid_loop_num; ...@@ -155,7 +192,6 @@ extern int *uid_loop_num;
extern int *loop_outer_loop; extern int *loop_outer_loop;
extern rtx *loop_number_exit_labels; extern rtx *loop_number_exit_labels;
extern int *loop_number_exit_count; extern int *loop_number_exit_count;
extern unsigned HOST_WIDE_INT loop_n_iterations;
extern int max_reg_before_loop; extern int max_reg_before_loop;
extern FILE *loop_dump_stream; extern FILE *loop_dump_stream;
...@@ -175,21 +211,18 @@ void emit_iv_add_mult PROTO((rtx, rtx, rtx, rtx, rtx)); ...@@ -175,21 +211,18 @@ void emit_iv_add_mult PROTO((rtx, rtx, rtx, rtx, rtx));
void find_loop_tree_blocks PROTO((void)); void find_loop_tree_blocks PROTO((void));
void unroll_block_trees 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)); rtx biv_total_increment PROTO((struct iv_class *, rtx, rtx));
unsigned HOST_WIDE_INT loop_iterations PROTO((rtx, rtx)); unsigned HOST_WIDE_INT loop_iterations PROTO((rtx, rtx, struct loop_info *));
rtx final_biv_value PROTO((struct iv_class *, rtx, rtx)); int precondition_loop_p PROTO((rtx, struct loop_info *,
rtx final_giv_value PROTO((struct induction *, rtx, rtx)); 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)); void emit_unrolled_add PROTO((rtx, rtx, rtx));
int back_branch_in_range_p 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