OSDN Git Service

* tree-vrp.c (adjust_range_with_scev): Use get_chrec_loop.
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 10 Dec 2006 22:17:15 +0000 (22:17 +0000)
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 10 Dec 2006 22:17:15 +0000 (22:17 +0000)
* loop-unswitch.c (unswitch_loops): Use FOR_EACH_LOOP.
* tree-loop-linear.c (linear_transform_loops): Ditto.
* tree-ssa-loop-im.c (determine_lsm): Ditto.
* tree-ssa-loop-niter.c (estimate_numbers_of_iterations,
free_numbers_of_iterations_estimates): Ditto.
* tree_ssa_unswitch_loops (tree_ssa_unswitch_loops): Ditto.
* tree-ssa-loop-ch.c (copy_loop_headers): Ditto.
* tree-ssa-loop-ivopts.c (tree_ssa_iv_optimize): Ditto.
* modulo-sched.c (sms_schedule): Ditto.
* tree-ssa-loop-ivcanon.c (canonicalize_induction_variables,
tree_unroll_loops_completely): Ditto.
* predict.c (predict_loops): Ditto.
* tree-if-conv.c (main_tree_if_conversion): Ditto.
* loop-unroll.c (unroll_and_peel_loops, peel_loops_completely,
decide_unrolling_and_peeling): Ditto.
* cfgloopmanip.c (unloop): Use delete_loop.
(place_new_loop): Access larray vector instead of parray.
(create_preheaders, force_single_succ_latches,
fix_loop_structure): Use FOR_EACH_LOOP and delete_loop..
* loop-doloop.c (doloop_optimize_loops): Ditto.
* loop-invariant.c (move_loop_invariants): Ditto.
* tree-cfg.c (replace_uses_by): Ditto.
* tree-ssa-loop-prefetch.c (tree_ssa_prefetch_arrays): Ditto.
* tree-chrec.h (CHREC_VAR, CHREC_LEFT, CHREC_RIGHT, CHREC_VARIABLE):
Moved to ...
* tree.h (CHREC_VAR, CHREC_LEFT, CHREC_RIGHT, CHREC_VARIABLE):
... here.
* tree-scalar-evolution.c (chrec_contains_symbols_defined_in_loop,
compute_overall_effect_of_inner_loop, chrec_is_positive): Use
get_loop and get_chrec_loop.
(number_of_iterations_for_all_loops): Use number_of_loops.
(scev_initialize, scev_reset, scev_const_prop): Use FOR_EACH_LOOP.
* tree-scalar-evolution.h (get_chrec_loop): New inline function.
* cfgloopanal.c (mark_irreducible_loops): Use number_of_loops,
and FOR_EACH_LOOP.
* tree-chrec.c (evolution_function_is_invariant_rec_p,
chrec_convert_1): Use get_loop and get_chrec_loop.
* loop-init.c (loop_optimizer_init): Use number_of_loops.
(loop_optimizer_init): Use FOR_EACH_LOOP.
* tree-vectorizer.c (vect_loops_num): Removed.
(vectorize_loops): Store number of loops locally.  Use
FOR_EACH_LOOP and get_loop.
* tree-vectorizer.h (vect_loops_num): Removed.
* tree-data-ref.c (get_number_of_iters_for_loop): Use get_loop.
(find_data_references_in_loop): Do not set parallel_p.
* tree-data-ref.h: Do not declare VEC(loop_p).
* cfgloop.c (flow_loops_dump, mark_single_exit_loops,
verify_loop_structure): Use FOR_EACH_LOOP.
(flow_loops_free): Use FOR_EACH_LOOP, free larray vector.
(initialize_loops_parallel_p): Removed.
(flow_loops_find): Push the loops into a vector.
(delete_loop): New function.
(cancel_loop): Use delete_loop.
* cfgloop.h: Declare VEC(loop_p).
(struct loop): Remove parallel_p field.
(struct loops): Replace num and parray field by larray vector.
Remove shared_headers field.
(delete_loop): Declare.
(get_loop, get_loops, number_of_loops, fel_next, fel_init,
FOR_EACH_LOOP): New.
* doc/loop.tex: Document new accessor functions.

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

33 files changed:
gcc/ChangeLog
gcc/cfgloop.c
gcc/cfgloop.h
gcc/cfgloopanal.c
gcc/cfgloopmanip.c
gcc/doc/loop.texi
gcc/loop-doloop.c
gcc/loop-init.c
gcc/loop-invariant.c
gcc/loop-unroll.c
gcc/loop-unswitch.c
gcc/modulo-sched.c
gcc/predict.c
gcc/tree-cfg.c
gcc/tree-chrec.c
gcc/tree-chrec.h
gcc/tree-data-ref.c
gcc/tree-data-ref.h
gcc/tree-if-conv.c
gcc/tree-loop-linear.c
gcc/tree-scalar-evolution.c
gcc/tree-scalar-evolution.h
gcc/tree-ssa-loop-ch.c
gcc/tree-ssa-loop-im.c
gcc/tree-ssa-loop-ivcanon.c
gcc/tree-ssa-loop-ivopts.c
gcc/tree-ssa-loop-niter.c
gcc/tree-ssa-loop-prefetch.c
gcc/tree-ssa-loop-unswitch.c
gcc/tree-vectorizer.c
gcc/tree-vectorizer.h
gcc/tree-vrp.c
gcc/tree.h

index 60ff40a..cabbcd1 100644 (file)
@@ -1,3 +1,68 @@
+2006-12-10  Zdenek Dvorak <dvorakz@suse.cz>
+
+       * tree-vrp.c (adjust_range_with_scev): Use get_chrec_loop.
+       * loop-unswitch.c (unswitch_loops): Use FOR_EACH_LOOP.
+       * tree-loop-linear.c (linear_transform_loops): Ditto.
+       * tree-ssa-loop-im.c (determine_lsm): Ditto.
+       * tree-ssa-loop-niter.c (estimate_numbers_of_iterations,
+       free_numbers_of_iterations_estimates): Ditto.
+       * tree_ssa_unswitch_loops (tree_ssa_unswitch_loops): Ditto.
+       * tree-ssa-loop-ch.c (copy_loop_headers): Ditto.
+       * tree-ssa-loop-ivopts.c (tree_ssa_iv_optimize): Ditto.
+       * modulo-sched.c (sms_schedule): Ditto.
+       * tree-ssa-loop-ivcanon.c (canonicalize_induction_variables,
+       tree_unroll_loops_completely): Ditto.
+       * predict.c (predict_loops): Ditto.
+       * tree-if-conv.c (main_tree_if_conversion): Ditto.
+       * loop-unroll.c (unroll_and_peel_loops, peel_loops_completely,
+       decide_unrolling_and_peeling): Ditto.
+       * cfgloopmanip.c (unloop): Use delete_loop.
+       (place_new_loop): Access larray vector instead of parray.
+       (create_preheaders, force_single_succ_latches,
+       fix_loop_structure): Use FOR_EACH_LOOP and delete_loop..
+       * loop-doloop.c (doloop_optimize_loops): Ditto.
+       * loop-invariant.c (move_loop_invariants): Ditto.
+       * tree-cfg.c (replace_uses_by): Ditto.
+       * tree-ssa-loop-prefetch.c (tree_ssa_prefetch_arrays): Ditto.
+       * tree-chrec.h (CHREC_VAR, CHREC_LEFT, CHREC_RIGHT, CHREC_VARIABLE):
+       Moved to ...
+       * tree.h (CHREC_VAR, CHREC_LEFT, CHREC_RIGHT, CHREC_VARIABLE):
+       ... here.
+       * tree-scalar-evolution.c (chrec_contains_symbols_defined_in_loop,
+       compute_overall_effect_of_inner_loop, chrec_is_positive): Use
+       get_loop and get_chrec_loop.
+       (number_of_iterations_for_all_loops): Use number_of_loops.
+       (scev_initialize, scev_reset, scev_const_prop): Use FOR_EACH_LOOP.
+       * tree-scalar-evolution.h (get_chrec_loop): New inline function.
+       * cfgloopanal.c (mark_irreducible_loops): Use number_of_loops,
+       and FOR_EACH_LOOP.
+       * tree-chrec.c (evolution_function_is_invariant_rec_p,
+       chrec_convert_1): Use get_loop and get_chrec_loop.
+       * loop-init.c (loop_optimizer_init): Use number_of_loops.
+       (loop_optimizer_init): Use FOR_EACH_LOOP.
+       * tree-vectorizer.c (vect_loops_num): Removed.
+       (vectorize_loops): Store number of loops locally.  Use
+       FOR_EACH_LOOP and get_loop.
+       * tree-vectorizer.h (vect_loops_num): Removed.
+       * tree-data-ref.c (get_number_of_iters_for_loop): Use get_loop.
+       (find_data_references_in_loop): Do not set parallel_p.
+       * tree-data-ref.h: Do not declare VEC(loop_p).
+       * cfgloop.c (flow_loops_dump, mark_single_exit_loops,
+       verify_loop_structure): Use FOR_EACH_LOOP.
+       (flow_loops_free): Use FOR_EACH_LOOP, free larray vector.
+       (initialize_loops_parallel_p): Removed.
+       (flow_loops_find): Push the loops into a vector.
+       (delete_loop): New function.
+       (cancel_loop): Use delete_loop.
+       * cfgloop.h: Declare VEC(loop_p).
+       (struct loop): Remove parallel_p field.
+       (struct loops): Replace num and parray field by larray vector.
+       Remove shared_headers field.
+       (delete_loop): Declare.
+       (get_loop, get_loops, number_of_loops, fel_next, fel_init,
+       FOR_EACH_LOOP): New.
+       * doc/loop.tex: Document new accessor functions.
+
 2006-12-10  Andrew MacLeod  <amacleod@redhat.com>
 
        * common.opt (-ftree-lrs): Remove live range splitting option.
