This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Change the array of loops to vector


Hello,

this patch is the next in the series of cleanups for the loop
representation.  It changes the representation used for the list of
loops in function to a vector.  To make the transition easier, it
introduces several new accessors (get_loop, number_of_loops,
and FOR_EACH_LOOP macro) that should be used to access the loop
information instead of querying it directly.

The patch also removes several unused fields from the loop structures.

Bootstrapped & regtested on i686 and x86_64, commited.

Zdenek

Index: ChangeLog
===================================================================
*** ChangeLog	(revision 119711)
--- ChangeLog	(working copy)
***************
*** 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: tree-vrp.c
===================================================================
*** tree-vrp.c	(revision 119711)
--- tree-vrp.c	(working copy)
*************** adjust_range_with_scev (value_range_t *v
*** 1998,2005 ****
  	 or decreases,  ... */
        dir == EV_DIR_UNKNOWN
        /* ... or if it may wrap.  */
!       || scev_probably_wraps_p (init, step, stmt,
! 				current_loops->parray[CHREC_VARIABLE (chrec)],
  				true))
      return;
  
--- 1998,2004 ----
  	 or decreases,  ... */
        dir == EV_DIR_UNKNOWN
        /* ... or if it may wrap.  */
!       || scev_probably_wraps_p (init, step, stmt, get_chrec_loop (chrec),
  				true))
      return;
  
