OSDN Git Service

* loop.h (struct loop_mem_info): Move from loop.c
authorm.hayes <m.hayes@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 9 Sep 2000 23:02:15 +0000 (23:02 +0000)
committerm.hayes <m.hayes@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 9 Sep 2000 23:02:15 +0000 (23:02 +0000)
(struct loop_info): Add fields store_mems, mems, mems_idx,
mems_allocated, unknown_address_altered,
unknown_constant_address_altered, num_mem_sets, and
first_loop_store_insn.

* loop.c (loop_store_mems): Replace with field in loop_info struct.
(loop_mems, loop_mems_idx, loop_mems_allocated): Likewise.
(unknown_address_altered, unknown_constant_address_altered): Likewise.
(num_mem_sets): Likewise.
  (replace_loop_mems, replace_loop_regs): New.
(struct loop_replace_args): New.
(load_mems): Use replace_loop_mems.
(try_copy_prop): Use replace_loop_regs.
(replace_loop_reg, replace_loop_mem): Use loop_replace_args structure.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36284 138bc75d-0d04-0410-961f-82ee72b054a4

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

index baaff9d..50a5643 100644 (file)
@@ -1,3 +1,21 @@
+2000-09-11  Michael Hayes  <mhayes@cygnus.com>
+
+       * loop.h (struct loop_mem_info): Move from loop.c
+       (struct loop_info): Add fields store_mems, mems, mems_idx,
+       mems_allocated, unknown_address_altered,
+       unknown_constant_address_altered, num_mem_sets, and
+       first_loop_store_insn.
+
+       * loop.c (loop_store_mems): Replace with field in loop_info struct.
+       (loop_mems, loop_mems_idx, loop_mems_allocated): Likewise.
+       (unknown_address_altered, unknown_constant_address_altered): Likewise.
+       (num_mem_sets): Likewise.
+       (replace_loop_mems, replace_loop_regs): New.
+       (struct loop_replace_args): New.
+       (load_mems): Use replace_loop_mems.
+       (try_copy_prop): Use replace_loop_regs.
+       (replace_loop_reg, replace_loop_mem): Use loop_replace_args structure.
+
 2000-09-09  Stephane Carrez  <Stephane.Carrez@worldnet.fr>
 
        * configure.in: Recognize m6811-elf and m6812-elf.
index 0ec79eb..33e2e29 100644 (file)
@@ -113,49 +113,6 @@ static varray_type reg_single_usage;
 
 static char *moved_once;
 
-/* List of MEMs that are stored in this loop.  */
-
-static rtx loop_store_mems;
-
-/* The insn where the first of these was found.  */
-static rtx first_loop_store_insn;
-
-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;
-
-/* Array of MEMs that are used (read or written) in this loop, but
-   cannot be aliased by anything in this loop, except perhaps
-   themselves.  In other words, if loop_mems[i] is altered during the
-   loop, it is altered by an expression that is rtx_equal_p to it.  */
-
-static loop_mem_info *loop_mems;
-
-/* The index of the next available slot in LOOP_MEMS.  */
-
-static int loop_mems_idx;
-
-/* The number of elements allocated in LOOP_MEMs.  */
-
-static int loop_mems_allocated;
-
-/* Nonzero if we don't know what MEMs were changed in the current
-   loop.  This happens if the loop contains a call (in which case
-   `loop_info->has_call' will also be set) or if we store into more
-   than NUM_STORES MEMs.  */
-
-static int unknown_address_altered;
-
-/* The above doesn't count any readonly memory locations that are stored.
-   This does.  */
-
-static int unknown_constant_address_altered;
-
-/* Count of memory write instructions discovered in the loop.  */
-static int num_mem_sets;
-
 /* Bound on pseudo register number before loop optimization.
    A pseudo has valid regscan info if its number is < max_reg_before_loop.  */
 unsigned int max_reg_before_loop;
