loop.h (struct iv): New.
authorMichael Hayes <mhayes@redhat.com>
Mon, 1 Jan 2001 00:49:30 +0000 (00:49 +0000)
committerMichael Hayes <m.hayes@gcc.gnu.org>
Mon, 1 Jan 2001 00:49:30 +0000 (00:49 +0000)
* 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

gcc/ChangeLog
gcc/loop.c
gcc/loop.h
gcc/unroll.c

index 071513750fc7d1ba609c2668275bb98e6e97c1c8..6f813063c06b29f622100134fe380c441cc29b16 100644 (file)
@@ -1,3 +1,13 @@
+2001-01-01  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'.
+       (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  <aoliva@redhat.com>
 
        * resource.c (mark_referenced_resources): Abort() before
index b5da95ed2465308db33a511a16e242d7be041003..5882a813d518f0fde3c65df6167798980c70c6d6 100644 (file)
@@ -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 = &REG_NOTES (p); *pnote;)
index 7ca9b06a0ff82b1cee34cc559c12384ae5792f7a..5b576949fbc8c319c28175568091f2cb638082b2 100644 (file)
@@ -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.  */
index 1c66b1ff8291d6c067b44051892e3a99feb88903..4597343fc3d818c9d774ad4297c9559d6db620fa 100644 (file)
@@ -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,