This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Loop IV info patch 2
- To: gcc-patches at gcc dot gnu dot org
- Subject: Loop IV info patch 2
- From: Michael Hayes <mhayes at redhat dot com>
- Date: Sun, 31 Dec 2000 20:46:37 +1300 (NZDT)
This patch combines three arrays into one, allowing two independent
ones to be overlaid to save memory. It also simplifies debugging
of IV info.
2000-12-29 Michael Hayes <mhayes@redhat.com>
* loop.h (struct iv): New.
(REG_IV_TYPE, REG_IV_CLASS, REG_INFO): Modify to use 'struct iv'.
(struct loop_ivs): Replace 'reg_iv_type', 'reg_iv_info',
'reg_biv_class' fields with 'regs' and 'n_regs'.
* loop.c (loop_bivs_find, strength_reduce): Use ivs->regs array.
* unroll.c (loop_iterations): Check array bounds with ivs->n_regs.
*** loop-7.c Thu Dec 28 15:58:06 2000
--- loop.c Thu Dec 28 15:58:32 2000
*************** loop_bivs_find (loop)
*** 3656,3675 ****
struct loop_ivs *ivs = LOOP_IVS (loop);
/* Temporary list pointers for traversing ivs->loop_iv_list. */
struct iv_class *bl, **backbl;
- /* Ratio of extra register life span we can justify
- for saving an instruction. More if loop doesn't call subroutines
- since in that case saving an insn makes more difference
- and more registers are available. */
- /* ??? could set this to last value of threshold in move_movables */
ivs->loop_iv_list = 0;
- VARRAY_INT_INIT (ivs->reg_iv_type, max_reg_before_loop, "reg_iv_type");
- VARRAY_GENERIC_PTR_INIT (ivs->reg_iv_info, max_reg_before_loop,
- "reg_iv_info");
- ivs->reg_biv_class = (struct iv_class **)
- xcalloc (max_reg_before_loop, sizeof (struct iv_class *));
-
for_each_insn_in_loop (loop, check_insn_for_bivs);
/* Scan ivs->loop_iv_list to remove all regs that proved not to be bivs.
--- 3656,3664 ----
*************** strength_reduce (loop, insn_count, flags
*** 4311,4316 ****
--- 4300,4307 ----
else
end_insert_before = emit_note_after (NOTE_INSN_DELETED, loop->end);
+ ivs->n_regs = max_reg_before_loop;
+ ivs->regs = (struct iv *) xcalloc (ivs->n_regs, sizeof (struct iv));
/* Find all BIVs in loop. */
loop_bivs_find (loop);
*************** strength_reduce (loop, insn_count, flags
*** 4357,4363 ****
/* Create reg_map to hold substitutions for replaceable giv regs.
Some givs might have been made from biv increments, so look at
ivs->reg_iv_type for a suitable size. */
! reg_map_size = ivs->reg_iv_type->num_elements;
reg_map = (rtx *) xcalloc (reg_map_size, sizeof (rtx));
/* Examine each iv class for feasibility of strength reduction/induction
--- 4348,4354 ----
/* Create reg_map to hold substitutions for replaceable giv regs.
Some givs might have been made from biv increments, so look at
ivs->reg_iv_type for a suitable size. */
! reg_map_size = ivs->n_regs;
reg_map = (rtx *) xcalloc (reg_map_size, sizeof (rtx));
/* Examine each iv class for feasibility of strength reduction/induction
*************** strength_reduce (loop, insn_count, flags
*** 4583,4591 ****
fprintf (loop_dump_stream, "\n");
egress:
! VARRAY_FREE (ivs->reg_iv_type);
! VARRAY_FREE (ivs->reg_iv_info);
! free (ivs->reg_biv_class);
{
struct iv_class *iv = ivs->loop_iv_list;
--- 4574,4580 ----
fprintf (loop_dump_stream, "\n");
egress:
! free (ivs->regs);
{
struct iv_class *iv = ivs->loop_iv_list;
*************** check_dbra_loop (loop, insn_count)
*** 7762,7768 ****
REG_EQUAL notes should still be correct. */
if (! set
|| GET_CODE (SET_DEST (set)) != REG
! || (size_t) REGNO (SET_DEST (set)) >= ivs->reg_iv_type->num_elements
|| REG_IV_TYPE (ivs, REGNO (SET_DEST (set))) != GENERAL_INDUCT
|| REG_IV_INFO (ivs, REGNO (SET_DEST (set)))->src_reg != bl->biv->src_reg)
for (pnote = ®_NOTES (p); *pnote;)
--- 7751,7757 ----
REG_EQUAL notes should still be correct. */
if (! set
|| GET_CODE (SET_DEST (set)) != REG
! || (size_t) REGNO (SET_DEST (set)) >= ivs->n_regs
|| REG_IV_TYPE (ivs, REGNO (SET_DEST (set))) != GENERAL_INDUCT
|| REG_IV_INFO (ivs, REGNO (SET_DEST (set)))->src_reg != bl->biv->src_reg)
for (pnote = ®_NOTES (p); *pnote;)
*** loop-7.h Thu Dec 28 15:58:03 2000
--- loop.h Thu Dec 28 15:58:35 2000
*************** struct iv_class
*** 178,183 ****
--- 178,184 ----
been reduced. */
};
+
typedef struct loop_mem_info
{
rtx mem; /* The MEM itself. */
*************** typedef struct loop_mem_info
*** 185,212 ****
int optimize; /* Nonzero if we can optimize access to this MEM. */
} loop_mem_info;
! struct loop_ivs
{
! /* Indexed by register number, indicates whether or not register is
! an induction variable, and if so what type. */
! varray_type reg_iv_type;
/* Indexed by register number, contains pointer to `struct
! induction' if register is an induction variable. This holds
! general info for all induction variables. */
! varray_type reg_iv_info;
!
! /* Indexed by register number, contains pointer to `struct iv_class'
! if register is a basic induction variable. This holds info
! describing the class (a related group) of induction variables
! that the biv belongs to. */
! struct iv_class **reg_biv_class;
/* The head of a list which links together (via the next field)
every iv class for the current loop. */
struct iv_class *loop_iv_list;
};
struct loop_regs
{
int num;
--- 186,233 ----
int optimize; /* Nonzero if we can optimize access to this MEM. */
} loop_mem_info;
!
! /* Definitions used by the basic induction variable discovery code. */
! enum iv_mode
{
! UNKNOWN_INDUCT,
! BASIC_INDUCT,
! NOT_BASIC_INDUCT,
! GENERAL_INDUCT
! };
!
!
! struct iv
! {
! enum iv_mode type;
! union
! {
! struct iv_class *class;
! struct induction *info;
! } iv;
! };
!
+ #define REG_IV_TYPE(ivs, n) ivs->regs[n].type
+ #define REG_IV_INFO(ivs, n) ivs->regs[n].iv.info
+ #define REG_IV_CLASS(ivs, n) ivs->regs[n].iv.class
+
+
+ struct loop_ivs
+ {
/* Indexed by register number, contains pointer to `struct
! iv' if register is an induction variable. */
! struct iv *regs;
!
! /* Size of regs array. */
! unsigned int n_regs;
/* The head of a list which links together (via the next field)
every iv class for the current loop. */
struct iv_class *loop_iv_list;
};
+
struct loop_regs
{
int num;
*************** struct loop_info
*** 338,351 ****
int pre_header_has_call;
};
- /* Definitions used by the basic induction variable discovery code. */
- enum iv_mode
- {
- UNKNOWN_INDUCT,
- BASIC_INDUCT,
- NOT_BASIC_INDUCT,
- GENERAL_INDUCT
- };
/* Variables declared in loop.c, but also needed in unroll.c. */
--- 359,364 ----
*************** extern unsigned int max_reg_before_loop;
*** 355,365 ****
extern struct loop **uid_loop;
extern FILE *loop_dump_stream;
- #define REG_IV_TYPE(ivs, n) \
- (*(enum iv_mode *) &VARRAY_INT(ivs->reg_iv_type, (n)))
- #define REG_IV_INFO(ivs, n) \
- (*(struct induction **) &VARRAY_GENERIC_PTR(ivs->reg_iv_info, (n)))
- #define REG_IV_CLASS(ivs, n) ivs->reg_biv_class[n]
/* Forward declarations for non-static functions declared in loop.c and
unroll.c. */
--- 368,373 ----
*** unroll-6.c Fri Dec 29 21:42:15 2000
--- unroll.c Thu Dec 28 15:58:43 2000
*************** loop_iterations (loop)
*** 3545,3551 ****
will propagate a new pseudo into the old iteration register but
this will be marked by having the REG_USERVAR_P bit set. */
! if ((unsigned) REGNO (iteration_var) >= ivs->reg_iv_type->num_elements
&& ! REG_USERVAR_P (iteration_var))
abort ();
--- 3545,3551 ----
will propagate a new pseudo into the old iteration register but
this will be marked by having the REG_USERVAR_P bit set. */
! if ((unsigned) REGNO (iteration_var) >= ivs->n_regs
&& ! REG_USERVAR_P (iteration_var))
abort ();
*************** loop_iterations (loop)
*** 3563,3569 ****
/* 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) >= ivs->reg_iv_type->num_elements)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
--- 3563,3569 ----
/* 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) >= ivs->n_regs)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,