index 5a58fb2..52e1ab0 100644 (file)
@@ -128,20 +128,16 @@ flow_loop_dump (const struct loop *loop, FILE *file,
 void
 flow_loops_dump (FILE *file, void (*loop_dump_aux) (const struct loop *, FILE *, int), int verbose)
 {
-  unsigned i;
+  loop_iterator li;
+  struct loop *loop;
 
   if (!current_loops || ! file)
     return;
 
-  fprintf (file, ";; %d loops found\n", current_loops->num);
+  fprintf (file, ";; %d loops found\n", number_of_loops ());
 
-  for (i = 0; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, LI_INCLUDE_ROOT)
     {
-      struct loop *loop = current_loops->parray[i];
-
-      if (!loop)
-       continue;
-
       flow_loop_dump (loop, file, loop_dump_aux, verbose);
     }
 
@@ -163,25 +159,22 @@ flow_loop_free (struct loop *loop)
 void
 flow_loops_free (struct loops *loops)
 {
-  if (loops->parray)
+  if (loops->larray)
     {
       unsigned i;
-
-      gcc_assert (loops->num);
+      loop_p loop;
 
       /* Free the loop descriptors.  */
-      for (i = 0; i < loops->num; i++)
+      for (i = 0; VEC_iterate (loop_p, loops->larray, i, loop); i++)
        {
-         struct loop *loop = loops->parray[i];
-
          if (!loop)
            continue;
 
          flow_loop_free (loop);
        }
 
-      free (loops->parray);
-      loops->parray = NULL;
+      VEC_free (loop_p, heap, loops->larray);
+      loops->larray = NULL;
     }
 }
 
@@ -242,13 +235,11 @@ mark_single_exit_loops (void)
   basic_block bb;
   edge e;
   struct loop *loop;
-  unsigned i;
+  loop_iterator li;
 
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
-      loop = current_loops->parray[i];
-      if (loop)
-       set_single_exit (loop, NULL);
+      set_single_exit (loop, NULL);
     }
 
   FOR_EACH_BB (bb)
@@ -278,12 +269,8 @@ mark_single_exit_loops (void)
        }
     }
 
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
-      loop = current_loops->parray[i];
-      if (!loop)
-       continue;
-
       if (single_exit (loop) == single_succ_edge (ENTRY_BLOCK_PTR))
        set_single_exit (loop, NULL);
     }
@@ -499,20 +486,6 @@ canonicalize_loop_headers (void)
 #endif
 }
 
-/* Initialize all the parallel_p fields of the loops structure to true.  */
-
-static void
-initialize_loops_parallel_p (struct loops *loops)
-{
-  unsigned int i;
-
-  for (i = 0; i < loops->num; i++)
-    {
-      struct loop *loop = loops->parray[i];
-      loop->parallel_p = true;
-    }
-}
-
 /* Find all the natural loops in the function and save in LOOPS structure and
    recalculate loop_depth information in basic block structures.
    Return the number of natural loops found.  */
@@ -528,6 +501,7 @@ flow_loops_find (struct loops *loops)
   int *rc_order;
   basic_block header;
   basic_block bb;
+  struct loop *root;
 
   memset (loops, 0, sizeof *loops);
 
@@ -594,26 +568,21 @@ flow_loops_find (struct loops *loops)
     }
 
   /* Allocate loop structures.  */
-  loops->parray = XCNEWVEC (struct loop *, num_loops + 1);
+  loops->larray = VEC_alloc (loop_p, heap, num_loops + 1);
 
   /* Dummy loop containing whole function.  */
-  loops->parray[0] = XCNEW (struct loop);
-  loops->parray[0]->next = NULL;
-  loops->parray[0]->inner = NULL;
-  loops->parray[0]->outer = NULL;
-  loops->parray[0]->depth = 0;
-  loops->parray[0]->pred = NULL;
-  loops->parray[0]->num_nodes = n_basic_blocks;
-  loops->parray[0]->latch = EXIT_BLOCK_PTR;
-  loops->parray[0]->header = ENTRY_BLOCK_PTR;
-  ENTRY_BLOCK_PTR->loop_father = loops->parray[0];
-  EXIT_BLOCK_PTR->loop_father = loops->parray[0];
-
-  loops->tree_root = loops->parray[0];
+  root = XCNEW (struct loop);
+  root->num_nodes = n_basic_blocks;
+  root->latch = EXIT_BLOCK_PTR;
+  root->header = ENTRY_BLOCK_PTR;
+  ENTRY_BLOCK_PTR->loop_father = root;
+  EXIT_BLOCK_PTR->loop_father = root;
+
+  VEC_quick_push (loop_p, loops->larray, root);
+  loops->tree_root = root;
 
   /* Find and record information about all the natural loops
      in the CFG.  */
-  loops->num = 1;
   FOR_EACH_BB (bb)
     bb->loop_father = loops->tree_root;
 
@@ -639,7 +608,8 @@ flow_loops_find (struct loops *loops)
 
          header = BASIC_BLOCK (rc_order[b]);
 
-         loop = loops->parray[num_loops] = XCNEW (struct loop);
+         loop = XCNEW (struct loop);
+         VEC_quick_push (loop_p, loops->larray, loop);
 
          loop->header = header;
          loop->num = num_loops;
@@ -662,9 +632,6 @@ flow_loops_find (struct loops *loops)
          loop->num_nodes = flow_loop_nodes_find (loop->header, loop);
        }
 
-      loops->num = num_loops;
-      initialize_loops_parallel_p (loops);
-
       free (dfs_order);
       free (rc_order);
     }
@@ -672,7 +639,7 @@ flow_loops_find (struct loops *loops)
   sbitmap_free (headers);
 
   loops->state = 0;
-  return loops->num;
+  return VEC_length (loop_p, loops->larray);
 }
 
 /* Return nonzero if basic block BB belongs to LOOP.  */