@@ -314,7 +271,9 @@ static void load_mems_and_recount_loop_regs_set PARAMS ((const struct loop*,
 static void load_mems PARAMS ((const struct loop *));
 static int insert_loop_mem PARAMS ((rtx *, void *));
 static int replace_loop_mem PARAMS ((rtx *, void *));
+static void replace_loop_mems PARAMS ((rtx, rtx, rtx));
 static int replace_loop_reg PARAMS ((rtx *, void *));
+static void replace_loop_regs PARAMS ((rtx insn, rtx, rtx));
 static void note_reg_stored PARAMS ((rtx, rtx, void *));
 static void try_copy_prop PARAMS ((const struct loop *, rtx, unsigned int));
 static void try_swap_copy_prop PARAMS ((const struct loop *, rtx,
@@ -327,16 +286,18 @@ static int iv_add_mult_cost PARAMS ((rtx, rtx, rtx, rtx));
 static void loop_dump_aux PARAMS ((const struct loop *, FILE *, int));
 void debug_loop PARAMS ((const struct loop *));
 
-typedef struct rtx_and_int {
-  rtx r;
-  int i;
-} rtx_and_int;
-
 typedef struct rtx_pair {
   rtx r1;
   rtx r2;
 } rtx_pair;
 
+typedef struct loop_replace_args
+{
+  rtx match;
+  rtx replacement;
+  rtx insn;
+} loop_replace_args;
+
 /* Nonzero iff INSN is between START and END, inclusive.  */
 #define INSN_IN_RANGE_P(INSN, START, END)      \
   (INSN_UID (INSN) < max_uid_for_loop          \
@@ -616,12 +577,12 @@ scan_loop (loop, flags)
   int loop_depth = 0;
   int nregs;
 
+  loop->top = 0;
+
   movables->head = 0;
   movables->last = 0;
   movables->num = 0;
 
-  loop->top = 0;
-
   /* Determine whether this loop starts with a jump down to a test at
      the end.  This will occur for a small number of loops with a test
      that is too complex to duplicate in front of the loop.
@@ -704,7 +665,7 @@ scan_loop (loop, flags)
      that even after the moving of movables creates some new registers
      we won't have to reallocate these arrays.  However, we do grow
      the arrays, if necessary, in load_mems_recount_loop_regs_set.  */
-  nregs = max_reg_num () + loop_mems_idx + 16;
+  nregs = max_reg_num () + loop_info->mems_idx + 16;
   VARRAY_INT_INIT (set_in_loop, nregs, "set_in_loop");
   VARRAY_INT_INIT (n_times_set, nregs, "n_times_set");
   VARRAY_CHAR_INIT (may_not_optimize, nregs, "may_not_optimize");
@@ -2332,10 +2293,10 @@ count_nonfixed_reads (loop, x)
 }
 \f
 /* Scan a loop setting the elements `cont', `vtop', `loops_enclosed',
-   `has_call', `has_volatile', and `has_tablejump' within LOOP.
-   Set the global variables `unknown_address_altered',
-   `unknown_constant_address_altered', and `num_mem_sets'.  Also, fill
-   in the array `loop_mems' and the list `loop_store_mems'.  */
+   `has_call', `has_volatile', `has_tablejump',
+   `unknown_address_altered', `unknown_constant_address_altered', and
+   `num_mem_sets' in LOOP.  Also, fill in the array `mems' and the
+   list `store_mems' in LOOP.  */
 
 static void
 prescan_loop (loop)
@@ -2359,12 +2320,12 @@ prescan_loop (loop)
   loop_info->has_multiple_exit_targets = 0;
   loop->level = 1;
 
-  unknown_address_altered = 0;
-  unknown_constant_address_altered = 0;
-  loop_store_mems = NULL_RTX;
-  first_loop_store_insn = NULL_RTX;
-  loop_mems_idx = 0;
-  num_mem_sets = 0;
+  loop_info->unknown_address_altered = 0;
+  loop_info->unknown_constant_address_altered = 0;
+  loop_info->store_mems = NULL_RTX;
+  loop_info->first_loop_store_insn = NULL_RTX;
+  loop_info->mems_idx = 0;
+  loop_info->num_mem_sets = 0;
 
   for (insn = NEXT_INSN (start); insn != NEXT_INSN (end);
        insn = NEXT_INSN (insn))
@@ -2385,7 +2346,7 @@ prescan_loop (loop)
       else if (GET_CODE (insn) == CALL_INSN)
        {
          if (! CONST_CALL_P (insn))
-           unknown_address_altered = 1;
+           loop_info->unknown_address_altered = 1;
          loop_info->has_call = 1;
        }
       else if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)
@@ -2401,9 +2362,9 @@ prescan_loop (loop)
                  || GET_CODE (PATTERN (insn)) == ADDR_VEC))
            loop_info->has_tablejump = 1;
 
-         note_stores (PATTERN (insn), note_addr_stored, NULL);
-         if (! first_loop_store_insn && loop_store_mems)
-           first_loop_store_insn = insn;
+         note_stores (PATTERN (insn), note_addr_stored, loop_info);
+         if (! loop_info->first_loop_store_insn && loop_info->store_mems)
+           loop_info->first_loop_store_insn = insn;
 
          if (! loop_info->has_multiple_exit_targets
              && GET_CODE (insn) == JUMP_INSN
@@ -2463,23 +2424,25 @@ prescan_loop (loop)
       && ! loop_info->has_multiple_exit_targets)
     for (insn = NEXT_INSN (start); insn != NEXT_INSN (end);
         insn = NEXT_INSN (insn))
-      for_each_rtx (&insn, insert_loop_mem, 0);
+      for_each_rtx (&insn, insert_loop_mem, loop_info);
 
   /* BLKmode MEMs are added to LOOP_STORE_MEM as necessary so
      that loop_invariant_p and load_mems can use true_dependence
      to determine what is really clobbered.  */
-  if (unknown_address_altered)
+  if (loop_info->unknown_address_altered)
     {
       rtx mem = gen_rtx_MEM (BLKmode, const0_rtx);
 
-      loop_store_mems = gen_rtx_EXPR_LIST (VOIDmode, mem, loop_store_mems);
+      loop_info->store_mems 
+       = gen_rtx_EXPR_LIST (VOIDmode, mem, loop_info->store_mems);
     }
-  if (unknown_constant_address_altered)
+  if (loop_info->unknown_constant_address_altered)
     {
       rtx mem = gen_rtx_MEM (BLKmode, const0_rtx);
 
       RTX_UNCHANGING_P (mem) = 1;
-      loop_store_mems = gen_rtx_EXPR_LIST (VOIDmode, mem, loop_store_mems);
+      loop_info->store_mems 
+       = gen_rtx_EXPR_LIST (VOIDmode, mem, loop_info->store_mems);
     }
 }
 \f
@@ -3093,25 +3056,28 @@ note_addr_stored (x, y, data)
      rtx y ATTRIBUTE_UNUSED;
      void *data ATTRIBUTE_UNUSED;
 {
+  struct loop_info *loop_info = data;
+
   if (x == 0 || GET_CODE (x) != MEM)
     return;
 
   /* Count number of memory writes.
      This affects heuristics in strength_reduce.  */
-  num_mem_sets++;
-
+  loop_info->num_mem_sets++;
+  
   /* BLKmode MEM means all memory is clobbered.  */
-    if (GET_MODE (x) == BLKmode)
+  if (GET_MODE (x) == BLKmode)
     {
       if (RTX_UNCHANGING_P (x))
-       unknown_constant_address_altered = 1;
+       loop_info->unknown_constant_address_altered = 1;
       else
-       unknown_address_altered = 1;
-
+       loop_info->unknown_address_altered = 1;
+      
       return;
     }
-
-  loop_store_mems = gen_rtx_EXPR_LIST (VOIDmode, x, loop_store_mems);
+  
+  loop_info->store_mems = gen_rtx_EXPR_LIST (VOIDmode, x, 
+                                            loop_info->store_mems);
 }
 
 /* X is a value modified by an INSN that references a biv inside a loop
@@ -3151,13 +3117,14 @@ note_set_pseudo_multiple_uses (x, y, data)
    The value is 2 if we refer to something only conditionally invariant.
 
    A memory ref is invariant if it is not volatile and does not conflict
-   with anything stored in `loop_store_mems'.  */
+   with anything stored in `loop_info->store_mems'.  */
 
 int
 loop_invariant_p (loop, x)
      const struct loop *loop;
      register rtx x;
 {
+  struct loop_info *loop_info = LOOP_INFO (loop);
   register int i;
   register enum rtx_code code;
   register const char *fmt;
@@ -3221,7 +3188,7 @@ loop_invariant_p (loop, x)
        return 0;
 
       /* See if there is any dependence between a store and this load.  */
-      mem_list_entry = loop_store_mems;
+      mem_list_entry = loop_info->store_mems;
       while (mem_list_entry)
        {
          if (true_dependence (XEXP (mem_list_entry, 0), VOIDmode,
@@ -8220,7 +8187,7 @@ check_dbra_loop (loop, insn_count)
       if (no_use_except_counting)
        /* No need to worry about MEMs.  */
        ;
-      else if (num_mem_sets <= 1)
+      else if (loop_info->num_mem_sets <= 1)
        {
          for (p = loop_start; p != loop_end; p = NEXT_INSN (p))
            if (INSN_P (p))
@@ -8232,15 +8199,15 @@ check_dbra_loop (loop, insn_count)
             This would work if the source was invariant also, however, in that
             case, the insn should have been moved out of the loop.  */
 
-         if (num_mem_sets == 1)
+         if (loop_info->num_mem_sets == 1)
            {
              struct induction *v;
 
              reversible_mem_store
-               = (! unknown_address_altered
-                  && ! unknown_constant_address_altered
+               = (! loop_info->unknown_address_altered
+                  && ! loop_info->unknown_constant_address_altered
                   && ! loop_invariant_p (loop,
-                                         XEXP (XEXP (loop_store_mems, 0),
+                                         XEXP (XEXP (loop_info->store_mems, 0),
                                                0)));
 
              /* If the store depends on a register that is set after the
@@ -8250,8 +8217,9 @@ check_dbra_loop (loop, insn_count)
                {
                  if (v->giv_type == DEST_REG
                      && reg_mentioned_p (v->dest_reg,
-                                         PATTERN (first_loop_store_insn))
-                     && loop_insn_first_p (first_loop_store_insn, v->insn))
+                                         PATTERN (loop_info->first_loop_store_insn))
+                     && loop_insn_first_p (loop_info->first_loop_store_insn, 
+                                           v->insn))
                    reversible_mem_store = 0;
                }
            }
@@ -8271,7 +8239,7 @@ check_dbra_loop (loop, insn_count)
           && ! loop_info->has_call
           && ! loop_info->has_volatile
           && reversible_mem_store
-          && (bl->giv_count + bl->biv_count + num_mem_sets
+          && (bl->giv_count + bl->biv_count + loop_info->num_mem_sets
              + the_movables.num + compare_and_branch == insn_count)
           && (bl == loop_iv_list && bl->next == 0))
          || no_use_except_counting)
@@ -9544,6 +9512,7 @@ insert_loop_mem (mem, data)
      rtx *mem;
      void *data ATTRIBUTE_UNUSED;
 {
+  struct loop_info *loop_info = data;
   int i;
   rtx m = *mem;
 
@@ -9574,40 +9543,40 @@ insert_loop_mem (mem, data)
     }
 
   /* See if we've already seen this MEM.  */
-  for (i = 0; i < loop_mems_idx; ++i)
-    if (rtx_equal_p (m, loop_mems[i].mem))
+  for (i = 0; i < loop_info->mems_idx; ++i)
+    if (rtx_equal_p (m, loop_info->mems[i].mem))
       {
-       if (GET_MODE (m) != GET_MODE (loop_mems[i].mem))
+       if (GET_MODE (m) != GET_MODE (loop_info->mems[i].mem))
          /* The modes of the two memory accesses are different.  If
             this happens, something tricky is going on, and we just
             don't optimize accesses to this MEM.  */
-         loop_mems[i].optimize = 0;
+         loop_info->mems[i].optimize = 0;
 
        return 0;
       }
 
   /* Resize the array, if necessary.  */
-  if (loop_mems_idx == loop_mems_allocated)
+  if (loop_info->mems_idx == loop_info->mems_allocated)
     {
-      if (loop_mems_allocated != 0)
-       loop_mems_allocated *= 2;
+      if (loop_info->mems_allocated != 0)
+       loop_info->mems_allocated *= 2;
       else
-       loop_mems_allocated = 32;
+       loop_info->mems_allocated = 32;
 
-      loop_mems = (loop_mem_info*)
-       xrealloc (loop_mems,
-                 loop_mems_allocated * sizeof (loop_mem_info));
+      loop_info->mems = (loop_mem_info*)
+       xrealloc (loop_info->mems,
+                 loop_info->mems_allocated * sizeof (loop_mem_info));
     }
 
   /* Actually insert the MEM.  */
-  loop_mems[loop_mems_idx].mem = m;
+  loop_info->mems[loop_info->mems_idx].mem = m;
   /* We can't hoist this MEM out of the loop if it's a BLKmode MEM
      because we can't put it in a register.  We still store it in the
      table, though, so that if we see the same address later, but in a
      non-BLK mode, we'll not think we can optimize it at that point.  */
-  loop_mems[loop_mems_idx].optimize = (GET_MODE (m) != BLKmode);
-  loop_mems[loop_mems_idx].reg = NULL_RTX;
-  ++loop_mems_idx;
+  loop_info->mems[loop_info->mems_idx].optimize = (GET_MODE (m) != BLKmode);
+  loop_info->mems[loop_info->mems_idx].reg = NULL_RTX;
+  ++loop_info->mems_idx;
 
   return 0;
 }
@@ -9678,6 +9647,7 @@ static void
 load_mems (loop)
      const struct loop *loop;
 {
+  struct loop_info *loop_info = LOOP_INFO (loop);
   int maybe_never = 0;
   int i;
   rtx p;
@@ -9687,7 +9657,7 @@ load_mems (loop)
   int next_maybe_never = 0;
   int last_max_reg = max_reg_num ();
 
-  if (loop_mems_idx == 0)
+  if (loop_info->mems_idx == 0)
     return;
 
   /* Find start of the extended basic block that enters the loop.  */
@@ -9736,23 +9706,23 @@ load_mems (loop)
     }
 
   /* Actually move the MEMs.  */
-  for (i = 0; i < loop_mems_idx; ++i)
+  for (i = 0; i < loop_info->mems_idx; ++i)
     {
       regset_head load_copies;
       regset_head store_copies;
       int written = 0;
       rtx reg;
-      rtx mem = loop_mems[i].mem;
+      rtx mem = loop_info->mems[i].mem;
       rtx mem_list_entry;
 
       if (MEM_VOLATILE_P (mem)
          || loop_invariant_p (loop, XEXP (mem, 0)) != 1)
        /* There's no telling whether or not MEM is modified.  */
-       loop_mems[i].optimize = 0;
+       loop_info->mems[i].optimize = 0;
 
       /* Go through the MEMs written to in the loop to see if this
         one is aliased by one of them.  */
-      mem_list_entry = loop_store_mems;
+      mem_list_entry = loop_info->store_mems;
       while (mem_list_entry)
        {
          if (rtx_equal_p (mem, XEXP (mem_list_entry, 0)))
@@ -9761,7 +9731,7 @@ load_mems (loop)
                                    mem, rtx_varies_p))
            {
              /* MEM is indeed aliased by this store.  */
-             loop_mems[i].optimize = 0;
+             loop_info->mems[i].optimize = 0;
              break;
            }
          mem_list_entry = XEXP (mem_list_entry, 1);
@@ -9769,27 +9739,27 @@ load_mems (loop)
 
       if (flag_float_store && written
          && GET_MODE_CLASS (GET_MODE (mem)) == MODE_FLOAT)
-       loop_mems[i].optimize = 0;
+       loop_info->mems[i].optimize = 0;
 
       /* If this MEM is written to, we must be sure that there
         are no reads from another MEM that aliases this one.  */
-      if (loop_mems[i].optimize && written)
+      if (loop_info->mems[i].optimize && written)
        {
          int j;
 
-         for (j = 0; j < loop_mems_idx; ++j)
+         for (j = 0; j < loop_info->mems_idx; ++j)
            {
              if (j == i)
                continue;
              else if (true_dependence (mem,
                                        VOIDmode,
-                                       loop_mems[j].mem,
+                                       loop_info->mems[j].mem,
                                        rtx_varies_p))
                {
-                 /* It's not safe to hoist loop_mems[i] out of
+                 /* It's not safe to hoist loop_info->mems[i] out of
                     the loop because writes to it might not be
-                    seen by reads from loop_mems[j].  */
-                 loop_mems[i].optimize = 0;
+                    seen by reads from loop_info->mems[j].  */
+                 loop_info->mems[i].optimize = 0;
                  break;
                }
            }
@@ -9798,9 +9768,9 @@ load_mems (loop)
       if (maybe_never && may_trap_p (mem))
        /* We can't access the MEM outside the loop; it might
           cause a trap that wouldn't have happened otherwise.  */
-       loop_mems[i].optimize = 0;
+       loop_info->mems[i].optimize = 0;
 
-      if (!loop_mems[i].optimize)
+      if (!loop_info->mems[i].optimize)
        /* We thought we were going to lift this MEM out of the
           loop, but later discovered that we could not.  */
        continue;
@@ -9814,7 +9784,7 @@ load_mems (loop)
         user-variable nor used in the loop test.  */
       reg = gen_reg_rtx (GET_MODE (mem));
       REG_USERVAR_P (reg) = 1;
-      loop_mems[i].reg = reg;
+      loop_info->mems[i].reg = reg;
 
       /* Now, replace all references to the MEM with the
         corresponding pesudos.  */
@@ -9823,8 +9793,6 @@ load_mems (loop)
           p != NULL_RTX;
           p = next_insn_in_loop (loop, p))
        {
-         rtx_and_int ri;
-
          if (INSN_P (p))
            {
              rtx set;
@@ -9859,9 +9827,8 @@ load_mems (loop)
                SET_REGNO_REG_SET (&store_copies, REGNO (SET_SRC (set)));
              
              /* Replace the memory reference with the shadow register.  */
-             ri.r = p;
-             ri.i = i;
-             for_each_rtx (&p, replace_loop_mem, &ri);
+             replace_loop_mems (p, loop_info->mems[i].mem,
+                                loop_info->mems[i].reg);
            }
 
          if (GET_CODE (p) == CODE_LABEL
@@ -9871,7 +9838,7 @@ load_mems (loop)
 
       if (! apply_change_group ())
        /* We couldn't replace all occurrences of the MEM.  */
-       loop_mems[i].optimize = 0;
+       loop_info->mems[i].optimize = 0;
       else
        {
          /* Load the memory immediately before LOOP->START, which is
@@ -10065,12 +10032,8 @@ try_copy_prop (loop, replacement, regno)
       if (init_insn && insn != init_insn)
        {
          struct note_reg_stored_arg arg;
-         rtx array[3];
-         array[0] = reg_rtx;
-         array[1] = replacement;
-         array[2] = insn;
 
-         for_each_rtx (&insn, replace_loop_reg, array);
+         replace_loop_regs (insn, reg_rtx, replacement);
          if (REGNO_LAST_UID (regno) == INSN_UID (insn))
            replaced_last = 1;
 
@@ -10191,8 +10154,8 @@ try_swap_copy_prop (loop, replacement, regno)
 
 
 /* Replace MEM with its associated pseudo register.  This function is
-   called from load_mems via for_each_rtx.  DATA is actually an
-   rtx_and_int * describing the instruction currently being scanned
+   called from load_mems via for_each_rtx.  DATA is actually a pointer
+   to a structure describing the instruction currently being scanned
    and the MEM we are currently replacing.  */
 
 static int
@@ -10200,9 +10163,7 @@ replace_loop_mem (mem, data)
      rtx *mem;
      void *data;
 {
-  rtx_and_int *ri;
-  rtx insn;
-  int i;
+  loop_replace_args *args = (loop_replace_args *)data;
   rtx m = *mem;
 
   if (m == NULL_RTX)
@@ -10223,25 +10184,36 @@ replace_loop_mem (mem, data)
       return 0;
     }
 
-  ri = (rtx_and_int *) data;
-  i = ri->i;
-
-  if (!rtx_equal_p (loop_mems[i].mem, m))
+  if (!rtx_equal_p (args->match, m))
     /* This is not the MEM we are currently replacing.  */
     return 0;
 
-  insn = ri->r;
-
   /* Actually replace the MEM.  */
-  validate_change (insn, mem, loop_mems[i].reg, 1);
+  validate_change (args->insn, mem, args->replacement, 1);
 
   return 0;
 }
 
+
+static void
+replace_loop_mems (insn, mem, reg)
+      rtx insn;
+      rtx mem;
+      rtx reg;
+{          
+  loop_replace_args args;
+
+  args.insn = insn;
+  args.match = mem;
+  args.replacement = reg;
+
+  for_each_rtx (&insn, replace_loop_mem, &args);
+}
+
+
 /* Replace one register with another.  Called through for_each_rtx; PX points
-   to the rtx being scanned.  DATA is actually an array of three rtx's; the
-   first one is the one to be replaced, and the second one the replacement.
-   The third one is the current insn.  */
+   to the rtx being scanned.  DATA is actually a pointer to 
+   a structure of arguments.  */
 
 static int
 replace_loop_reg (px, data)
@@ -10249,17 +10221,34 @@ replace_loop_reg (px, data)
      void *data;
 {
   rtx x = *px;
-  rtx *array = (rtx *) data;
+  loop_replace_args *args = (loop_replace_args *)data;
 
   if (x == NULL_RTX)
     return 0;
 
-  if (x == array[0])
-    validate_change (array[2], px, array[1], 1);
+  if (x == args->match)
+    validate_change (args->insn, px, args->replacement, 1);
 
   return 0;
 }
 
+
+static void
+replace_loop_regs (insn, reg, replacement)
+     rtx insn;
+     rtx reg;
+     rtx replacement;
+{
+  loop_replace_args args;
+
+  args.insn = insn;
+  args.match = reg;
+  args.replacement = replacement;
+
+  for_each_rtx (&insn, replace_loop_reg, &args);
+}
+
+
 /* Replace occurrences of the old exit label for the loop with the new
    one.  DATA is an rtx_pair containing the old and new labels,
    respectively.  */
index 1bc9a35..78939a1 100644 (file)
@@ -164,6 +164,15 @@ struct iv_class {
                                   biv controls. */
 };
 
+
+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;
+
+
 /* Information required to calculate the number of loop iterations. 
    This is set by loop_iterations.  */
 
@@ -207,6 +216,30 @@ struct loop_info
   /* The number of times the loop body was unrolled.  */
   unsigned int unroll_number;
   int used_count_register;
+  /* List of MEMs that are stored in this loop.  */
+  rtx store_mems;
+  /* Array of MEMs that are used (read or written) in this loop, but
+     cannot be aliased by anything in this loop, except perhaps
+     themselves.  In other words, if mems[i] is altered during
+     the loop, it is altered by an expression that is rtx_equal_p to
+     it.  */
+  loop_mem_info *mems;
+  /* The index of the next available slot in MEMS.  */
+  int mems_idx;
+  /* The number of elements allocated in MEMS.  */
+  int mems_allocated;
+  /* Nonzero if we don't know what MEMs were changed in the current
+     loop.  This happens if the loop contains a call (in which case
+     `has_call' will also be set) or if we store into more than
+     NUM_STORES MEMs.  */
+  int unknown_address_altered;
+  /* The above doesn't count any readonly memory locations that are
+     stored.  This does.  */
+  int unknown_constant_address_altered;
+  /* Count of memory write instructions discovered in the loop.  */
+  int num_mem_sets;
+  /* The insn where the first of these was found.  */
+  rtx first_loop_store_insn;
 };
 
 /* Definitions used by the basic induction variable discovery code.  */