From: Michael Hayes Date: Mon, 1 Jan 2001 00:49:30 +0000 (+0000) Subject: loop.h (struct iv): New. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=14be28e5f43fa2710e15441ff8b4e54b64295303;p=gcc.git loop.h (struct iv): New. * 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'. (struct ivs): Rename 'loop_iv_list' field to 'list'. * loop.c (loop_bivs_find, strength_reduce): Use ivs->regs array. * unroll.c (loop_iterations): Check array bounds with ivs->n_regs. From-SVN: r38582 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 071513750fc..6f813063c06 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2001-01-01 Michael Hayes + + * 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'. + (struct ivs): Rename 'loop_iv_list' field to 'list'. + * loop.c (loop_bivs_find, strength_reduce): Use ivs->regs array. + * unroll.c (loop_iterations): Check array bounds with ivs->n_regs. + 2000-12-31 Alexandre Oliva * resource.c (mark_referenced_resources): Abort() before diff --git a/gcc/loop.c b/gcc/loop.c index b5da95ed246..5882a813d51 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -3652,27 +3652,16 @@ loop_bivs_find (loop) { struct loop_regs *regs = LOOP_REGS (loop); struct loop_ivs *ivs = LOOP_IVS (loop); - /* Temporary list pointers for traversing ivs->loop_iv_list. */ + /* Temporary list pointers for traversing ivs->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 *)); + ivs->list = 0; 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. + /* Scan ivs->list to remove all regs that proved not to be bivs. Make a sanity check against regs->n_times_set. */ - for (backbl = &ivs->loop_iv_list, bl = *backbl; bl; bl = bl->next) + for (backbl = &ivs->list, bl = *backbl; bl; bl = bl->next) { if (REG_IV_TYPE (ivs, bl->regno) != BASIC_INDUCT /* Above happens if register modified by subreg, etc. */ @@ -3711,7 +3700,7 @@ loop_bivs_init_find (loop) struct loop *loop; { struct loop_ivs *ivs = LOOP_IVS (loop); - /* Temporary list pointers for traversing ivs->loop_iv_list. */ + /* Temporary list pointers for traversing ivs->list. */ struct iv_class *bl; int call_seen; rtx p; @@ -3767,11 +3756,11 @@ loop_bivs_check (loop) struct loop *loop; { struct loop_ivs *ivs = LOOP_IVS (loop); - /* Temporary list pointers for traversing ivs->loop_iv_list. */ + /* Temporary list pointers for traversing ivs->list. */ struct iv_class *bl; struct iv_class **backbl; - for (backbl = &ivs->loop_iv_list; (bl = *backbl); backbl = &bl->next) + for (backbl = &ivs->list; (bl = *backbl); backbl = &bl->next) { rtx src; rtx note; @@ -3846,7 +3835,7 @@ loop_givs_check (loop) struct loop_ivs *ivs = LOOP_IVS (loop); struct iv_class *bl; - for (bl = ivs->loop_iv_list; bl; bl = bl->next) + for (bl = ivs->list; bl; bl = bl->next) { struct induction *v; @@ -4280,7 +4269,7 @@ strength_reduce (loop, insn_count, flags) struct loop_regs *regs = LOOP_REGS (loop); struct loop_ivs *ivs = LOOP_IVS (loop); rtx p; - /* Temporary list pointer for traversing ivs->loop_iv_list. */ + /* Temporary list pointer for traversing ivs->list. */ struct iv_class *bl; /* Ratio of extra register life span we can justify for saving an instruction. More if loop doesn't call subroutines @@ -4309,12 +4298,14 @@ strength_reduce (loop, insn_count, flags) 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); /* Exit if there are no bivs. */ - if (! ivs->loop_iv_list) + if (! ivs->list) { /* Can still unroll the loop anyways, but indicate that there is no strength reduction info available. */ @@ -4355,13 +4346,13 @@ strength_reduce (loop, insn_count, flags) /* 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_size = ivs->n_regs; reg_map = (rtx *) xcalloc (reg_map_size, sizeof (rtx)); /* Examine each iv class for feasibility of strength reduction/induction variable elimination. */ - for (bl = ivs->loop_iv_list; bl; bl = bl->next) + for (bl = ivs->list; bl; bl = bl->next) { struct induction *v; int benefit; @@ -4581,11 +4572,9 @@ strength_reduce (loop, insn_count, flags) fprintf (loop_dump_stream, "\n"); egress: - VARRAY_FREE (ivs->reg_iv_type); - VARRAY_FREE (ivs->reg_iv_info); - free (ivs->reg_biv_class); + free (ivs->regs); { - struct iv_class *iv = ivs->loop_iv_list; + struct iv_class *iv = ivs->list; while (iv) { struct iv_class *next = iv->next; @@ -4941,9 +4930,9 @@ record_biv (loop, v, insn, dest_reg, inc_val, mult_val, location, bl->reversed = 0; bl->total_benefit = 0; - /* Add this class to ivs->loop_iv_list. */ - bl->next = ivs->loop_iv_list; - ivs->loop_iv_list = bl; + /* Add this class to ivs->list. */ + bl->next = ivs->list; + ivs->list = bl; /* Put it in the array of biv register classes. */ REG_IV_CLASS (ivs, REGNO (dest_reg)) = bl; @@ -5448,7 +5437,7 @@ update_giv_derive (loop, p) subsequent biv update was performed. If this adjustment cannot be done, the giv cannot derive further givs. */ - for (bl = ivs->loop_iv_list; bl; bl = bl->next) + for (bl = ivs->list; bl; bl = bl->next) for (biv = bl->biv; biv; biv = biv->next_iv) if (GET_CODE (p) == CODE_LABEL || GET_CODE (p) == JUMP_INSN || biv->insn == p) @@ -5750,7 +5739,7 @@ general_induction_var (loop, x, src_reg, add_val, mult_val, ext_val, /* Since this is now an invariant and wasn't before, it must be a giv with MULT_VAL == 0. It doesn't matter which BIV we associate this with. */ - *src_reg = ivs->loop_iv_list->biv->dest_reg; + *src_reg = ivs->list->biv->dest_reg; *mult_val = const0_rtx; *add_val = x; break; @@ -7271,7 +7260,7 @@ check_dbra_loop (loop, insn_count) it will be zero on the last iteration. Also skip if the biv is used between its update and the test insn. */ - for (bl = ivs->loop_iv_list; bl; bl = bl->next) + for (bl = ivs->list; bl; bl = bl->next) { if (bl->biv_count == 1 && ! bl->biv->maybe_multiple @@ -7461,7 +7450,7 @@ check_dbra_loop (loop, insn_count) && reversible_mem_store && (bl->giv_count + bl->biv_count + loop_info->num_mem_sets + LOOP_MOVABLES (loop)->num + compare_and_branch == insn_count) - && (bl == ivs->loop_iv_list && bl->next == 0)) + && (bl == ivs->list && bl->next == 0)) || no_use_except_counting) { rtx tem; @@ -7760,7 +7749,7 @@ check_dbra_loop (loop, insn_count) 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 + || (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;) diff --git a/gcc/loop.h b/gcc/loop.h index 7ca9b06a0ff..5b576949fbc 100644 --- a/gcc/loop.h +++ b/gcc/loop.h @@ -54,7 +54,7 @@ Boston, MA 02111-1307, USA. */ value is a linear function of a biv. */ /* Bivs are recognized by `basic_induction_var'; - Givs by `general_induct_var'. */ + Givs by `general_induction_var'. */ /* An enum for the two different types of givs, those that are used as memory addresses and those that are calculated into registers. */ @@ -64,6 +64,7 @@ enum g_types DEST_REG }; + /* A `struct induction' is created for every instruction that sets an induction variable (either a biv or a giv). */ @@ -152,6 +153,7 @@ struct induction a substitute for the lifetime information. */ }; + /* A `struct iv_class' is created for each biv. */ struct iv_class @@ -182,35 +184,58 @@ struct iv_class been reduced. */ }; -typedef struct loop_mem_info + +/* Definitions used by the basic induction variable discovery code. */ +enum iv_mode { - rtx mem; /* The MEM itself. */ - rtx reg; /* Corresponding pseudo, if any. */ - int optimize; /* Nonzero if we can optimize access to this MEM. */ -} loop_mem_info; + UNKNOWN_INDUCT, + BASIC_INDUCT, + NOT_BASIC_INDUCT, + GENERAL_INDUCT +}; -struct loop_ivs + +/* A `struct iv' is created for every register. */ + +struct iv { - /* Indexed by register number, indicates whether or not register is - an induction variable, and if so what type. */ - varray_type reg_iv_type; + 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 - induction' if register is an induction variable. This holds - general info for all induction variables. */ - varray_type reg_iv_info; + iv' if register is an induction variable. */ + struct iv *regs; - /* 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; + /* 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 iv_class *list; }; + +typedef struct loop_mem_info +{ + rtx mem; /* The MEM itself. */ + rtx reg; /* Corresponding pseudo, if any. */ + int optimize; /* Nonzero if we can optimize access to this MEM. */ +} loop_mem_info; + + struct loop_regs { int num; @@ -342,14 +367,6 @@ struct loop_info 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,11 +376,6 @@ extern unsigned int max_reg_before_loop; 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. */ diff --git a/gcc/unroll.c b/gcc/unroll.c index 1c66b1ff829..4597343fc3d 100644 --- a/gcc/unroll.c +++ b/gcc/unroll.c @@ -1184,7 +1184,7 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p) /* Search the list of bivs and givs to find ones which need to be remapped when split, and set their reg_map entry appropriately. */ - for (bl = ivs->loop_iv_list; bl; bl = bl->next) + for (bl = ivs->list; bl; bl = bl->next) { if (REGNO (bl->biv->src_reg) != bl->regno) map->reg_map[bl->regno] = bl->biv->src_reg; @@ -2447,7 +2447,7 @@ find_splittable_regs (loop, unroll_type, end_insert_before, unroll_number) rtx loop_start = loop->start; rtx loop_end = loop->end; - for (bl = ivs->loop_iv_list; bl; bl = bl->next) + for (bl = ivs->list; bl; bl = bl->next) { /* Biv_total_increment must return a constant value, otherwise we can not calculate the split values. */ @@ -3545,7 +3545,7 @@ loop_iterations (loop) 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 + if ((unsigned) REGNO (iteration_var) >= ivs->n_regs && ! REG_USERVAR_P (iteration_var)) abort (); @@ -3563,7 +3563,7 @@ loop_iterations (loop) /* 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 ((unsigned) REGNO (iteration_var) >= ivs->n_regs) { if (loop_dump_stream) fprintf (loop_dump_stream,