@@ -924,6 +891,21 @@ find_common_loop (struct loop *loop_s, struct loop *loop_d)
   return loop_s;
 }
 
+/* Removes LOOP from structures and frees its data.  */
+
+void
+delete_loop (struct loop *loop)
+{
+  /* Remove the loop from structure.  */
+  flow_loop_tree_node_remove (loop);
+
+  /* Remove loop from loops array.  */
+  VEC_replace (loop_p, current_loops->larray, loop->num, NULL);
+
+  /* Free loop data.  */
+  flow_loop_free (loop);
+}
+
 /* Cancels the LOOP; it must be innermost one.  */
 
 static void
@@ -939,14 +921,7 @@ cancel_loop (struct loop *loop)
   for (i = 0; i < loop->num_nodes; i++)
     bbs[i]->loop_father = loop->outer;
 
-  /* Remove the loop from structure.  */
-  flow_loop_tree_node_remove (loop);
-
-  /* Remove loop from loops array.  */
-  current_loops->parray[loop->num] = NULL;
-
-  /* Free loop data.  */
-  flow_loop_free (loop);
+  delete_loop (loop);
 }
 
 /* Cancels LOOP and all its subloops.  */
@@ -974,52 +949,48 @@ verify_loop_structure (void)
   struct loop *loop;
   int err = 0;
   edge e;
+  unsigned num = number_of_loops ();
+  loop_iterator li;
 
   /* Check sizes.  */
-  sizes = XCNEWVEC (unsigned, current_loops->num);
+  sizes = XCNEWVEC (unsigned, num);
   sizes[0] = 2;
 
   FOR_EACH_BB (bb)
     for (loop = bb->loop_father; loop; loop = loop->outer)
       sizes[loop->num]++;
 
-  for (i = 0; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, LI_INCLUDE_ROOT)
     {
-      if (!current_loops->parray[i])
-       continue;
+      i = loop->num;
 
-      if (current_loops->parray[i]->num_nodes != sizes[i])
+      if (loop->num_nodes != sizes[i])
        {
          error ("size of loop %d should be %d, not %d",
-                  i, sizes[i], current_loops->parray[i]->num_nodes);
+                  i, sizes[i], loop->num_nodes);
          err = 1;
        }
     }
 
   /* Check get_loop_body.  */
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
-      loop = current_loops->parray[i];
-      if (!loop)
-       continue;
       bbs = get_loop_body (loop);
 
       for (j = 0; j < loop->num_nodes; j++)
        if (!flow_bb_inside_loop_p (loop, bbs[j]))
          {
            error ("bb %d do not belong to loop %d",
-                   bbs[j]->index, i);
+                   bbs[j]->index, loop->num);
            err = 1;
          }
       free (bbs);
     }
 
   /* Check headers and latches.  */
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
-      loop = current_loops->parray[i];
-      if (!loop)
-       continue;
+      i = loop->num;
 
       if ((current_loops->state & LOOPS_HAVE_PREHEADERS)
          && EDGE_COUNT (loop->header->preds) != 2)
@@ -1120,7 +1091,7 @@ verify_loop_structure (void)
   /* Check the single_exit.  */
   if (current_loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
     {
-      memset (sizes, 0, sizeof (unsigned) * current_loops->num);
+      memset (sizes, 0, sizeof (unsigned) * num);
       FOR_EACH_BB (bb)
        {
          edge_iterator ei;
@@ -1154,11 +1125,9 @@ verify_loop_structure (void)
            }
        }
 
-      for (i = 1; i < current_loops->num; i++)
+      FOR_EACH_LOOP (li, loop, 0)
        {
-         loop = current_loops->parray[i];
-         if (!loop)
-           continue;
+         i = loop->num;
 
          if (sizes[i] == 1
              && !single_exit (loop))
index fa0a456..d523acf 100644 (file)
@@ -146,12 +146,6 @@ struct loop
      EXIT_BLOCK_PTR do not count.  Do not use directly; this field should
      only be accessed via single_exit/set_single_exit functions.  */
   edge single_exit_;
-
-  /* True when the loop does not carry data dependences, and
-     consequently the iterations can be executed in any order.  False
-     when the loop carries data dependences, or when the property is
-     not decidable.  */
-  bool parallel_p;
 };
 
 /* Flags for state of loop structure.  */
@@ -166,26 +160,21 @@ enum
 #define LOOPS_NORMAL (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES \
                      | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
 
+typedef struct loop *loop_p;
+DEF_VEC_P (loop_p);
+DEF_VEC_ALLOC_P (loop_p, heap);
+
 /* Structure to hold CFG information about natural loops within a function.  */
 struct loops
 {
-  /* Number of natural loops in the function.  */
-  unsigned num;
-
   /* State of loops.  */
   int state;
 
-  /* We store just pointers to loops here.  
-     Note that a loop in this array may actually be NULL, if the loop
-     has been removed and the entire loops structure has not been
-     recomputed since that time.  */
-  struct loop **parray;
+  /* Array of the loops.  */
+  VEC (loop_p, heap) *larray;
 
   /* Pointer to root of loop hierarchy tree.  */
   struct loop *tree_root;
-
-  /* Headers shared by multiple loops that should be merged.  */
-  sbitmap shared_headers;
 };
 
 /* Loop recognition.  */
@@ -231,6 +220,7 @@ extern void add_bb_to_loop (basic_block, struct loop *);
 extern void remove_bb_from_loops (basic_block);
 
 extern void cancel_loop_tree (struct loop *);
+extern void delete_loop (struct loop *);
 
 extern int fix_loop_placement (struct loop *);
 
@@ -375,6 +365,124 @@ simple_loop_desc (struct loop *loop)
   return (struct niter_desc *) loop->aux;
 }
 
+/* Accessors for the loop structures.  */
+
+/* Returns the loop with index NUM from current_loops.  */
+
+static inline struct loop *
+get_loop (unsigned num)
+{
+  return VEC_index (loop_p, current_loops->larray, num);
+}
+
+/* Returns the list of loops in current_loops.  */
+
+static inline VEC (loop_p, heap) *
+get_loops (void)
+{
+  if (!current_loops)
+    return NULL;
+
+  return current_loops->larray;
+}
+
+/* Returns the number of loops in current_loops (including the removed
+   ones and the fake loop that forms the root of the loop tree).  */
+
+static inline unsigned
+number_of_loops (void)
+{
+  if (!current_loops)
+    return 0;
+
+  return VEC_length (loop_p, current_loops->larray);
+}
+
+/* Loop iterators.  */
+
+/* Flags for loop iteration.  */
+
+enum li_flags
+{
+  LI_INCLUDE_ROOT,     /* Include the fake root of the loop tree.  */
+  LI_FROM_INNERMOST,   /* Iterate over the loops in the reverse order,
+                          starting from innermost ones.  */
+  LI_ONLY_INNERMOST,   /* Iterate only over innermost loops.  */
+  LI_ONLY_OLD          /* Do not traverse the loops created during the
+                          traversal (this is the default behavior with
+                          LI_FROM_INNERMOST).  */
+};
+
+/* The iterator for loops.  */
+
+typedef struct
+{
+  int idx;             /* Index of the actual loop.  */
+  int end;             /* Only loops before end should be traversed.  */
+} loop_iterator;
+
+static inline void
+fel_next (loop_iterator *li, loop_p *loop, unsigned flags)
+{
+  if (flags & LI_FROM_INNERMOST)
+    {
+      li->idx--;
+      for (; li->idx > li->end; li->idx--)
+       {
+         *loop = VEC_index (loop_p, current_loops->larray, li->idx);
+         if (*loop
+             && (!(flags & LI_ONLY_INNERMOST)
+                 || (*loop)->inner == NULL))
+           return;
+       }
+    }
+  else
+    {
+      if (!(flags & LI_ONLY_OLD))
+       li->end = number_of_loops ();
+      li->idx++;
+      for (; li->idx < li->end; li->idx++)
+       {
+         *loop = VEC_index (loop_p, current_loops->larray, li->idx);
+         if (*loop
+             && (!(flags & LI_ONLY_INNERMOST)
+                 || (*loop)->inner == NULL))
+           return;
+       }
+    }
+
+  *loop = NULL;
+}
+
+static inline void
+fel_init (loop_iterator *li, loop_p *loop, unsigned flags)
+{
+  if (!current_loops)
+    {
+      li->idx = 0;
+      li->end = 0;
+      *loop = NULL;
+      return;
+    }
+
+  if (flags & LI_FROM_INNERMOST)
+    {
+      li->idx = number_of_loops ();
+      li->end = (flags & LI_INCLUDE_ROOT) ? -1 : 0;
+    }
+  else
+    {
+      li->idx = (flags & LI_INCLUDE_ROOT) ? -1 : 0;
+      li->end = number_of_loops ();
+    }
+  fel_next (li, loop, flags);
+}
+
+#define FOR_EACH_LOOP(LI, LOOP, FLAGS) \
+  for (fel_init (&(LI), &(LOOP), FLAGS); \
+       (LOOP); \
+       fel_next (&(LI), &(LOOP), FLAGS))
+
 /* The properties of the target.  */
 
 extern unsigned target_avail_regs;     /* Number of available registers.  */