Index: loop-unswitch.c
===================================================================
*** loop-unswitch.c	(revision 119711)
--- loop-unswitch.c	(working copy)
*************** compare_and_jump_seq (rtx op0, rtx op1, 
*** 138,159 ****
  void
  unswitch_loops (void)
  {
!   int i, num;
    struct loop *loop;
  
    /* Go through inner loops (only original ones).  */
-   num = current_loops->num;
  
!   for (i = 1; i < num; i++)
      {
-       /* 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);
--- 138,150 ----
  void
  unswitch_loops (void)
  {
!   loop_iterator li;
    struct loop *loop;
  
    /* Go through inner loops (only original ones).  */
  
!   FOR_EACH_LOOP (li, loop, LI_ONLY_OLD | LI_ONLY_INNERMOST)
      {
        unswitch_single_loop (loop, NULL_RTX, 0);
  #ifdef ENABLE_CHECKING
        verify_dominators (CDI_DOMINATORS);
Index: tree-loop-linear.c
===================================================================
*** tree-loop-linear.c	(revision 119711)
--- tree-loop-linear.c	(working copy)
*************** void
*** 242,257 ****
  linear_transform_loops (void)
  {
    bool modified = false;
!   unsigned int i;
    VEC(tree,heap) *oldivs = NULL;
    VEC(tree,heap) *invariants = NULL;
    
!   for (i = 1; i < current_loops->num; i++)
      {
        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;
--- 242,257 ----
  linear_transform_loops (void)
  {
    bool modified = false;
!   loop_iterator li;
    VEC(tree,heap) *oldivs = NULL;
    VEC(tree,heap) *invariants = NULL;
+   struct loop *loop_nest;
    
!   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 *temp;
        lambda_loopnest before, after;
        lambda_trans_matrix trans;
*************** linear_transform_loops (void)
*** 270,276 ****
                  ...
                 }
             } */
!       if (!loop_nest || !loop_nest->inner || !single_exit (loop_nest))
  	continue;
        VEC_truncate (tree, oldivs, 0);
        VEC_truncate (tree, invariants, 0);
--- 270,276 ----
                  ...
                 }
             } */
!       if (!loop_nest->inner || !single_exit (loop_nest))
  	continue;
        VEC_truncate (tree, oldivs, 0);
        VEC_truncate (tree, invariants, 0);
Index: doc/loop.texi
===================================================================
*** doc/loop.texi	(revision 119711)
--- doc/loop.texi	(working copy)
*************** The root of this tree is a fake loop tha
*** 63,82 ****
  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
  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.
  
  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.
  
  The loops are analyzed through @code{loop_optimizer_init} function.  The
  argument of this function is a set of flags represented in an integer
--- 63,87 ----
  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{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{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.  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: tree-ssa-loop-im.c
===================================================================
*** tree-ssa-loop-im.c	(revision 119711)
--- tree-ssa-loop-im.c	(working copy)
*************** static void
*** 1377,1410 ****
  determine_lsm (void)
  {
    struct loop *loop;
! 
!   if (!current_loops->tree_root->inner)
!     return;
  
    /* Pass the loops from the outermost and perform the store motion as
       suitable.  */
  
!   loop = current_loops->tree_root->inner;
!   while (1)
      {
        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;
      }
  }
  
  /* Fills ALWAYS_EXECUTED_IN information for basic blocks of LOOP, i.e.
--- 1377,1393 ----
  determine_lsm (void)
  {
    struct loop *loop;
!   loop_iterator li;
  
    /* Pass the loops from the outermost and perform the store motion as
       suitable.  */
  
!   FOR_EACH_LOOP (li, loop, 0)
      {
        determine_lsm_loop (loop);
      }
+ 
+   bsi_commit_edge_inserts ();
  }
  
  /* Fills ALWAYS_EXECUTED_IN information for basic blocks of LOOP, i.e.
Index: tree-ssa-loop-niter.c
===================================================================
*** tree-ssa-loop-niter.c	(revision 119711)
--- tree-ssa-loop-niter.c	(working copy)
*************** estimate_numbers_of_iterations_loop (str
*** 2024,2037 ****
  void
  estimate_numbers_of_iterations (void)
  {
!   unsigned i;
    struct loop *loop;
  
!   for (i = 1; i < current_loops->num; i++)
      {
!       loop = current_loops->parray[i];
!       if (loop)
! 	estimate_numbers_of_iterations_loop (loop);
      }
  }
  
--- 2024,2035 ----
  void
  estimate_numbers_of_iterations (void)
  {
!   loop_iterator li;
    struct loop *loop;
  
!   FOR_EACH_LOOP (li, loop, 0)
      {
!       estimate_numbers_of_iterations_loop (loop);
      }
  }
  
*************** free_numbers_of_iterations_estimates_loo
*** 2246,2259 ****
  void
  free_numbers_of_iterations_estimates (void)
  {
!   unsigned i;
    struct loop *loop;
  
!   for (i = 1; i < current_loops->num; i++)
      {
!       loop = current_loops->parray[i];
!       if (loop)
! 	free_numbers_of_iterations_estimates_loop (loop);
      }
  }
  
--- 2244,2255 ----
  void
  free_numbers_of_iterations_estimates (void)
  {
!   loop_iterator li;
    struct loop *loop;
  
!   FOR_EACH_LOOP (li, loop, 0)
      {
!       free_numbers_of_iterations_estimates_loop (loop);
      }
  }
  
Index: tree-ssa-loop-unswitch.c
===================================================================
*** tree-ssa-loop-unswitch.c	(revision 119711)
--- tree-ssa-loop-unswitch.c	(working copy)
*************** static tree tree_may_unswitch_on (basic_
*** 82,104 ****
  unsigned int
  tree_ssa_unswitch_loops (void)
  {
!   int i, num;
    struct loop *loop;
    bool changed = false;
  
    /* Go through inner loops (only original ones).  */
!   num = current_loops->num;
! 
!   for (i = 1; i < num; i++)
      {
-       /* Removed loop?  */
-       loop = current_loops->parray[i];
-       if (!loop)
- 	continue;
- 
-       if (loop->inner)
- 	continue;
- 
        changed |= tree_unswitch_single_loop (loop, 0);
      }
  
--- 82,94 ----
  unsigned int
  tree_ssa_unswitch_loops (void)
  {
!   loop_iterator li;
    struct loop *loop;
    bool changed = false;
  
    /* Go through inner loops (only original ones).  */
!   FOR_EACH_LOOP (li, loop, LI_ONLY_OLD | LI_ONLY_INNERMOST)
      {
        changed |= tree_unswitch_single_loop (loop, 0);
      }
  
Index: cfgloopmanip.c
===================================================================
*** cfgloopmanip.c	(revision 119711)
--- cfgloopmanip.c	(working copy)
*************** unloop (struct loop *loop, bool *irred_i
*** 552,560 ****
      }
  
    /* Remove the loop and free its data.  */
!   flow_loop_tree_node_remove (loop);
!   current_loops->parray[loop->num] = NULL;
!   flow_loop_free (loop);
  
    remove_edge (single_succ_edge (latch));
  
--- 552,558 ----
      }
  
    /* Remove the loop and free its data.  */
!   delete_loop (loop);
  
    remove_edge (single_succ_edge (latch));
  
*************** fix_loop_placements (struct loop *loop, 
*** 634,644 ****
  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++;
  }
  
  /* Copies copy of LOOP as subloop of TARGET loop, placing newly
--- 632,639 ----
  static void
  place_new_loop (struct loop *loop)
  {
!   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
*************** create_preheader (struct loop *loop, int
*** 1195,1203 ****
  void
  create_preheaders (int flags)
  {
!   unsigned i;
!   for (i = 1; i < current_loops->num; i++)
!     create_preheader (current_loops->parray[i], flags);
    current_loops->state |= LOOPS_HAVE_PREHEADERS;
  }
  
--- 1190,1200 ----
  void
  create_preheaders (int flags)
  {
!   loop_iterator li;
!   struct loop *loop;
! 
!   FOR_EACH_LOOP (li, loop, 0)
!     create_preheader (loop, flags);
    current_loops->state |= LOOPS_HAVE_PREHEADERS;
  }
  
*************** create_preheaders (int flags)
*** 1206,1218 ****
  void
  force_single_succ_latches (void)
  {
!   unsigned i;
    struct loop *loop;
    edge e;
  
!   for (i = 1; i < current_loops->num; i++)
      {
-       loop = current_loops->parray[i];
        if (loop->latch != loop->header && single_succ_p (loop->latch))
  	continue;
  
--- 1203,1214 ----
  void
  force_single_succ_latches (void)
  {
!   loop_iterator li;
    struct loop *loop;
    edge e;
  
!   FOR_EACH_LOOP (li, loop, 0)
      {
        if (loop->latch != loop->header && single_succ_p (loop->latch))
  	continue;
  
*************** fix_loop_structure (bitmap changed_bbs)
*** 1392,1398 ****
  {
    basic_block bb;
    struct loop *loop, *ploop;
!   unsigned i;
  
    /* Remove the old bb -> loop mapping.  */
    FOR_EACH_BB (bb)
--- 1388,1394 ----
  {
    basic_block bb;
    struct loop *loop, *ploop;
!   loop_iterator li;
  
    /* Remove the old bb -> loop mapping.  */
    FOR_EACH_BB (bb)
*************** fix_loop_structure (bitmap changed_bbs)
*** 1403,1414 ****
  
    /* Remove the dead loops from structures.  */
    current_loops->tree_root->num_nodes = n_basic_blocks;
!   for (i = 1; i < current_loops->num; i++)
      {
-       loop = current_loops->parray[i];
-       if (!loop)
- 	continue;
- 
        loop->num_nodes = 0;
        if (loop->header)
  	continue;
--- 1399,1406 ----
  
    /* Remove the dead loops from structures.  */
    current_loops->tree_root->num_nodes = n_basic_blocks;
!   FOR_EACH_LOOP (li, loop, 0)
      {
        loop->num_nodes = 0;
        if (loop->header)
  	continue;
*************** fix_loop_structure (bitmap changed_bbs)
*** 1421,1458 ****
  	}
  
        /* Remove the loop and free its data.  */
!       flow_loop_tree_node_remove (loop);
!       current_loops->parray[loop->num] = NULL;
!       flow_loop_free (loop);
      }
  
    /* Rescan the bodies of loops, starting from the outermost.  */
!   loop = current_loops->tree_root;
!   while (1)
      {
-       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++)
      {
-       loop = current_loops->parray[i];
-       if (!loop)
- 	continue;
- 
        bb = loop_preheader_edge (loop)->src;
        if (bb->loop_father != loop->outer)
  	{
--- 1413,1430 ----
  	}
  
        /* Remove the loop and free its data.  */
!       delete_loop (loop);
      }
  
    /* Rescan the bodies of loops, starting from the outermost.  */
!   FOR_EACH_LOOP (li, loop, 0)
      {
        loop->num_nodes = flow_loop_nodes_find (loop->header, loop);
      }
  
    /* Now fix the loop nesting.  */
!   FOR_EACH_LOOP (li, loop, 0)
      {
        bb = loop_preheader_edge (loop)->src;
        if (bb->loop_father != loop->outer)
  	{
Index: tree-ssa-loop-ch.c
===================================================================
*** tree-ssa-loop-ch.c	(revision 119711)
--- tree-ssa-loop-ch.c	(working copy)
*************** do_while_loop_p (struct loop *loop)
*** 123,129 ****
  static unsigned int
  copy_loop_headers (void)
  {
!   unsigned i;
    struct loop *loop;
    basic_block header;
    edge exit, entry;
--- 123,129 ----
  static unsigned int
  copy_loop_headers (void)
  {
!   loop_iterator li;
    struct loop *loop;
    basic_block header;
    edge exit, entry;
*************** copy_loop_headers (void)
*** 144,157 ****
    copied_bbs = XNEWVEC (basic_block, n_basic_blocks);
    bbs_size = n_basic_blocks;
  
!   for (i = 1; i < current_loops->num; i++)
      {
        /* 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
--- 144,154 ----
    copied_bbs = XNEWVEC (basic_block, n_basic_blocks);
    bbs_size = n_basic_blocks;
  
!   FOR_EACH_LOOP (li, loop, 0)
      {
        /* Copy at most 20 insns.  */
        int limit = 20;
  
        header = loop->header;
  
        /* If the loop is already a do-while style one (either because it was
Index: tree.h
===================================================================
*** tree.h	(revision 119711)
--- tree.h	(working copy)
*************** struct tree_constructor GTY(())
*** 1587,1592 ****
--- 1587,1598 ----
  #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)
Index: tree-scalar-evolution.c
===================================================================
*** tree-scalar-evolution.c	(revision 119711)
--- tree-scalar-evolution.c	(working copy)
*************** chrec_contains_symbols_defined_in_loop (
*** 375,381 ****
      {
        tree def = SSA_NAME_DEF_STMT (chrec);
        struct loop *def_loop = loop_containing_stmt (def);
!       struct loop *loop = current_loops->parray[loop_nb];
  
        if (def_loop == NULL)
  	return false;
--- 375,381 ----
      {
        tree def = SSA_NAME_DEF_STMT (chrec);
        struct loop *def_loop = loop_containing_stmt (def);
!       struct loop *loop = get_loop (loop_nb);
  
        if (def_loop == NULL)
  	return false;
*************** compute_overall_effect_of_inner_loop (st
*** 467,474 ****
      {
        if (CHREC_VARIABLE (evolution_fn) >= (unsigned) loop->num)
  	{
! 	  struct loop *inner_loop = 
! 	    current_loops->parray[CHREC_VARIABLE (evolution_fn)];
  	  tree nb_iter = number_of_iterations_in_loop (inner_loop);
  
  	  if (nb_iter == chrec_dont_know)
--- 467,473 ----
      {
        if (CHREC_VARIABLE (evolution_fn) >= (unsigned) loop->num)
  	{
! 	  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)
*************** chrec_is_positive (tree chrec, bool *val
*** 534,542 ****
        if (!evolution_function_is_affine_p (chrec))
  	return false;
  
!       nb_iter = number_of_iterations_in_loop
! 	(current_loops->parray[CHREC_VARIABLE (chrec)]);
! 
        if (chrec_contains_undetermined (nb_iter))
  	return false;
  
--- 533,539 ----
        if (!evolution_function_is_affine_p (chrec))
  	return false;
  
!       nb_iter = number_of_iterations_in_loop (get_chrec_loop (chrec));
        if (chrec_contains_undetermined (nb_iter))
  	return false;
  
*************** number_of_iterations_for_all_loops (VEC(
*** 2530,2536 ****
        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, "-----------------------------------------\n");
        fprintf (dump_file, ")\n\n");
        
--- 2527,2533 ----
        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", number_of_loops ());
        fprintf (dump_file, "-----------------------------------------\n");
        fprintf (dump_file, ")\n\n");
        
*************** initialize_scalar_evolutions_analyzer (v
*** 2747,2753 ****
  void
  scev_initialize (void)
  {
!   unsigned i;
  
    scalar_evolution_info = htab_create (100, hash_scev_info,
  				       eq_scev_info, del_scev_info);
--- 2744,2751 ----
  void
  scev_initialize (void)
  {
!   loop_iterator li;
!   struct loop *loop;
  
    scalar_evolution_info = htab_create (100, hash_scev_info,
  				       eq_scev_info, del_scev_info);
*************** scev_initialize (void)
*** 2755,2763 ****
    
    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;
  }
  
  /* Cleans up the information cached by the scalar evolutions analysis.  */
--- 2753,2762 ----
    
    initialize_scalar_evolutions_analyzer ();
  
!   FOR_EACH_LOOP (li, loop, 0)
!     {
!       loop->nb_iterations = NULL_TREE;
!     }
  }
  
  /* Cleans up the information cached by the scalar evolutions analysis.  */
*************** scev_initialize (void)
*** 2765,2782 ****
  void
  scev_reset (void)
  {
!   unsigned i;
    struct loop *loop;
  
    if (!scalar_evolution_info || !current_loops)
      return;
  
    htab_empty (scalar_evolution_info);
!   for (i = 1; i < current_loops->num; i++)
      {
!       loop = current_loops->parray[i];
!       if (loop)
! 	loop->nb_iterations = NULL_TREE;
      }
  }
  
--- 2764,2779 ----
  void
  scev_reset (void)
  {
!   loop_iterator li;
    struct loop *loop;
  
    if (!scalar_evolution_info || !current_loops)
      return;
  
    htab_empty (scalar_evolution_info);
!   FOR_EACH_LOOP (li, loop, 0)
      {
!       loop->nb_iterations = NULL_TREE;
      }
  }
  
*************** scev_const_prop (void)
*** 2890,2895 ****
--- 2887,2893 ----
    struct loop *loop, *ex_loop;
    bitmap ssa_names_to_remove = NULL;
    unsigned i;
+   loop_iterator li;
  
    if (!current_loops)
      return 0;
*************** scev_const_prop (void)
*** 2931,2937 ****
    if (ssa_names_to_remove)
      {
        bitmap_iterator bi;
-       unsigned i;
  
        EXECUTE_IF_SET_IN_BITMAP (ssa_names_to_remove, 0, i, bi)
  	{
--- 2929,2934 ----
*************** scev_const_prop (void)
*** 2947,2962 ****
      }
  
    /* Now the regular final value replacement.  */
!   for (i = current_loops->num - 1; i > 0; i--)
      {
        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);
--- 2944,2955 ----
      }
  
    /* Now the regular final value replacement.  */
!   FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
      {
        edge exit;
        tree def, rslt, ass, niter;
        block_stmt_iterator bsi;
  
        /* If we do not know exact number of iterations of the loop, we cannot
  	 replace the final value.  */
        exit = single_exit (loop);
Index: tree-scalar-evolution.h
===================================================================
*** tree-scalar-evolution.h	(revision 119711)
--- tree-scalar-evolution.h	(working copy)
*************** unsigned int scev_const_prop (void);
*** 36,39 ****
--- 36,47 ----
  
  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: cfgloopanal.c
===================================================================
*** cfgloopanal.c	(revision 119711)
--- cfgloopanal.c	(working copy)
*************** mark_irreducible_loops (void)
*** 273,283 ****
    edge_iterator ei;
    int i, src, dest;
    struct graph *g;
!   int num = current_loops ? current_loops->num : 1;
    int *queue1 = XNEWVEC (int, last_basic_block + num);
    int *queue2 = XNEWVEC (int, last_basic_block + num);
    int nq, depth;
!   struct loop *cloop;
  
    /* Reset the flags.  */
    FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
--- 273,284 ----
    edge_iterator ei;
    int i, src, dest;
    struct graph *g;
!   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, *loop;
!   loop_iterator li;
  
    /* Reset the flags.  */
    FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
*************** mark_irreducible_loops (void)
*** 343,351 ****
      {
        queue1[nq++] = BB_REPR (act);
      }
!   for (i = 1; i < num; i++)
!     if (current_loops->parray[i])
!       queue1[nq++] = LOOP_REPR (current_loops->parray[i]);
    dfs (g, queue1, nq, queue2, false);
    for (i = 0; i < nq; i++)
      queue1[i] = queue2[nq - i - 1];
--- 344,357 ----
      {
        queue1[nq++] = BB_REPR (act);
      }
! 
!   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: tree-chrec.c
===================================================================
*** tree-chrec.c	(revision 119711)
--- tree-chrec.c	(working copy)
*************** evolution_function_is_invariant_rec_p (t
*** 939,946 ****
      return true;
  
    if (TREE_CODE (chrec) == SSA_NAME 
!       && expr_invariant_in_loop_p (current_loops->parray[loopnum],
! 				   chrec))
      return true;
  
    if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
--- 939,945 ----
      return true;
  
    if (TREE_CODE (chrec) == SSA_NAME 
!       && expr_invariant_in_loop_p (get_loop (loopnum), chrec))
      return true;
  
    if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
*************** chrec_convert_1 (tree type, tree chrec, 
*** 1280,1286 ****
    if (!evolution_function_is_affine_p (chrec))
      goto keep_cast;
  
!   loop = current_loops->parray[CHREC_VARIABLE (chrec)];
    base = CHREC_LEFT (chrec);
    step = CHREC_RIGHT (chrec);
  
--- 1279,1285 ----
    if (!evolution_function_is_affine_p (chrec))
      goto keep_cast;
  
!   loop = get_chrec_loop (chrec);
    base = CHREC_LEFT (chrec);
    step = CHREC_RIGHT (chrec);
  
Index: tree-chrec.h
===================================================================
*** tree-chrec.h	(revision 119711)
--- tree-chrec.h	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 22,35 ****
  #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))
- 
- 
- 
  /* 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.  */
--- 22,27 ----
Index: tree-ssa-loop-ivopts.c
===================================================================
*** tree-ssa-loop-ivopts.c	(revision 119711)
--- tree-ssa-loop-ivopts.c	(working copy)
*************** tree_ssa_iv_optimize (void)
*** 5889,5918 ****
  {
    struct loop *loop;
    struct ivopts_data data;
  
    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)
      {
        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);
--- 5889,5905 ----
  {
    struct loop *loop;
    struct ivopts_data data;
+   loop_iterator li;
  
    tree_ssa_iv_optimize_init (&data);
  
    /* Optimize the loops starting with the innermost ones.  */
!   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);
      }
  
    tree_ssa_iv_optimize_finalize (&data);
Index: modulo-sched.c
===================================================================
*** modulo-sched.c	(revision 119711)
--- modulo-sched.c	(working copy)
*************** sms_schedule (void)
*** 878,889 ****
    ddg_ptr *g_arr, g;
    int * node_order;
    int maxii;
!   unsigned i,num_loops;
    partial_schedule_ptr ps;
    struct df *df;
    basic_block bb = NULL;
!   /* vars to the versioning only if needed*/
!   struct loop * nloop;
    basic_block condition_bb = NULL;
    edge latch_edge;
    gcov_type trip_count = 0;
--- 878,888 ----
    ddg_ptr *g_arr, g;
    int * node_order;
    int maxii;
!   loop_iterator li;
    partial_schedule_ptr ps;
    struct df *df;
    basic_block bb = NULL;
!   struct loop *loop, *nloop;
    basic_block condition_bb = NULL;
    edge latch_edge;
    gcov_type trip_count = 0;
*************** sms_schedule (void)
*** 921,936 ****
  
    /* 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);
! 
  
    /* 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++)
      {
        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))
--- 920,933 ----
  
    /* 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, number_of_loops ());
  
    /* Build DDGs for all the relevant loops and hold them in G_ARR
       indexed by the loop index.  */
!   FOR_EACH_LOOP (li, loop, 0)
      {
        rtx head, tail;
        rtx count_reg;
  
        /* For debugging.  */
        if ((passes++ > MAX_SMS_LOOP_NUMBER) && (MAX_SMS_LOOP_NUMBER != -1))
*************** sms_schedule (void)
*** 1019,1025 ****
  	  continue;
          }
  
!       g_arr[i] = g;
      }
  
    /* Release Data Flow analysis data structures.  */
--- 1016,1022 ----
  	  continue;
          }
  
!       g_arr[loop->num] = g;
      }
  
    /* Release Data Flow analysis data structures.  */
*************** sms_schedule (void)
*** 1027,1044 ****
    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++)
      {
        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]))
          continue;
  
        if (dump_file)
--- 1024,1038 ----
    df = NULL;
  
    /* We don't want to perform SMS on new loops - created by versioning.  */
!   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;
  
!       if (! (g = g_arr[loop->num]))
          continue;
  
        if (dump_file)
Index: loop-init.c
===================================================================
*** loop-init.c	(revision 119711)
--- loop-init.c	(working copy)
*************** loop_optimizer_init (unsigned flags)
*** 68,76 ****
    flow_loops_find (loops);
    current_loops = loops;
  
!   if (current_loops->num <= 1)
      {
!       /* No loops.  */
        loop_optimizer_finalize ();
        return;
      }
--- 68,77 ----
    flow_loops_find (loops);
    current_loops = loops;
  
!   if (number_of_loops () <= 1)
      {
!       /* 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;
      }
*************** loop_optimizer_init (unsigned flags)
*** 104,118 ****
  void
  loop_optimizer_finalize (void)
  {
!   unsigned i;
    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]);
  
    /* Clean up.  */
    flow_loops_free (current_loops);
--- 105,121 ----
  void
  loop_optimizer_finalize (void)
  {
!   loop_iterator li;
!   struct loop *loop;
    basic_block bb;
  
    if (!current_loops)
      return;
  
!   FOR_EACH_LOOP (li, loop, 0)
!     {
!       free_simple_loop_desc (loop);
!     }
  
    /* Clean up.  */
    flow_loops_free (current_loops);
Index: tree-ssa-loop-ivcanon.c
===================================================================
*** tree-ssa-loop-ivcanon.c	(revision 119711)
--- tree-ssa-loop-ivcanon.c	(working copy)
*************** canonicalize_loop_induction_variables (s
*** 332,349 ****
  unsigned int
  canonicalize_induction_variables (void)
  {
!   unsigned i;
    struct loop *loop;
    bool changed = false;
    
!   for (i = 1; i < current_loops->num; i++)
      {
!       loop = current_loops->parray[i];
! 
!       if (loop)
! 	changed |= canonicalize_loop_induction_variables (loop,
! 							  true, UL_SINGLE_ITER,
! 							  true);
      }
  
    /* Clean up the information about numbers of iterations, since brute force
--- 332,346 ----
  unsigned int
  canonicalize_induction_variables (void)
  {
!   loop_iterator li;
    struct loop *loop;
    bool changed = false;
    
!   FOR_EACH_LOOP (li, loop, 0)
      {
!       changed |= canonicalize_loop_induction_variables (loop,
! 							true, UL_SINGLE_ITER,
! 							true);
      }
  
    /* Clean up the information about numbers of iterations, since brute force
*************** canonicalize_induction_variables (void)
*** 362,379 ****
  unsigned int
  tree_unroll_loops_completely (bool may_increase_size)
  {
!   unsigned i;
    struct loop *loop;
    bool changed = false;
    enum unroll_level ul;
  
!   for (i = 1; i < current_loops->num; i++)
      {
-       loop = current_loops->parray[i];
- 
-       if (!loop)
- 	continue;
- 
        if (may_increase_size && maybe_hot_bb_p (loop->header))
  	ul = UL_ALL;
        else
--- 359,371 ----
  unsigned int
  tree_unroll_loops_completely (bool may_increase_size)
  {
!   loop_iterator li;
    struct loop *loop;
    bool changed = false;
    enum unroll_level ul;
  
!   FOR_EACH_LOOP (li, loop, 0)
      {
        if (may_increase_size && maybe_hot_bb_p (loop->header))
  	ul = UL_ALL;
        else
Index: predict.c
===================================================================
*** predict.c	(revision 119711)
--- predict.c	(working copy)
*************** combine_predictions_for_bb (basic_block 
*** 630,646 ****
  static void
  predict_loops (void)
  {
!   unsigned i;
  
    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++)
      {
        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;
--- 630,646 ----
  static void
  predict_loops (void)
  {
!   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_EACH_LOOP (li, loop, 0)
      {
        basic_block bb, *bbs;
        unsigned j, n_exits;
        VEC (edge, heap) *exits;
        struct tree_niter_desc niter_desc;
        edge ex;
Index: tree-vectorizer.c
===================================================================
*** tree-vectorizer.c	(revision 119711)
--- tree-vectorizer.c	(working copy)
*************** FILE *vect_dump;
*** 174,182 ****
     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;
  
--- 174,179 ----
*************** vectorize_loops (void)
*** 2157,2162 ****
--- 2154,2162 ----
  {
    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 ();
*************** vectorize_loops (void)
*** 2170,2183 ****
    /* 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++)
      {
        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);
--- 2170,2179 ----
    /* 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 = number_of_loops ();
!   FOR_EACH_LOOP (li, loop, LI_ONLY_OLD)
      {
        loop_vec_info loop_vinfo;
  
        vect_loop_location = find_loop_location (loop);
        loop_vinfo = vect_analyze_loop (loop);
*************** vectorize_loops (void)
*** 2201,2209 ****
  
    for (i = 1; i < vect_loops_num; i++)
      {
-       struct loop *loop = current_loops->parray[i];
        loop_vec_info loop_vinfo;
  
        if (!loop)
  	continue;
        loop_vinfo = loop->aux;
--- 2197,2205 ----
  
    for (i = 1; i < vect_loops_num; i++)
      {
        loop_vec_info loop_vinfo;
  
+       loop = get_loop (i);
        if (!loop)
  	continue;
        loop_vinfo = loop->aux;
Index: tree-vectorizer.h
===================================================================
*** tree-vectorizer.h	(revision 119711)
--- tree-vectorizer.h	(working copy)
*************** known_alignment_for_access_p (struct dat
*** 327,335 ****
  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;
  
--- 327,332 ----
Index: tree-if-conv.c
===================================================================
*** tree-if-conv.c	(revision 119711)
--- tree-if-conv.c	(working copy)
*************** bb_with_exit_edge_p (struct loop *loop, 
*** 1092,1110 ****
  static unsigned int
  main_tree_if_conversion (void)
  {
!   unsigned i, loop_num;
    struct loop *loop;
  
    if (!current_loops)
      return 0;
  
!   loop_num = current_loops->num;
!   for (i = 0; i < loop_num; i++)
      {
-       loop =  current_loops->parray[i];
-       if (!loop)
-       continue;
- 
        tree_if_conversion (loop, true);
      }
    return 0;
--- 1092,1105 ----
  static unsigned int
  main_tree_if_conversion (void)
  {
!   loop_iterator li;
    struct loop *loop;
  
    if (!current_loops)
      return 0;
  
!   FOR_EACH_LOOP (li, loop, 0)
      {
        tree_if_conversion (loop, true);
      }
    return 0;
Index: tree-data-ref.c
===================================================================
*** tree-data-ref.c	(revision 119711)
--- tree-data-ref.c	(working copy)
*************** analyze_ziv_subscript (tree chrec_a, 
*** 2304,2310 ****
  static tree
  get_number_of_iters_for_loop (int loopnum)
  {
!   struct loop *loop = current_loops->parray[loopnum];
    tree numiter = number_of_iterations_in_loop (loop);
  
    if (TREE_CODE (numiter) == INTEGER_CST)
--- 2304,2310 ----
  static tree
  get_number_of_iters_for_loop (int loopnum)
  {
!   struct loop *loop = get_loop (loopnum);
    tree numiter = number_of_iterations_in_loop (loop);
  
    if (TREE_CODE (numiter) == INTEGER_CST)
*************** find_data_references_in_loop (struct loo
*** 4109,4115 ****
    block_stmt_iterator bsi;
  
    bbs = get_loop_body (loop);
-   loop->parallel_p = true;
  
    for (i = 0; i < loop->num_nodes; i++)
      {
--- 4109,4114 ----
*************** find_data_references_in_loop (struct loo
*** 4137,4152 ****
  	      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);
--- 4136,4146 ----
Index: loop-unroll.c
===================================================================
*** loop-unroll.c	(revision 119711)
--- loop-unroll.c	(working copy)
*************** static rtx get_expansion (struct var_to_
*** 144,151 ****
  void
  unroll_and_peel_loops (int flags)
  {
!   struct loop *loop, *next;
    bool check;
  
    /* First perform complete loop peeling (it is almost surely a win,
       and affects parameters for further decision a lot).  */
--- 144,152 ----
  void
  unroll_and_peel_loops (int flags)
  {
!   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).  */
*************** unroll_and_peel_loops (int flags)
*** 154,175 ****
    /* 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)
      {
-       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)
--- 155,163 ----
    /* Now decide rest of unrolling and peeling.  */
    decide_unrolling_and_peeling (flags);
  
    /* Scan the loops, inner ones first.  */
!   FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
      {
        check = true;
        /* And perform the appropriate transformations.  */
        switch (loop->lpt_decision.decision)
*************** unroll_and_peel_loops (int flags)
*** 202,208 ****
  	  verify_loop_structure ();
  #endif
  	}
-       loop = next;
      }
  
    iv_analysis_done ();
--- 190,195 ----
*************** static void
*** 234,248 ****
  peel_loops_completely (int flags)
  {
    struct loop *loop;
!   unsigned i;
  
    /* Scan the loops, the inner ones first.  */
!   for (i = current_loops->num - 1; i > 0; i--)
      {
-       loop = current_loops->parray[i];
-       if (!loop)
- 	continue;
- 
        loop->lpt_decision.decision = LPT_NONE;
  
        if (dump_file)
--- 221,231 ----
  peel_loops_completely (int flags)
  {
    struct loop *loop;
!   loop_iterator li;
  
    /* Scan the loops, the inner ones first.  */
!   FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
      {
        loop->lpt_decision.decision = LPT_NONE;
  
        if (dump_file)
*************** peel_loops_completely (int flags)
*** 271,293 ****
  static void
  decide_unrolling_and_peeling (int flags)
  {
!   struct loop *loop = current_loops->tree_root, *next;
! 
!   while (loop->inner)
!     loop = loop->inner;
  
    /* Scan the loops, inner ones first.  */
!   while (loop != current_loops->tree_root)
      {
-       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)
--- 254,265 ----
  static void
  decide_unrolling_and_peeling (int flags)
  {
!   struct loop *loop;
!   loop_iterator li;
  
    /* Scan the loops, inner ones first.  */
!   FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
      {
        loop->lpt_decision.decision = LPT_NONE;
  
        if (dump_file)
*************** decide_unrolling_and_peeling (int flags)
*** 298,304 ****
  	{
  	  if (dump_file)
  	    fprintf (dump_file, ";; Not considering loop, cold area\n");
- 	  loop = next;
  	  continue;
  	}
  
--- 270,275 ----
*************** decide_unrolling_and_peeling (int flags)
*** 308,314 ****
  	  if (dump_file)
  	    fprintf (dump_file,
  		     ";; Not considering loop, cannot duplicate\n");
- 	  loop = next;
  	  continue;
  	}
  
--- 279,284 ----
*************** decide_unrolling_and_peeling (int flags)
*** 317,323 ****
  	{
  	  if (dump_file)
  	    fprintf (dump_file, ";; Not considering loop, is not innermost\n");
- 	  loop = next;
  	  continue;
  	}
  
--- 287,292 ----
*************** decide_unrolling_and_peeling (int flags)
*** 334,341 ****
  	decide_unroll_stupid (loop, flags);
        if (loop->lpt_decision.decision == LPT_NONE)
  	decide_peel_simple (loop, flags);
- 
-       loop = next;
      }
  }
  
--- 303,308 ----
Index: tree-data-ref.h
===================================================================
*** tree-data-ref.h	(revision 119711)
--- tree-data-ref.h	(working copy)
*************** DEF_VEC_ALLOC_P (subscript_p, heap);
*** 224,233 ****
  #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.  */
  
--- 224,229 ----
Index: loop-doloop.c
===================================================================
*** loop-doloop.c	(revision 119711)
--- loop-doloop.c	(working copy)
*************** doloop_optimize (struct loop *loop)
*** 621,635 ****
  void
  doloop_optimize_loops (void)
  {
!   unsigned i;
    struct loop *loop;
  
!   for (i = 1; i < current_loops->num; i++)
      {
-       loop = current_loops->parray[i];
-       if (!loop)
- 	continue;
- 
        doloop_optimize (loop);
      }
  
--- 621,631 ----
  void
  doloop_optimize_loops (void)
  {
!   loop_iterator li;
    struct loop *loop;
  
!   FOR_EACH_LOOP (li, loop, 0)
      {
        doloop_optimize (loop);
      }
  
Index: loop-invariant.c
===================================================================
*** loop-invariant.c	(revision 119711)
--- loop-invariant.c	(working copy)
*************** void
*** 1318,1350 ****
  move_loop_invariants (void)
  {
    struct loop *loop;
!   unsigned i;
  
    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)
      {
        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]);
  
    df_finish (df);
    df = NULL;
--- 1318,1338 ----
  move_loop_invariants (void)
  {
    struct loop *loop;
!   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.  */
!   FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
      {
        move_single_loop_invariants (loop);
      }
  
!   FOR_EACH_LOOP (li, loop, 0)
!     {
!       free_loop_data (loop);
!     }
  
    df_finish (df);
    df = NULL;
Index: tree-ssa-loop-prefetch.c
===================================================================
*** tree-ssa-loop-prefetch.c	(revision 119711)
--- tree-ssa-loop-prefetch.c	(working copy)
*************** fail:
*** 998,1004 ****
  unsigned int
  tree_ssa_prefetch_arrays (void)
  {
!   unsigned i;
    struct loop *loop;
    bool unrolled = false;
    int todo_flags = 0;
--- 998,1004 ----
  unsigned int
  tree_ssa_prefetch_arrays (void)
  {
!   loop_iterator li;
    struct loop *loop;
    bool unrolled = false;
    int todo_flags = 0;
*************** tree_ssa_prefetch_arrays (void)
*** 1043,1054 ****
       here.  */
    gcc_assert ((PREFETCH_BLOCK & (PREFETCH_BLOCK - 1)) == 0);
  
!   for (i = current_loops->num - 1; i > 0; i--)
      {
-       loop = current_loops->parray[i];
-       if (!loop)
- 	continue;
- 
        if (dump_file && (dump_flags & TDF_DETAILS))
  	fprintf (dump_file, "Processing loop %d:\n", loop->num);
  
--- 1043,1050 ----
       here.  */
    gcc_assert ((PREFETCH_BLOCK & (PREFETCH_BLOCK - 1)) == 0);
  
!   FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
      {
        if (dump_file && (dump_flags & TDF_DETAILS))
  	fprintf (dump_file, "Processing loop %d:\n", loop->num);
  
Index: cfgloop.c
===================================================================
*** cfgloop.c	(revision 119711)
--- cfgloop.c	(working copy)
*************** flow_loop_dump (const struct loop *loop,
*** 128,147 ****
  void
  flow_loops_dump (FILE *file, void (*loop_dump_aux) (const struct loop *, FILE *, int), int verbose)
  {
!   unsigned i;
  
    if (!current_loops || ! file)
      return;
  
!   fprintf (file, ";; %d loops found\n", current_loops->num);
  
!   for (i = 0; i < current_loops->num; i++)
      {
-       struct loop *loop = current_loops->parray[i];
- 
-       if (!loop)
- 	continue;
- 
        flow_loop_dump (loop, file, loop_dump_aux, verbose);
      }
  
--- 128,143 ----
  void
  flow_loops_dump (FILE *file, void (*loop_dump_aux) (const struct loop *, FILE *, int), int verbose)
  {
!   loop_iterator li;
!   struct loop *loop;
  
    if (!current_loops || ! file)
      return;
  
!   fprintf (file, ";; %d loops found\n", number_of_loops ());
  
!   FOR_EACH_LOOP (li, loop, LI_INCLUDE_ROOT)
      {
        flow_loop_dump (loop, file, loop_dump_aux, verbose);
      }
  
*************** flow_loop_free (struct loop *loop)
*** 163,187 ****
  void
  flow_loops_free (struct loops *loops)
  {
!   if (loops->parray)
      {
        unsigned i;
! 
!       gcc_assert (loops->num);
  
        /* Free the loop descriptors.  */
!       for (i = 0; i < loops->num; i++)
  	{
- 	  struct loop *loop = loops->parray[i];
- 
  	  if (!loop)
  	    continue;
  
  	  flow_loop_free (loop);
  	}
  
!       free (loops->parray);
!       loops->parray = NULL;
      }
  }
  
--- 159,180 ----
  void
  flow_loops_free (struct loops *loops)
  {
!   if (loops->larray)
      {
        unsigned i;
!       loop_p loop;
  
        /* Free the loop descriptors.  */
!       for (i = 0; VEC_iterate (loop_p, loops->larray, i, loop); i++)
  	{
  	  if (!loop)
  	    continue;
  
  	  flow_loop_free (loop);
  	}
  
!       VEC_free (loop_p, heap, loops->larray);
!       loops->larray = NULL;
      }
  }
  
*************** mark_single_exit_loops (void)
*** 242,254 ****
    basic_block bb;
    edge e;
    struct loop *loop;
!   unsigned i;
  
!   for (i = 1; i < current_loops->num; i++)
      {
!       loop = current_loops->parray[i];
!       if (loop)
! 	set_single_exit (loop, NULL);
      }
  
    FOR_EACH_BB (bb)
--- 235,245 ----
    basic_block bb;
    edge e;
    struct loop *loop;
!   loop_iterator li;
  
!   FOR_EACH_LOOP (li, loop, 0)
      {
!       set_single_exit (loop, NULL);
      }
  
    FOR_EACH_BB (bb)
*************** mark_single_exit_loops (void)
*** 278,289 ****
  	}
      }
  
!   for (i = 1; i < current_loops->num; i++)
      {
-       loop = current_loops->parray[i];
-       if (!loop)
- 	continue;
- 
        if (single_exit (loop) == single_succ_edge (ENTRY_BLOCK_PTR))
  	set_single_exit (loop, NULL);
      }
--- 269,276 ----
  	}
      }
  
!   FOR_EACH_LOOP (li, loop, 0)
      {
        if (single_exit (loop) == single_succ_edge (ENTRY_BLOCK_PTR))
  	set_single_exit (loop, NULL);
      }
*************** canonicalize_loop_headers (void)
*** 499,518 ****
  #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.  */
--- 486,491 ----
*************** flow_loops_find (struct loops *loops)
*** 528,533 ****
--- 501,507 ----
    int *rc_order;
    basic_block header;
    basic_block bb;
+   struct loop *root;
  
    memset (loops, 0, sizeof *loops);
  
*************** flow_loops_find (struct loops *loops)
*** 594,619 ****
      }
  
    /* Allocate loop structures.  */
!   loops->parray = XCNEWVEC (struct loop *, 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];
  
    /* 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;
  
--- 568,588 ----
      }
  
    /* Allocate loop structures.  */
!   loops->larray = VEC_alloc (loop_p, heap, num_loops + 1);
  
    /* Dummy loop containing whole function.  */
!   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.  */
    FOR_EACH_BB (bb)
      bb->loop_father = loops->tree_root;
  
*************** flow_loops_find (struct loops *loops)
*** 639,645 ****
  
  	  header = BASIC_BLOCK (rc_order[b]);
  
! 	  loop = loops->parray[num_loops] = XCNEW (struct loop);
  
  	  loop->header = header;
  	  loop->num = num_loops;
--- 608,615 ----
  
  	  header = BASIC_BLOCK (rc_order[b]);
  
! 	  loop = XCNEW (struct loop);
! 	  VEC_quick_push (loop_p, loops->larray, loop);
  
  	  loop->header = header;
  	  loop->num = num_loops;
*************** flow_loops_find (struct loops *loops)
*** 662,670 ****
  	  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);
      }
--- 632,637 ----
*************** flow_loops_find (struct loops *loops)
*** 672,678 ****
    sbitmap_free (headers);
  
    loops->state = 0;
!   return loops->num;
  }
  
  /* Return nonzero if basic block BB belongs to LOOP.  */
--- 639,645 ----
    sbitmap_free (headers);
  
    loops->state = 0;
!   return VEC_length (loop_p, loops->larray);
  }
  
  /* Return nonzero if basic block BB belongs to LOOP.  */
*************** find_common_loop (struct loop *loop_s, s
*** 924,929 ****
--- 891,911 ----
    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
*************** cancel_loop (struct loop *loop)
*** 939,952 ****
    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);
  }
  
  /* Cancels LOOP and all its subloops.  */
--- 921,927 ----
    for (i = 0; i < loop->num_nodes; i++)
      bbs[i]->loop_father = loop->outer;
  
!   delete_loop (loop);
  }
  
  /* Cancels LOOP and all its subloops.  */
*************** verify_loop_structure (void)
*** 974,1025 ****
    struct loop *loop;
    int err = 0;
    edge e;
  
    /* Check sizes.  */
!   sizes = XCNEWVEC (unsigned, current_loops->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++)
      {
!       if (!current_loops->parray[i])
! 	continue;
  
!       if (current_loops->parray[i]->num_nodes != sizes[i])
  	{
  	  error ("size of loop %d should be %d, not %d",
! 		   i, sizes[i], current_loops->parray[i]->num_nodes);
  	  err = 1;
  	}
      }
  
    /* Check get_loop_body.  */
!   for (i = 1; i < current_loops->num; i++)
      {
-       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);
  	    err = 1;
  	  }
        free (bbs);
      }
  
    /* Check headers and latches.  */
!   for (i = 1; i < current_loops->num; i++)
      {
!       loop = current_loops->parray[i];
!       if (!loop)
! 	continue;
  
        if ((current_loops->state & LOOPS_HAVE_PREHEADERS)
  	  && EDGE_COUNT (loop->header->preds) != 2)
--- 949,996 ----
    struct loop *loop;
    int err = 0;
    edge e;
+   unsigned num = number_of_loops ();
+   loop_iterator li;
  
    /* Check sizes.  */
!   sizes = XCNEWVEC (unsigned, num);
    sizes[0] = 2;
  
    FOR_EACH_BB (bb)
      for (loop = bb->loop_father; loop; loop = loop->outer)
        sizes[loop->num]++;
  
!   FOR_EACH_LOOP (li, loop, LI_INCLUDE_ROOT)
      {
!       i = loop->num;
  
!       if (loop->num_nodes != sizes[i])
  	{
  	  error ("size of loop %d should be %d, not %d",
! 		   i, sizes[i], loop->num_nodes);
  	  err = 1;
  	}
      }
  
    /* Check get_loop_body.  */
!   FOR_EACH_LOOP (li, loop, 0)
      {
        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, loop->num);
  	    err = 1;
  	  }
        free (bbs);
      }
  
    /* Check headers and latches.  */
!   FOR_EACH_LOOP (li, loop, 0)
      {
!       i = loop->num;
  
        if ((current_loops->state & LOOPS_HAVE_PREHEADERS)
  	  && EDGE_COUNT (loop->header->preds) != 2)
*************** verify_loop_structure (void)
*** 1120,1126 ****
    /* Check the single_exit.  */
    if (current_loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
      {
!       memset (sizes, 0, sizeof (unsigned) * current_loops->num);
        FOR_EACH_BB (bb)
  	{
  	  edge_iterator ei;
--- 1091,1097 ----
    /* Check the single_exit.  */
    if (current_loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
      {
!       memset (sizes, 0, sizeof (unsigned) * num);
        FOR_EACH_BB (bb)
  	{
  	  edge_iterator ei;
*************** verify_loop_structure (void)
*** 1154,1164 ****
  	    }
  	}
  
!       for (i = 1; i < current_loops->num; i++)
  	{
! 	  loop = current_loops->parray[i];
! 	  if (!loop)
! 	    continue;
  
  	  if (sizes[i] == 1
  	      && !single_exit (loop))
--- 1125,1133 ----
  	    }
  	}
  
!       FOR_EACH_LOOP (li, loop, 0)
  	{
! 	  i = loop->num;
  
  	  if (sizes[i] == 1
  	      && !single_exit (loop))
Index: cfgloop.h
===================================================================
*** cfgloop.h	(revision 119711)
--- cfgloop.h	(working copy)
*************** struct loop
*** 146,157 ****
       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.  */
--- 146,151 ----
*************** enum
*** 166,191 ****
  #define LOOPS_NORMAL (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES \
  		      | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
  
  /* 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;
  
    /* 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.  */
--- 160,180 ----
  #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
  {
    /* State of loops.  */
    int state;
  
!   /* Array of the loops.  */
!   VEC (loop_p, heap) *larray;
  
    /* Pointer to root of loop hierarchy tree.  */
    struct loop *tree_root;
  };
  
  /* Loop recognition.  */
*************** extern void add_bb_to_loop (basic_block,
*** 231,236 ****
--- 220,226 ----
  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 *);
  
*************** simple_loop_desc (struct loop *loop)
*** 375,380 ****
--- 365,488 ----
    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: tree-cfg.c
===================================================================
*** tree-cfg.c	(revision 119711)
--- tree-cfg.c	(working copy)
*************** replace_uses_by (tree name, tree val)
*** 1245,1251 ****
    use_operand_p use;
    tree stmt;
    edge e;
-   unsigned i;
  
    FOR_EACH_IMM_USE_STMT (stmt, imm_iter, name)
      {
--- 1245,1250 ----
*************** replace_uses_by (tree name, tree val)
*** 1286,1297 ****
    if (current_loops)
      {
        struct loop *loop;
  
!       for (i = 0; i < current_loops->num; i++)
  	{
! 	  loop = current_loops->parray[i];
! 	  if (loop)
! 	    substitute_in_loop_info (loop, name, val);
  	}
      }
  }
--- 1285,1295 ----
    if (current_loops)
      {
        struct loop *loop;
+       loop_iterator li;
  
!       FOR_EACH_LOOP (li, loop, 0)
  	{
! 	  substitute_in_loop_info (loop, name, val);
  	}
      }
  }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]