index 16b3b46..5a91897 100644 (file)
@@ -273,11 +273,12 @@ mark_irreducible_loops (void)
   edge_iterator ei;
   int i, src, dest;
   struct graph *g;
-  int num = current_loops ? current_loops->num : 1;
+  int num = current_loops ? number_of_loops () : 1;
   int *queue1 = XNEWVEC (int, last_basic_block + num);
   int *queue2 = XNEWVEC (int, last_basic_block + num);
   int nq, depth;
-  struct loop *cloop;
+  struct loop *cloop, *loop;
+  loop_iterator li;
 
   /* Reset the flags.  */
   FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
@@ -343,9 +344,14 @@ mark_irreducible_loops (void)
     {
       queue1[nq++] = BB_REPR (act);
     }
-  for (i = 1; i < num; i++)
-    if (current_loops->parray[i])
-      queue1[nq++] = LOOP_REPR (current_loops->parray[i]);
+
+  if (current_loops)
+    {
+      FOR_EACH_LOOP (li, loop, 0)
+       {
+         queue1[nq++] = LOOP_REPR (loop);
+       }
+    }
   dfs (g, queue1, nq, queue2, false);
   for (i = 0; i < nq; i++)
     queue1[i] = queue2[nq - i - 1];
index 180a475..83d4e4c 100644 (file)
@@ -552,9 +552,7 @@ unloop (struct loop *loop, bool *irred_invalidated)
     }
 
   /* Remove the loop and free its data.  */
-  flow_loop_tree_node_remove (loop);
-  current_loops->parray[loop->num] = NULL;
-  flow_loop_free (loop);
+  delete_loop (loop);
 
   remove_edge (single_succ_edge (latch));
 
@@ -634,11 +632,8 @@ fix_loop_placements (struct loop *loop, bool *irred_invalidated)
 static void
 place_new_loop (struct loop *loop)
 {
-  current_loops->parray =
-    xrealloc (current_loops->parray, (current_loops->num + 1) * sizeof (struct loop *));
-  current_loops->parray[current_loops->num] = loop;
-
-  loop->num = current_loops->num++;
+  loop->num = number_of_loops ();
+  VEC_safe_push (loop_p, heap, current_loops->larray, loop);
 }
 
 /* Copies copy of LOOP as subloop of TARGET loop, placing newly
@@ -1195,9 +1190,11 @@ create_preheader (struct loop *loop, int flags)
 void
 create_preheaders (int flags)
 {
-  unsigned i;
-  for (i = 1; i < current_loops->num; i++)
-    create_preheader (current_loops->parray[i], flags);
+  loop_iterator li;
+  struct loop *loop;
+
+  FOR_EACH_LOOP (li, loop, 0)
+    create_preheader (loop, flags);
   current_loops->state |= LOOPS_HAVE_PREHEADERS;
 }
 
@@ -1206,13 +1203,12 @@ create_preheaders (int flags)
 void
 force_single_succ_latches (void)
 {
-  unsigned i;
+  loop_iterator li;
   struct loop *loop;
   edge e;
 
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
-      loop = current_loops->parray[i];
       if (loop->latch != loop->header && single_succ_p (loop->latch))
        continue;
 
@@ -1392,7 +1388,7 @@ fix_loop_structure (bitmap changed_bbs)
 {
   basic_block bb;
   struct loop *loop, *ploop;
-  unsigned i;
+  loop_iterator li;
 
   /* Remove the old bb -> loop mapping.  */
   FOR_EACH_BB (bb)
@@ -1403,12 +1399,8 @@ fix_loop_structure (bitmap changed_bbs)
 
   /* Remove the dead loops from structures.  */
   current_loops->tree_root->num_nodes = n_basic_blocks;
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
-      loop = current_loops->parray[i];
-      if (!loop)
-       continue;
-
       loop->num_nodes = 0;
       if (loop->header)
        continue;
@@ -1421,38 +1413,18 @@ fix_loop_structure (bitmap changed_bbs)
        }
 
       /* Remove the loop and free its data.  */
-      flow_loop_tree_node_remove (loop);
-      current_loops->parray[loop->num] = NULL;
-      flow_loop_free (loop);
+      delete_loop (loop);
     }
 
   /* Rescan the bodies of loops, starting from the outermost.  */
-  loop = current_loops->tree_root;
-  while (1)
+  FOR_EACH_LOOP (li, loop, 0)
     {
-      if (loop->inner)
-       loop = loop->inner;
-      else
-       {
-         while (!loop->next
-                && loop != current_loops->tree_root)
-           loop = loop->outer;
-         if (loop == current_loops->tree_root)
-           break;
-
-         loop = loop->next;
-       }
-
       loop->num_nodes = flow_loop_nodes_find (loop->header, loop);
     }
 
   /* Now fix the loop nesting.  */
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
-      loop = current_loops->parray[i];
-      if (!loop)
-       continue;
-
       bb = loop_preheader_edge (loop)->src;
       if (bb->loop_father != loop->outer)
        {
index 642a523..354241f 100644 (file)
@@ -63,20 +63,25 @@ The root of this tree is a fake loop that contains all blocks in the
 function.  Each of the loops is represented in a @code{struct loop}
 structure.  Each loop is assigned an index (@code{num} field of the
 @code{struct loop} structure), and the pointer to the loop is stored in
-the corresponding field of the @code{parray} field of the loops
+the corresponding field of the @code{larray} vector in the loops
 structure.  Index of a sub-loop is always greater than the index of its
 super-loop.  The indices do not have to be continuous, there may be
-empty (@code{NULL}) entries in the @code{parray} created by deleting
-loops.  The index of a loop never changes.  The first unused index is
-stored in the @code{num} field of the loops structure.
+empty (@code{NULL}) entries in the @code{larray} created by deleting
+loops.  The index of a loop never changes.
+
+The entries of the @code{larray} field should not be accessed directly.
+The function @code{get_loop} returns the loop description for a loop with
+the given index.  @code{number_of_loops} function returns number of
+loops in the function.  To traverse all loops, use @code{FOR_EACH_LOOP}
+macro.  The @code{flags} argument of the macro is used to determine
+the direction of traversal and the set of loops visited.
 
 Each basic block contains the reference to the innermost loop it belongs
 to (@code{loop_father}).  For this reason, it is only possible to have
 one @code{struct loops} structure initialized at the same time for each
-CFG.  It is recommended to use the global variable @code{current_loops}
-to contain the @code{struct loops} structure, especially if the loop
-structures are updated throughout several passes.  Many of the loop
-manipulation functions assume that dominance information is up-to-date.
+CFG.  The global variable @code{current_loops} contains the
+@code{struct loops} structure.  Many of the loop manipulation functions
+assume that dominance information is up-to-date.
 
 The loops are analyzed through @code{loop_optimizer_init} function.  The
 argument of this function is a set of flags represented in an integer
index 093ec30..ef42c60 100644 (file)
@@ -621,15 +621,11 @@ doloop_optimize (struct loop *loop)
 void
 doloop_optimize_loops (void)
 {
-  unsigned i;
+  loop_iterator li;
   struct loop *loop;
 
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
-      loop = current_loops->parray[i];
-      if (!loop)
-       continue;
-
       doloop_optimize (loop);
     }
 
index 35727c0..32e56b3 100644 (file)
@@ -68,9 +68,10 @@ loop_optimizer_init (unsigned flags)
   flow_loops_find (loops);
   current_loops = loops;
 
-  if (current_loops->num <= 1)
+  if (number_of_loops () <= 1)
     {
-      /* No loops.  */
+      /* No loops (the 1 returned by number_of_loops corresponds to the fake
+        loop that we put as a root of the loop tree).  */
       loop_optimizer_finalize ();
       return;
     }
@@ -104,15 +105,17 @@ loop_optimizer_init (unsigned flags)
 void
 loop_optimizer_finalize (void)
 {
-  unsigned i;
+  loop_iterator li;
+  struct loop *loop;
   basic_block bb;
 
   if (!current_loops)
     return;
 
-  for (i = 1; i < current_loops->num; i++)
-    if (current_loops->parray[i])
-      free_simple_loop_desc (current_loops->parray[i]);
+  FOR_EACH_LOOP (li, loop, 0)
+    {
+      free_simple_loop_desc (loop);
+    }
 
   /* Clean up.  */
   flow_loops_free (current_loops);
index d4258f0..4c6e8bc 100644 (file)
@@ -1318,33 +1318,21 @@ void
 move_loop_invariants (void)
 {
   struct loop *loop;
-  unsigned i;
+  loop_iterator li;
 
   df = df_init (DF_HARD_REGS | DF_EQUIV_NOTES);
   df_chain_add_problem (df, DF_UD_CHAIN);
  
   /* Process the loops, innermost first.  */
-  loop = current_loops->tree_root;
-  while (loop->inner)
-    loop = loop->inner;
-
-  while (loop != current_loops->tree_root)
+  FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
     {
       move_single_loop_invariants (loop);
-
-      if (loop->next)
-       {
-         loop = loop->next;
-         while (loop->inner)
-           loop = loop->inner;
-       }
-      else
-       loop = loop->outer;
     }
 
-  for (i = 1; i < current_loops->num; i++)
-    if (current_loops->parray[i])
-      free_loop_data (current_loops->parray[i]);
+  FOR_EACH_LOOP (li, loop, 0)
+    {
+      free_loop_data (loop);
+    }
 
   df_finish (df);
   df = NULL;
index 776b2e1..3a79dcc 100644 (file)
@@ -144,8 +144,9 @@ static rtx get_expansion (struct var_to_expand *);
 void
 unroll_and_peel_loops (int flags)
 {
-  struct loop *loop, *next;
+  struct loop *loop;
   bool check;
+  loop_iterator li;
 
   /* First perform complete loop peeling (it is almost surely a win,
      and affects parameters for further decision a lot).  */
@@ -154,22 +155,9 @@ unroll_and_peel_loops (int flags)
   /* Now decide rest of unrolling and peeling.  */
   decide_unrolling_and_peeling (flags);
 
-  loop = current_loops->tree_root;
-  while (loop->inner)
-    loop = loop->inner;
-
   /* Scan the loops, inner ones first.  */
-  while (loop != current_loops->tree_root)
+  FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
     {
-      if (loop->next)
-       {
-         next = loop->next;
-         while (next->inner)
-           next = next->inner;
-       }
-      else
-       next = loop->outer;
-
       check = true;
       /* And perform the appropriate transformations.  */
       switch (loop->lpt_decision.decision)
@@ -202,7 +190,6 @@ unroll_and_peel_loops (int flags)
          verify_loop_structure ();
 #endif
        }
-      loop = next;
     }
 
   iv_analysis_done ();
@@ -234,15 +221,11 @@ static void
 peel_loops_completely (int flags)
 {
   struct loop *loop;
-  unsigned i;
+  loop_iterator li;
 
   /* Scan the loops, the inner ones first.  */
-  for (i = current_loops->num - 1; i > 0; i--)
+  FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
     {
-      loop = current_loops->parray[i];
-      if (!loop)
-       continue;
-
       loop->lpt_decision.decision = LPT_NONE;
 
       if (dump_file)
@@ -271,23 +254,12 @@ peel_loops_completely (int flags)
 static void
 decide_unrolling_and_peeling (int flags)
 {
-  struct loop *loop = current_loops->tree_root, *next;
-
-  while (loop->inner)
-    loop = loop->inner;
+  struct loop *loop;
+  loop_iterator li;
 
   /* Scan the loops, inner ones first.  */
-  while (loop != current_loops->tree_root)
+  FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
     {
-      if (loop->next)
-       {
-         next = loop->next;
-         while (next->inner)
-           next = next->inner;
-       }
-      else
-       next = loop->outer;
-
       loop->lpt_decision.decision = LPT_NONE;
 
       if (dump_file)
@@ -298,7 +270,6 @@ decide_unrolling_and_peeling (int flags)
        {
          if (dump_file)
            fprintf (dump_file, ";; Not considering loop, cold area\n");
-         loop = next;
          continue;
        }
 
@@ -308,7 +279,6 @@ decide_unrolling_and_peeling (int flags)
          if (dump_file)
            fprintf (dump_file,
                     ";; Not considering loop, cannot duplicate\n");
-         loop = next;
          continue;
        }
 
@@ -317,7 +287,6 @@ decide_unrolling_and_peeling (int flags)
        {
          if (dump_file)
            fprintf (dump_file, ";; Not considering loop, is not innermost\n");
-         loop = next;
          continue;
        }
 
@@ -334,8 +303,6 @@ decide_unrolling_and_peeling (int flags)
        decide_unroll_stupid (loop, flags);
       if (loop->lpt_decision.decision == LPT_NONE)
        decide_peel_simple (loop, flags);
-
-      loop = next;
     }
 }
 
index db236e8..82cf1ea 100644 (file)
@@ -138,22 +138,13 @@ compare_and_jump_seq (rtx op0, rtx op1, enum rtx_code comp, rtx label, int prob,
 void
 unswitch_loops (void)
 {
-  int i, num;
+  loop_iterator li;
   struct loop *loop;
 
   /* Go through inner loops (only original ones).  */
-  num = current_loops->num;
 
-  for (i = 1; i < num; i++)
+  FOR_EACH_LOOP (li, loop, LI_ONLY_OLD | LI_ONLY_INNERMOST)
     {
-      /* Removed loop?  */
-      loop = current_loops->parray[i];
-      if (!loop)
-       continue;
-
-      if (loop->inner)
-       continue;
-
       unswitch_single_loop (loop, NULL_RTX, 0);
 #ifdef ENABLE_CHECKING
       verify_dominators (CDI_DOMINATORS);
index 4160e99..3352e20 100644 (file)
@@ -878,12 +878,11 @@ sms_schedule (void)
   ddg_ptr *g_arr, g;
   int * node_order;
   int maxii;
-  unsigned i,num_loops;
+  loop_iterator li;
   partial_schedule_ptr ps;
   struct df *df;
   basic_block bb = NULL;
-  /* vars to the versioning only if needed*/
-  struct loop * nloop;
+  struct loop *loop, *nloop;
   basic_block condition_bb = NULL;
   edge latch_edge;
   gcov_type trip_count = 0;
@@ -921,16 +920,14 @@ sms_schedule (void)
 
   /* Allocate memory to hold the DDG array one entry for each loop.
      We use loop->num as index into this array.  */
-  g_arr = XCNEWVEC (ddg_ptr, current_loops->num);
-
+  g_arr = XCNEWVEC (ddg_ptr, number_of_loops ());
 
   /* Build DDGs for all the relevant loops and hold them in G_ARR
      indexed by the loop index.  */
-  for (i = 0; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
       rtx head, tail;
       rtx count_reg;
-      struct loop *loop = current_loops->parray[i];
 
       /* For debugging.  */
       if ((passes++ > MAX_SMS_LOOP_NUMBER) && (MAX_SMS_LOOP_NUMBER != -1))
@@ -1019,7 +1016,7 @@ sms_schedule (void)
          continue;
         }
 
-      g_arr[i] = g;
+      g_arr[loop->num] = g;
     }
 
   /* Release Data Flow analysis data structures.  */
@@ -1027,18 +1024,15 @@ sms_schedule (void)
   df = NULL;
 
   /* We don't want to perform SMS on new loops - created by versioning.  */
-  num_loops = current_loops->num;
-  /* Go over the built DDGs and perfrom SMS for each one of them.  */
-  for (i = 0; i < num_loops; i++)
+  FOR_EACH_LOOP (li, loop, LI_ONLY_OLD)
     {
       rtx head, tail;
       rtx count_reg, count_init;
       int mii, rec_mii;
       unsigned stage_count = 0;
       HOST_WIDEST_INT loop_count = 0;
-      struct loop *loop = current_loops->parray[i];
 
-      if (! (g = g_arr[i]))
+      if (! (g = g_arr[loop->num]))
         continue;
 
       if (dump_file)
index 4b5344b..534258f 100644 (file)
@@ -630,17 +630,17 @@ combine_predictions_for_bb (basic_block bb)
 static void
 predict_loops (void)
 {
-  unsigned i;
+  loop_iterator li;
+  struct loop *loop;
 
   scev_initialize ();
 
   /* Try to predict out blocks in a loop that are not part of a
      natural loop.  */
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
       basic_block bb, *bbs;
       unsigned j, n_exits;
-      struct loop *loop = current_loops->parray[i];
       VEC (edge, heap) *exits;
       struct tree_niter_desc niter_desc;
       edge ex;
index e4733a2..59a32ea 100644 (file)
@@ -1245,7 +1245,6 @@ replace_uses_by (tree name, tree val)
   use_operand_p use;
   tree stmt;
   edge e;
-  unsigned i;
 
   FOR_EACH_IMM_USE_STMT (stmt, imm_iter, name)
     {
@@ -1286,12 +1285,11 @@ replace_uses_by (tree name, tree val)
   if (current_loops)
     {
       struct loop *loop;
+      loop_iterator li;
 
-      for (i = 0; i < current_loops->num; i++)
+      FOR_EACH_LOOP (li, loop, 0)
        {
-         loop = current_loops->parray[i];
-         if (loop)
-           substitute_in_loop_info (loop, name, val);
+         substitute_in_loop_info (loop, name, val);
        }
     }
 }
index a74a49c..01d0bf9 100644 (file)
@@ -939,8 +939,7 @@ evolution_function_is_invariant_rec_p (tree chrec, int loopnum)
     return true;
 
   if (TREE_CODE (chrec) == SSA_NAME 
-      && expr_invariant_in_loop_p (current_loops->parray[loopnum],
-                                  chrec))
+      && expr_invariant_in_loop_p (get_loop (loopnum), chrec))
     return true;
 
   if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
@@ -1280,7 +1279,7 @@ chrec_convert_1 (tree type, tree chrec, tree at_stmt,
   if (!evolution_function_is_affine_p (chrec))
     goto keep_cast;
 
-  loop = current_loops->parray[CHREC_VARIABLE (chrec)];
+  loop = get_chrec_loop (chrec);
   base = CHREC_LEFT (chrec);
   step = CHREC_RIGHT (chrec);
 
index bc5c778..c22867b 100644 (file)
@@ -22,14 +22,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #ifndef GCC_TREE_CHREC_H
 #define GCC_TREE_CHREC_H
 
-/* Accessors for the chains of recurrences.  */
-#define CHREC_VAR(NODE)           TREE_OPERAND (NODE, 0)
-#define CHREC_LEFT(NODE)          TREE_OPERAND (NODE, 1)
-#define CHREC_RIGHT(NODE)         TREE_OPERAND (NODE, 2)
-#define CHREC_VARIABLE(NODE)      TREE_INT_CST_LOW (CHREC_VAR (NODE))
-
-\f
-
 /* The following trees are unique elements.  Thus the comparison of another 
    element to these elements should be done on the pointer to these trees, 
    and not on their value.  */
index 7ed14f0..96d57a0 100644 (file)
@@ -2304,7 +2304,7 @@ analyze_ziv_subscript (tree chrec_a,
 static tree
 get_number_of_iters_for_loop (int loopnum)
 {
-  struct loop *loop = current_loops->parray[loopnum];
+  struct loop *loop = get_loop (loopnum);
   tree numiter = number_of_iterations_in_loop (loop);
 
   if (TREE_CODE (numiter) == INTEGER_CST)
@@ -4109,7 +4109,6 @@ find_data_references_in_loop (struct loop *loop,
   block_stmt_iterator bsi;
 
   bbs = get_loop_body (loop);
-  loop->parallel_p = true;
 
   for (i = 0; i < loop->num_nodes; i++)
     {
@@ -4137,16 +4136,11 @@ find_data_references_in_loop (struct loop *loop,
              DR_OFFSET_MISALIGNMENT (res) = NULL_TREE;
              DR_MEMTAG (res) = NULL_TREE;
              DR_PTR_INFO (res) = NULL;
-             loop->parallel_p = false;
              VEC_safe_push (data_reference_p, heap, *datarefs, res);
 
              free (bbs);
              return chrec_dont_know;
            }
-
-         /* When there are no defs in the loop, the loop is parallel.  */
-         if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
-           loop->parallel_p = false;
        }
     }
   free (bbs);
index 2d23dce..8c6ee41 100644 (file)
@@ -224,10 +224,6 @@ DEF_VEC_ALLOC_P (subscript_p, heap);
 #define SUB_LAST_CONFLICT(SUB) SUB->last_conflict
 #define SUB_DISTANCE(SUB) SUB->distance
 
-typedef struct loop *loop_p;
-DEF_VEC_P(loop_p);
-DEF_VEC_ALLOC_P (loop_p, heap);
-
 /* A data_dependence_relation represents a relation between two
    data_references A and B.  */
 
index 2f30435..e97824f 100644 (file)
@@ -1092,19 +1092,14 @@ bb_with_exit_edge_p (struct loop *loop, basic_block bb)
 static unsigned int
 main_tree_if_conversion (void)
 {
-  unsigned i, loop_num;
+  loop_iterator li;
   struct loop *loop;
 
   if (!current_loops)
     return 0;
 
-  loop_num = current_loops->num;
-  for (i = 0; i < loop_num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
-      loop =  current_loops->parray[i];
-      if (!loop)
-      continue;
-
       tree_if_conversion (loop, true);
     }
   return 0;
index 0c1c685..61fdee3 100644 (file)
@@ -242,16 +242,16 @@ void
 linear_transform_loops (void)
 {
   bool modified = false;
-  unsigned int i;
+  loop_iterator li;
   VEC(tree,heap) *oldivs = NULL;
   VEC(tree,heap) *invariants = NULL;
+  struct loop *loop_nest;
   
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop_nest, 0)
     {
       unsigned int depth = 0;
       VEC (ddr_p, heap) *dependence_relations;
       VEC (data_reference_p, heap) *datarefs;
-      struct loop *loop_nest = current_loops->parray[i];
       struct loop *temp;
       lambda_loopnest before, after;
       lambda_trans_matrix trans;
@@ -270,7 +270,7 @@ linear_transform_loops (void)
                 ...
                }
            } */
-      if (!loop_nest || !loop_nest->inner || !single_exit (loop_nest))
+      if (!loop_nest->inner || !single_exit (loop_nest))
        continue;
       VEC_truncate (tree, oldivs, 0);
       VEC_truncate (tree, invariants, 0);
index b882d45..c668bf2 100644 (file)
@@ -375,7 +375,7 @@ chrec_contains_symbols_defined_in_loop (tree chrec, unsigned loop_nb)
     {
       tree def = SSA_NAME_DEF_STMT (chrec);
       struct loop *def_loop = loop_containing_stmt (def);
-      struct loop *loop = current_loops->parray[loop_nb];
+      struct loop *loop = get_loop (loop_nb);
 
       if (def_loop == NULL)
        return false;
@@ -467,8 +467,7 @@ compute_overall_effect_of_inner_loop (struct loop *loop, tree evolution_fn)
     {
       if (CHREC_VARIABLE (evolution_fn) >= (unsigned) loop->num)
        {
-         struct loop *inner_loop = 
-           current_loops->parray[CHREC_VARIABLE (evolution_fn)];
+         struct loop *inner_loop = get_chrec_loop (evolution_fn);
          tree nb_iter = number_of_iterations_in_loop (inner_loop);
 
          if (nb_iter == chrec_dont_know)
@@ -534,9 +533,7 @@ chrec_is_positive (tree chrec, bool *value)
       if (!evolution_function_is_affine_p (chrec))
        return false;
 
-      nb_iter = number_of_iterations_in_loop
-       (current_loops->parray[CHREC_VARIABLE (chrec)]);
-
+      nb_iter = number_of_iterations_in_loop (get_chrec_loop (chrec));
       if (chrec_contains_undetermined (nb_iter))
        return false;
 
@@ -2530,7 +2527,7 @@ number_of_iterations_for_all_loops (VEC(tree,heap) **exit_conditions)
       fprintf (dump_file, "-----------------------------------------\n");
       fprintf (dump_file, "%d\tnb_chrec_dont_know_loops\n", nb_chrec_dont_know_loops);
       fprintf (dump_file, "%d\tnb_static_loops\n", nb_static_loops);
-      fprintf (dump_file, "%d\tnb_total_loops\n", current_loops->num);
+      fprintf (dump_file, "%d\tnb_total_loops\n", number_of_loops ());
       fprintf (dump_file, "-----------------------------------------\n");
       fprintf (dump_file, ")\n\n");
       
@@ -2747,7 +2744,8 @@ initialize_scalar_evolutions_analyzer (void)
 void
 scev_initialize (void)
 {
-  unsigned i;
+  loop_iterator li;
+  struct loop *loop;
 
   scalar_evolution_info = htab_create (100, hash_scev_info,
                                       eq_scev_info, del_scev_info);
@@ -2755,9 +2753,10 @@ scev_initialize (void)
   
   initialize_scalar_evolutions_analyzer ();
 
-  for (i = 1; i < current_loops->num; i++)
-    if (current_loops->parray[i])
-      current_loops->parray[i]->nb_iterations = NULL_TREE;
+  FOR_EACH_LOOP (li, loop, 0)
+    {
+      loop->nb_iterations = NULL_TREE;
+    }
 }
 
 /* Cleans up the information cached by the scalar evolutions analysis.  */
@@ -2765,18 +2764,16 @@ scev_initialize (void)
 void
 scev_reset (void)
 {
-  unsigned i;
+  loop_iterator li;
   struct loop *loop;
 
   if (!scalar_evolution_info || !current_loops)
     return;
 
   htab_empty (scalar_evolution_info);
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
-      loop = current_loops->parray[i];
-      if (loop)
-       loop->nb_iterations = NULL_TREE;
+      loop->nb_iterations = NULL_TREE;
     }
 }
 
@@ -2890,6 +2887,7 @@ scev_const_prop (void)
   struct loop *loop, *ex_loop;
   bitmap ssa_names_to_remove = NULL;
   unsigned i;
+  loop_iterator li;
 
   if (!current_loops)
     return 0;
@@ -2931,7 +2929,6 @@ scev_const_prop (void)
   if (ssa_names_to_remove)
     {
       bitmap_iterator bi;
-      unsigned i;
 
       EXECUTE_IF_SET_IN_BITMAP (ssa_names_to_remove, 0, i, bi)
        {
@@ -2947,16 +2944,12 @@ scev_const_prop (void)
     }
 
   /* Now the regular final value replacement.  */
-  for (i = current_loops->num - 1; i > 0; i--)
+  FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
     {
       edge exit;
       tree def, rslt, ass, niter;
       block_stmt_iterator bsi;
 
-      loop = current_loops->parray[i];
-      if (!loop)
-       continue;
-
       /* If we do not know exact number of iterations of the loop, we cannot
         replace the final value.  */
       exit = single_exit (loop);
index ad3ddd5..98855b9 100644 (file)
@@ -36,4 +36,12 @@ unsigned int scev_const_prop (void);
 
 extern bool simple_iv (struct loop *, tree, tree, affine_iv *, bool);
 
+/* Returns the loop of the polynomial chrec CHREC.  */
+
+static inline struct loop *
+get_chrec_loop (tree chrec)
+{
+  return get_loop (CHREC_VARIABLE (chrec));
+}
+
 #endif  /* GCC_TREE_SCALAR_EVOLUTION_H  */
index bcbc514..e1d5af8 100644 (file)
@@ -123,7 +123,7 @@ do_while_loop_p (struct loop *loop)
 static unsigned int
 copy_loop_headers (void)
 {
-  unsigned i;
+  loop_iterator li;
   struct loop *loop;
   basic_block header;
   edge exit, entry;
@@ -144,14 +144,11 @@ copy_loop_headers (void)
   copied_bbs = XNEWVEC (basic_block, n_basic_blocks);
   bbs_size = n_basic_blocks;
 
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
       /* Copy at most 20 insns.  */
       int limit = 20;
 
-      loop = current_loops->parray[i];
-      if (!loop)
-       continue;
       header = loop->header;
 
       /* If the loop is already a do-while style one (either because it was
index 9fd0eba..9bdffa2 100644 (file)
@@ -1377,34 +1377,17 @@ static void
 determine_lsm (void)
 {
   struct loop *loop;
-
-  if (!current_loops->tree_root->inner)
-    return;
+  loop_iterator li;
 
   /* Pass the loops from the outermost and perform the store motion as
      suitable.  */
 
-  loop = current_loops->tree_root->inner;
-  while (1)
+  FOR_EACH_LOOP (li, loop, 0)
     {
       determine_lsm_loop (loop);
-
-      if (loop->inner)
-       {
-         loop = loop->inner;
-         continue;
-       }
-      while (!loop->next)
-       {
-         loop = loop->outer;
-         if (loop == current_loops->tree_root)
-           {
-             bsi_commit_edge_inserts ();
-             return;
-           }
-       }
-      loop = loop->next;
     }
+
+  bsi_commit_edge_inserts ();
 }
 
 /* Fills ALWAYS_EXECUTED_IN information for basic blocks of LOOP, i.e.
index 7dcb0da..6326801 100644 (file)
@@ -332,18 +332,15 @@ canonicalize_loop_induction_variables (struct loop *loop,
 unsigned int
 canonicalize_induction_variables (void)
 {
-  unsigned i;
+  loop_iterator li;
   struct loop *loop;
   bool changed = false;
   
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
-      loop = current_loops->parray[i];
-
-      if (loop)
-       changed |= canonicalize_loop_induction_variables (loop,
-                                                         true, UL_SINGLE_ITER,
-                                                         true);
+      changed |= canonicalize_loop_induction_variables (loop,
+                                                       true, UL_SINGLE_ITER,
+                                                       true);
     }
 
   /* Clean up the information about numbers of iterations, since brute force
@@ -362,18 +359,13 @@ canonicalize_induction_variables (void)
 unsigned int
 tree_unroll_loops_completely (bool may_increase_size)
 {
-  unsigned i;
+  loop_iterator li;
   struct loop *loop;
   bool changed = false;
   enum unroll_level ul;
 
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
-      loop = current_loops->parray[i];
-
-      if (!loop)
-       continue;
-
       if (may_increase_size && maybe_hot_bb_p (loop->header))
        ul = UL_ALL;
       else
index 0132fc9..1aea162 100644 (file)
@@ -5889,30 +5889,17 @@ tree_ssa_iv_optimize (void)
 {
   struct loop *loop;
   struct ivopts_data data;
+  loop_iterator li;
 
   tree_ssa_iv_optimize_init (&data);
 
   /* Optimize the loops starting with the innermost ones.  */
-  loop = current_loops->tree_root;
-  while (loop->inner)
-    loop = loop->inner;
-
-  /* Scan the loops, inner ones first.  */
-  while (loop != current_loops->tree_root)
+  FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
        flow_loop_dump (loop, dump_file, NULL, 1);
 
       tree_ssa_iv_optimize_loop (&data, loop);
-
-      if (loop->next)
-       {
-         loop = loop->next;
-         while (loop->inner)
-           loop = loop->inner;
-       }
-      else
-       loop = loop->outer;
     }
 
   tree_ssa_iv_optimize_finalize (&data);
index de9ce1c..bff08a0 100644 (file)
@@ -2024,14 +2024,12 @@ estimate_numbers_of_iterations_loop (struct loop *loop)
 void
 estimate_numbers_of_iterations (void)
 {
-  unsigned i;
+  loop_iterator li;
   struct loop *loop;
 
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
-      loop = current_loops->parray[i];
-      if (loop)
-       estimate_numbers_of_iterations_loop (loop);
+      estimate_numbers_of_iterations_loop (loop);
     }
 }
 
@@ -2246,14 +2244,12 @@ free_numbers_of_iterations_estimates_loop (struct loop *loop)
 void
 free_numbers_of_iterations_estimates (void)
 {
-  unsigned i;
+  loop_iterator li;
   struct loop *loop;
 
-  for (i = 1; i < current_loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
-      loop = current_loops->parray[i];
-      if (loop)
-       free_numbers_of_iterations_estimates_loop (loop);
+      free_numbers_of_iterations_estimates_loop (loop);
     }
 }
 
index 114d0e3..5f39b8d 100644 (file)
@@ -998,7 +998,7 @@ fail:
 unsigned int
 tree_ssa_prefetch_arrays (void)
 {
-  unsigned i;
+  loop_iterator li;
   struct loop *loop;
   bool unrolled = false;
   int todo_flags = 0;
@@ -1043,12 +1043,8 @@ tree_ssa_prefetch_arrays (void)
      here.  */
   gcc_assert ((PREFETCH_BLOCK & (PREFETCH_BLOCK - 1)) == 0);
 
-  for (i = current_loops->num - 1; i > 0; i--)
+  FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
     {
-      loop = current_loops->parray[i];
-      if (!loop)
-       continue;
-
       if (dump_file && (dump_flags & TDF_DETAILS))
        fprintf (dump_file, "Processing loop %d:\n", loop->num);
 
index 3c58e8c..52465db 100644 (file)
@@ -82,23 +82,13 @@ static tree tree_may_unswitch_on (basic_block, struct loop *);
 unsigned int
 tree_ssa_unswitch_loops (void)
 {
-  int i, num;
+  loop_iterator li;
   struct loop *loop;
   bool changed = false;
 
   /* Go through inner loops (only original ones).  */
-  num = current_loops->num;
-
-  for (i = 1; i < num; i++)
+  FOR_EACH_LOOP (li, loop, LI_ONLY_OLD | LI_ONLY_INNERMOST)
     {
-      /* Removed loop?  */
-      loop = current_loops->parray[i];
-      if (!loop)
-       continue;
-
-      if (loop->inner)
-       continue;
-
       changed |= tree_unswitch_single_loop (loop, 0);
     }
 
index 9974343..d948c99 100644 (file)
@@ -174,9 +174,6 @@ FILE *vect_dump;
    to mark that it's uninitialized.  */
 enum verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;
 
-/* Number of loops, at the beginning of vectorization.  */
-unsigned int vect_loops_num;
-
 /* Loop location.  */
 static LOC vect_loop_location;
 
@@ -2157,6 +2154,9 @@ vectorize_loops (void)
 {
   unsigned int i;
   unsigned int num_vectorized_loops = 0;
+  unsigned int vect_loops_num;
+  loop_iterator li;
+  struct loop *loop;
 
   /* Fix the verbosity level if not defined explicitly by the user.  */
   vect_set_dump_settings ();
@@ -2170,14 +2170,10 @@ vectorize_loops (void)
   /* If some loop was duplicated, it gets bigger number 
      than all previously defined loops. This fact allows us to run 
      only over initial loops skipping newly generated ones.  */
-  vect_loops_num = current_loops->num;
-  for (i = 1; i < vect_loops_num; i++)
+  vect_loops_num = number_of_loops ();
+  FOR_EACH_LOOP (li, loop, LI_ONLY_OLD)
     {
       loop_vec_info loop_vinfo;
-      struct loop *loop = current_loops->parray[i];
-
-      if (!loop)
-        continue;
 
       vect_loop_location = find_loop_location (loop);
       loop_vinfo = vect_analyze_loop (loop);
@@ -2201,9 +2197,9 @@ vectorize_loops (void)
 
   for (i = 1; i < vect_loops_num; i++)
     {
-      struct loop *loop = current_loops->parray[i];
       loop_vec_info loop_vinfo;
 
+      loop = get_loop (i);
       if (!loop)
        continue;
       loop_vinfo = loop->aux;
index 0c026b1..325f402 100644 (file)
@@ -327,9 +327,6 @@ known_alignment_for_access_p (struct data_reference *data_ref_info)
 extern FILE *vect_dump;
 extern enum verbosity_levels vect_verbosity_level;
 
-/* Number of loops, at the beginning of vectorization.  */
-extern unsigned int vect_loops_num;
-
 /* Bitmap of virtual variables to be renamed.  */
 extern bitmap vect_vnames_to_rename;
 
index eb28ca9..8e9d3ca 100644 (file)
@@ -1998,8 +1998,7 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
         or decreases,  ... */
       dir == EV_DIR_UNKNOWN
       /* ... or if it may wrap.  */
-      || scev_probably_wraps_p (init, step, stmt,
-                               current_loops->parray[CHREC_VARIABLE (chrec)],
+      || scev_probably_wraps_p (init, step, stmt, get_chrec_loop (chrec),
                                true))
     return;
 
index 98be968..4e42c9b 100644 (file)
@@ -1587,6 +1587,12 @@ struct tree_constructor GTY(())
 #define COND_EXPR_THEN(NODE)   (TREE_OPERAND (COND_EXPR_CHECK (NODE), 1))
 #define COND_EXPR_ELSE(NODE)   (TREE_OPERAND (COND_EXPR_CHECK (NODE), 2))
 
+/* Accessors for the chains of recurrences.  */
+#define CHREC_VAR(NODE)           TREE_OPERAND (POLYNOMIAL_CHREC_CHECK (NODE), 0)
+#define CHREC_LEFT(NODE)          TREE_OPERAND (POLYNOMIAL_CHREC_CHECK (NODE), 1)
+#define CHREC_RIGHT(NODE)         TREE_OPERAND (POLYNOMIAL_CHREC_CHECK (NODE), 2)
+#define CHREC_VARIABLE(NODE)      TREE_INT_CST_LOW (CHREC_VAR (NODE))
+
 /* LABEL_EXPR accessor. This gives access to the label associated with
    the given label expression.  */
 #define LABEL_EXPR_LABEL(NODE)  TREE_OPERAND (LABEL_EXPR_CHECK (NODE), 0)