[patch] Use current_loops instead of loops argument

Zdenek Dvorak rakdver@atrey.karlin.mff.cuni.cz
Fri Nov 24 13:11:00 GMT 2006


Hello,

at the moment, some of the loop manipulation functions take struct loops
as an argument, while some use the current_loops global variable.
In effect, on some places we end up using both these approaches
at the same time, which is a bit confusing.  This patch makes us use
current_loops everywhere, instead.

Bootstrapped & regtested on i686.  I will wait for some time before
commiting it, to give people chance to complain.

Zdenek

	* tree-vrp.c (execute_vrp): Do not pass loops structure through
	arguments.
	* loop-unswitch.c (unswitch_loops, unswitch_single_loop,
	unswitch_loop): Ditto.
	* tree-loop-linear.c (linear_transform_loops): Ditto.
	* tree-ssa-loop-im.c (determine_lsm, tree_ssa_lim_initialize,
	tree_ssa_lim): Ditto.
	* tree-ssa-loop-niter.c (estimate_numbers_of_iterations,
	free_numbers_of_iterations_estimates): Ditto.
	* tree-ssa-loop-unswitch.c (tree_ssa_unswitch_loops,
	tree_unswitch_single_loop, tree_unswitch_loop): Ditto.
	* cfgloopmanip.c (fix_bb_placement, fix_bb_placements,
	remove_path, add_loop, loopify, unloop, fix_loop_placements,
	place_new_loop, duplicate_loop, duplicate_subloops,
	update_single_exit_for_duplicated_loops, copy_loops_to,
	duplicate_loop_to_header_edge, create_preheaders,
	force_single_succ_latches, loop_version, fix_loop_structure):
	Ditto.
	* tree-ssa-loop-manip.c (tree_duplicate_loop_to_header_edge,
	tree_unroll_loop): Ditto.
	* tree-ssa-loop-ch.c (copy_loop_headers): Ditto.
	* tree-scalar-evolution.c (select_loops_exit_conditions,
	scev_initialize, scev_analysis): Ditto.
	* tree-scalar-evolution.h (scev_initialize): Ditto.
	* cfghooks.c (cfg_hook_duplicate_loop_to_header_edge): Ditto.
	* cfgloopanal.c (mark_irreducible_loops, mark_loop_exit_edges): Ditto.
	* tree-ssa-loop-ivopts.c (tree_ssa_iv_optimize): Ditto.
	* modulo-sched.c (sms_schedule): Ditto.
	* tree-ssa-dom.c (tree_ssa_dominator_optimize): Ditto.
	* loop-init.c (loop_optimizer_init, rtl_move_loop_invariants,
	rtl_unswitch, rtl_unroll_and_peel_loops, rtl_doloop): Ditto.
	* ifcvt.c (if_convert): Ditto.
	* tree-ssa-loop-ivcanon.c (try_unroll_loop_completely,
	canonicalize_loop_induction_variables,
	canonicalize_induction_variables,
	tree_unroll_loops_completely, remove_empty_loops): Ditto.
	* tree-ssa-loop.c (tree_ssa_loop_init, tree_ssa_loop_im,
	tree_ssa_loop_unswitch, tree_vectorize, tree_linear_transform,
	tree_ssa_loop_ivcanon, tree_ssa_empty_loop, tree_ssa_loop_bounds,
	tree_complete_unroll, tree_ssa_loop_prefetch, tree_ssa_loop_ivopts,
	tree_ssa_loop_done): Ditto.
	* predict.c (predict_loops, tree_estimate_probability, estimate_loops,
	estimate_bb_frequencies): Ditto.
	* tree-vectorizer.c (slpeel_tree_duplicate_loop_to_edge_cfg,
	slpeel_tree_peel_loop_to_edge, vectorize_loops): Ditto.
	* loop-unroll.c (unroll_and_peel_loops, peel_loops_completely,
	decide_unrolling_and_peeling, peel_loop_completely,
	unroll_loop_constant_iterations, unroll_loop_runtime_iterations,
	peel_loop_simple, unroll_loop_stupid): Ditto.
	* loop-doloop.c (doloop_optimize_loops): Ditto.
	* tree-cfgcleanup.c (cleanup_tree_cfg_loop): Ditto.
	* loop-invariant.c (move_loop_invariants): Ditto.
	* tree-ssa-dce.c (tree_ssa_dce_loop): Ditto.
	* tree-ssa-loop-prefetch.c (loop_prefetch_arrays,
	tree_ssa_prefetch_arrays): Ditto.
	* lambda-code.c (gcc_loopnest_to_lambda_loopnest, perfect_nestify):
	Ditto.
	* tree-vect-transform.c (vect_do_peeling_for_loop_bound,
	vect_do_peeling_for_alignment, vect_transform_loop): Ditto.
	* cfgloop.c (flow_loops_cfg_dump, flow_loops_dump,
	mark_single_exit_loops, cancel_loop, cancel_loop_tree,
	verify_loop_structure): Ditto.
	* tree-flow.h (vectorize_loops, tree_ssa_lim, tree_ssa_unswitch_loops,
	canonicalize_induction_variables, tree_unroll_loops_completely,
	tree_ssa_prefetch_arrays, remove_empty_loops, tree_ssa_iv_optimize,
	estimate_numbers_of_iterations, free_numbers_of_iterations_estimates,
	tree_duplicate_loop_to_header_edge, tree_ssa_loop_version,
	tree_unroll_loop, linear_transform_loops): Declaration changed.
	* basic-block.h: Remove declaration of struct loops.
	* cfghooks.h (struct cfg_hooks): Change type of
	cfg_hook_duplicate_loop_to_header_edge.
	(cfg_hook_duplicate_loop_to_header_edge): Declaration changed.
	* tree-vectorizer.h (slpeel_tree_peel_loop_to_edge,
	vect_transform_loop): Declaration changed.
	* lambda.h (gcc_loopnest_to_lambda_loopnest): Declaration changed.
	* cfgloop.h (flow_loops_dump, fix_loop_structure,
	mark_irreducible_loops, mark_single_exit_loops, mark_loop_exit_edges,
	cancel_loop_tree, create_preheaders, force_single_succ_latches,
	verify_loop_structure, duplicate_loop, duplicate_loop_to_header_edge,
	loopify, loop_version, remove_path, unswitch_loops,
	unroll_and_peel_loops, doloop_optimize_loops, move_loop_invariants):
	Declaration changed.

Index: tree-vrp.c
===================================================================
*** tree-vrp.c	(revision 119131)
--- tree-vrp.c	(working copy)
*************** execute_vrp (void)
*** 4774,4780 ****
  
    loop_optimizer_init (LOOPS_NORMAL);
    if (current_loops)
!     scev_initialize (current_loops);
  
    vrp_initialize ();
    ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node);
--- 4774,4780 ----
  
    loop_optimizer_init (LOOPS_NORMAL);
    if (current_loops)
!     scev_initialize ();
  
    vrp_initialize ();
    ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node);
Index: loop-unswitch.c
===================================================================
*** loop-unswitch.c	(revision 119131)
--- loop-unswitch.c	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 79,87 ****
    containing subloops would not be very large compared to complications
    with handling this case.  */
  
! static struct loop *unswitch_loop (struct loops *, struct loop *,
! 				   basic_block, rtx, rtx);
! static void unswitch_single_loop (struct loops *, struct loop *, rtx, int);
  static rtx may_unswitch_on (basic_block, struct loop *, rtx *);
  
  /* Prepare a sequence comparing OP0 with OP1 using COMP and jumping to LABEL if
--- 79,86 ----
    containing subloops would not be very large compared to complications
    with handling this case.  */
  
! static struct loop *unswitch_loop (struct loop *, basic_block, rtx, rtx);
! static void unswitch_single_loop (struct loop *, rtx, int);
  static rtx may_unswitch_on (basic_block, struct loop *, rtx *);
  
  /* Prepare a sequence comparing OP0 with OP1 using COMP and jumping to LABEL if
*************** compare_and_jump_seq (rtx op0, rtx op1, 
*** 135,164 ****
    return seq;
  }
  
! /* Main entry point.  Perform loop unswitching on all suitable LOOPS.  */
  void
! unswitch_loops (struct loops *loops)
  {
    int i, num;
    struct loop *loop;
  
    /* Go through inner loops (only original ones).  */
!   num = loops->num;
  
    for (i = 1; i < num; i++)
      {
        /* Removed loop?  */
!       loop = loops->parray[i];
        if (!loop)
  	continue;
  
        if (loop->inner)
  	continue;
  
!       unswitch_single_loop (loops, loop, NULL_RTX, 0);
  #ifdef ENABLE_CHECKING
        verify_dominators (CDI_DOMINATORS);
!       verify_loop_structure (loops);
  #endif
      }
  
--- 134,163 ----
    return seq;
  }
  
! /* Main entry point.  Perform loop unswitching on all suitable loops.  */
  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);
!       verify_loop_structure ();
  #endif
      }
  
*************** reversed_condition (rtx cond)
*** 259,266 ****
     number of unswitchings done; do not allow it to grow too much, it is too
     easy to create example on that the code would grow exponentially.  */
  static void
! unswitch_single_loop (struct loops *loops, struct loop *loop,
! 		      rtx cond_checked, int num)
  {
    basic_block *bbs;
    struct loop *nloop;
--- 258,264 ----
     number of unswitchings done; do not allow it to grow too much, it is too
     easy to create example on that the code would grow exponentially.  */
  static void
! unswitch_single_loop (struct loop *loop, rtx cond_checked, int num)
  {
    basic_block *bbs;
    struct loop *nloop;
*************** unswitch_single_loop (struct loops *loop
*** 351,357 ****
  	{
  	  /* Remove false path.  */
  	  e = FALLTHRU_EDGE (bbs[i]);
! 	  remove_path (loops, e);
  	  free (bbs);
  	  repeat = 1;
  	}
--- 349,355 ----
  	{
  	  /* Remove false path.  */
  	  e = FALLTHRU_EDGE (bbs[i]);
! 	  remove_path (e);
  	  free (bbs);
  	  repeat = 1;
  	}
*************** unswitch_single_loop (struct loops *loop
*** 359,365 ****
  	{
  	  /* Remove true path.  */
  	  e = BRANCH_EDGE (bbs[i]);
! 	  remove_path (loops, e);
  	  free (bbs);
  	  repeat = 1;
  	}
--- 357,363 ----
  	{
  	  /* Remove true path.  */
  	  e = BRANCH_EDGE (bbs[i]);
! 	  remove_path (e);
  	  free (bbs);
  	  repeat = 1;
  	}
*************** unswitch_single_loop (struct loops *loop
*** 376,387 ****
      fprintf (dump_file, ";; Unswitching loop\n");
  
    /* Unswitch the loop on this condition.  */
!   nloop = unswitch_loop (loops, loop, bbs[i], cond, cinsn);
    gcc_assert (nloop);
  
    /* Invoke itself on modified loops.  */
!   unswitch_single_loop (loops, nloop, rconds, num + 1);
!   unswitch_single_loop (loops, loop, conds, num + 1);
  
    free_EXPR_LIST_node (conds);
    if (rcond)
--- 374,385 ----
      fprintf (dump_file, ";; Unswitching loop\n");
  
    /* Unswitch the loop on this condition.  */
!   nloop = unswitch_loop (loop, bbs[i], cond, cinsn);
    gcc_assert (nloop);
  
    /* Invoke itself on modified loops.  */
!   unswitch_single_loop (nloop, rconds, num + 1);
!   unswitch_single_loop (loop, conds, num + 1);
  
    free_EXPR_LIST_node (conds);
    if (rcond)
*************** unswitch_single_loop (struct loops *loop
*** 398,405 ****
     NULL, it is the insn in that COND is compared.  */
  
  static struct loop *
! unswitch_loop (struct loops *loops, struct loop *loop, basic_block unswitch_on,
! 	       rtx cond, rtx cinsn)
  {
    edge entry, latch_edge, true_edge, false_edge, e;
    basic_block switch_bb, unswitch_on_alt;
--- 396,402 ----
     NULL, it is the insn in that COND is compared.  */
  
  static struct loop *
! unswitch_loop (struct loop *loop, basic_block unswitch_on, rtx cond, rtx cinsn)
  {
    edge entry, latch_edge, true_edge, false_edge, e;
    basic_block switch_bb, unswitch_on_alt;
*************** unswitch_loop (struct loops *loops, stru
*** 423,429 ****
    entry->flags &= ~EDGE_IRREDUCIBLE_LOOP;
    zero_bitmap = sbitmap_alloc (2);
    sbitmap_zero (zero_bitmap);
!   if (!duplicate_loop_to_header_edge (loop, entry, loops, 1,
  	zero_bitmap, NULL, NULL, NULL, 0))
      {
        sbitmap_free (zero_bitmap);
--- 420,426 ----
    entry->flags &= ~EDGE_IRREDUCIBLE_LOOP;
    zero_bitmap = sbitmap_alloc (2);
    sbitmap_zero (zero_bitmap);
!   if (!duplicate_loop_to_header_edge (loop, entry, 1,
  	zero_bitmap, NULL, NULL, NULL, 0))
      {
        sbitmap_free (zero_bitmap);
*************** unswitch_loop (struct loops *loops, stru
*** 466,478 ****
      }
  
    /* Loopify from the copy of LOOP body, constructing the new loop.  */
!   nloop = loopify (loops, latch_edge,
  		   single_pred_edge (get_bb_copy (loop->header)), switch_bb,
  		   BRANCH_EDGE (switch_bb), FALLTHRU_EDGE (switch_bb), true);
  
    /* Remove branches that are now unreachable in new loops.  */
!   remove_path (loops, true_edge);
!   remove_path (loops, false_edge);
  
    /* One of created loops do not have to be subloop of the outer loop now,
       so fix its placement in loop data structure.  */
--- 463,475 ----
      }
  
    /* Loopify from the copy of LOOP body, constructing the new loop.  */
!   nloop = loopify (latch_edge,
  		   single_pred_edge (get_bb_copy (loop->header)), switch_bb,
  		   BRANCH_EDGE (switch_bb), FALLTHRU_EDGE (switch_bb), true);
  
    /* Remove branches that are now unreachable in new loops.  */
!   remove_path (true_edge);
!   remove_path (false_edge);
  
    /* One of created loops do not have to be subloop of the outer loop now,
       so fix its placement in loop data structure.  */
Index: tree-loop-linear.c
===================================================================
*** tree-loop-linear.c	(revision 119131)
--- tree-loop-linear.c	(working copy)
*************** try_interchange_loops (lambda_trans_matr
*** 236,257 ****
    return trans;
  }
  
! /* Perform a set of linear transforms on LOOPS.  */
  
  void
! linear_transform_loops (struct loops *loops)
  {
    bool modified = false;
    unsigned int i;
    VEC(tree,heap) *oldivs = NULL;
    VEC(tree,heap) *invariants = NULL;
    
!   for (i = 1; i < loops->num; i++)
      {
        unsigned int depth = 0;
        VEC (ddr_p, heap) *dependence_relations;
        VEC (data_reference_p, heap) *datarefs;
!       struct loop *loop_nest = loops->parray[i];
        struct loop *temp;
        lambda_loopnest before, after;
        lambda_trans_matrix trans;
--- 236,257 ----
    return trans;
  }
  
! /* Perform a set of linear transforms on loops.  */
  
  void
! 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;
*************** linear_transform_loops (struct loops *lo
*** 319,325 ****
  	  goto free_and_continue;
  	}
  
!       before = gcc_loopnest_to_lambda_loopnest (loops, loop_nest, &oldivs,
  						&invariants);
  
        if (!before)
--- 319,325 ----
  	  goto free_and_continue;
  	}
  
!       before = gcc_loopnest_to_lambda_loopnest (loop_nest, &oldivs,
  						&invariants);
  
        if (!before)
Index: tree-ssa-loop-im.c
===================================================================
*** tree-ssa-loop-im.c	(revision 119131)
--- tree-ssa-loop-im.c	(working copy)
*************** determine_lsm_loop (struct loop *loop)
*** 1372,1391 ****
  }
  
  /* Try to perform store motion for all memory references modified inside
!    any of LOOPS.  */
  
  static void
! determine_lsm (struct loops *loops)
  {
    struct loop *loop;
  
!   if (!loops->tree_root->inner)
      return;
  
    /* Pass the loops from the outermost and perform the store motion as
       suitable.  */
  
!   loop = loops->tree_root->inner;
    while (1)
      {
        determine_lsm_loop (loop);
--- 1372,1391 ----
  }
  
  /* Try to perform store motion for all memory references modified inside
!    loops.  */
  
  static void
! 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);
*************** determine_lsm (struct loops *loops)
*** 1398,1404 ****
        while (!loop->next)
  	{
  	  loop = loop->outer;
! 	  if (loop == loops->tree_root)
  	    {
  	      bsi_commit_edge_inserts ();
  	      return;
--- 1398,1404 ----
        while (!loop->next)
  	{
  	  loop = loop->outer;
! 	  if (loop == current_loops->tree_root)
  	    {
  	      bsi_commit_edge_inserts ();
  	      return;
*************** fill_always_executed_in (struct loop *lo
*** 1476,1486 ****
      fill_always_executed_in (loop, contains_call);
  }
  
! /* Compute the global information needed by the loop invariant motion pass.
!    LOOPS is the loop tree.  */
  
  static void
! tree_ssa_lim_initialize (struct loops *loops)
  {
    sbitmap contains_call = sbitmap_alloc (last_basic_block);
    block_stmt_iterator bsi;
--- 1476,1485 ----
      fill_always_executed_in (loop, contains_call);
  }
  
! /* Compute the global information needed by the loop invariant motion pass.  */
  
  static void
! tree_ssa_lim_initialize (void)
  {
    sbitmap contains_call = sbitmap_alloc (last_basic_block);
    block_stmt_iterator bsi;
*************** tree_ssa_lim_initialize (struct loops *l
*** 1500,1506 ****
  	SET_BIT (contains_call, bb->index);
      }
  
!   for (loop = loops->tree_root->inner; loop; loop = loop->next)
      fill_always_executed_in (loop, contains_call);
  
    sbitmap_free (contains_call);
--- 1499,1505 ----
  	SET_BIT (contains_call, bb->index);
      }
  
!   for (loop = current_loops->tree_root->inner; loop; loop = loop->next)
      fill_always_executed_in (loop, contains_call);
  
    sbitmap_free (contains_call);
*************** tree_ssa_lim_finalize (void)
*** 1519,1531 ****
      }
  }
  
! /* Moves invariants from LOOPS.  Only "expensive" invariants are moved out --
     i.e. those that are likely to be win regardless of the register pressure.  */
  
  void
! tree_ssa_lim (struct loops *loops)
  {
!   tree_ssa_lim_initialize (loops);
  
    /* For each statement determine the outermost loop in that it is
       invariant and cost for computing the invariant.  */
--- 1518,1530 ----
      }
  }
  
! /* Moves invariants from loops.  Only "expensive" invariants are moved out --
     i.e. those that are likely to be win regardless of the register pressure.  */
  
  void
! tree_ssa_lim (void)
  {
!   tree_ssa_lim_initialize ();
  
    /* For each statement determine the outermost loop in that it is
       invariant and cost for computing the invariant.  */
*************** tree_ssa_lim (struct loops *loops)
*** 1534,1540 ****
    /* For each memory reference determine whether it is possible to hoist it
       out of the loop.  Force the necessary invariants to be moved out of the
       loops as well.  */
!   determine_lsm (loops);
  
    /* Move the expressions that are expensive enough.  */
    move_computations ();
--- 1533,1539 ----
    /* For each memory reference determine whether it is possible to hoist it
       out of the loop.  Force the necessary invariants to be moved out of the
       loops as well.  */
!   determine_lsm ();
  
    /* Move the expressions that are expensive enough.  */
    move_computations ();
Index: tree-ssa-loop-niter.c
===================================================================
*** tree-ssa-loop-niter.c	(revision 119131)
--- tree-ssa-loop-niter.c	(working copy)
*************** estimate_numbers_of_iterations_loop (str
*** 2018,2034 ****
    compute_estimated_nb_iterations (loop);
  }
  
! /* Records estimates on numbers of iterations of LOOPS.  */
  
  void
! estimate_numbers_of_iterations (struct loops *loops)
  {
    unsigned i;
    struct loop *loop;
  
!   for (i = 1; i < loops->num; i++)
      {
!       loop = loops->parray[i];
        if (loop)
  	estimate_numbers_of_iterations_loop (loop);
      }
--- 2018,2034 ----
    compute_estimated_nb_iterations (loop);
  }
  
! /* Records estimates on numbers of iterations of loops.  */
  
  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);
      }
*************** free_numbers_of_iterations_estimates_loo
*** 2240,2256 ****
    loop->bounds = NULL;
  }
  
! /* Frees the information on upper bounds on numbers of iterations of LOOPS.  */
  
  void
! free_numbers_of_iterations_estimates (struct loops *loops)
  {
    unsigned i;
    struct loop *loop;
  
!   for (i = 1; i < loops->num; i++)
      {
!       loop = loops->parray[i];
        if (loop)
  	free_numbers_of_iterations_estimates_loop (loop);
      }
--- 2240,2256 ----
    loop->bounds = NULL;
  }
  
! /* Frees the information on upper bounds on numbers of iterations of loops.  */
  
  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);
      }
Index: tree-ssa-loop-unswitch.c
===================================================================
*** tree-ssa-loop-unswitch.c	(revision 119131)
--- tree-ssa-loop-unswitch.c	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 73,106 ****
     tree-ssa-loop-im.c ensures that all the suitable conditions are in this
     shape.  */
  
! static struct loop *tree_unswitch_loop (struct loops *, struct loop *, basic_block,
! 				   tree);
! static bool tree_unswitch_single_loop (struct loops *, struct loop *, int);
  static tree tree_may_unswitch_on (basic_block, struct loop *);
  
! /* Main entry point.  Perform loop unswitching on all suitable LOOPS.  */
  
  unsigned int
! tree_ssa_unswitch_loops (struct loops *loops)
  {
    int i, num;
    struct loop *loop;
    bool changed = false;
  
    /* Go through inner loops (only original ones).  */
!   num = loops->num;
  
    for (i = 1; i < num; i++)
      {
        /* Removed loop?  */
!       loop = loops->parray[i];
        if (!loop)
  	continue;
  
        if (loop->inner)
  	continue;
  
!       changed |= tree_unswitch_single_loop (loops, loop, 0);
      }
  
    if (changed)
--- 73,105 ----
     tree-ssa-loop-im.c ensures that all the suitable conditions are in this
     shape.  */
  
! static struct loop *tree_unswitch_loop (struct loop *, basic_block, tree);
! static bool tree_unswitch_single_loop (struct loop *, int);
  static tree tree_may_unswitch_on (basic_block, struct loop *);
  
! /* Main entry point.  Perform loop unswitching on all suitable loops.  */
  
  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);
      }
  
    if (changed)
*************** simplify_using_entry_checks (struct loop
*** 177,183 ****
     grow exponentially.  */
  
  static bool
! tree_unswitch_single_loop (struct loops *loops, struct loop *loop, int num)
  {
    basic_block *bbs;
    struct loop *nloop;
--- 176,182 ----
     grow exponentially.  */
  
  static bool
! tree_unswitch_single_loop (struct loop *loop, int num)
  {
    basic_block *bbs;
    struct loop *nloop;
*************** tree_unswitch_single_loop (struct loops 
*** 252,258 ****
  
    initialize_original_copy_tables ();
    /* Unswitch the loop on this condition.  */
!   nloop = tree_unswitch_loop (loops, loop, bbs[i], cond);
    if (!nloop)
      {
        free_original_copy_tables ();
--- 251,257 ----
  
    initialize_original_copy_tables ();
    /* Unswitch the loop on this condition.  */
!   nloop = tree_unswitch_loop (loop, bbs[i], cond);
    if (!nloop)
      {
        free_original_copy_tables ();
*************** tree_unswitch_single_loop (struct loops 
*** 265,272 ****
    free_original_copy_tables ();
  
    /* Invoke itself on modified loops.  */
!   tree_unswitch_single_loop (loops, nloop, num + 1);
!   tree_unswitch_single_loop (loops, loop, num + 1);
    free (bbs);
    return true;
  }
--- 264,271 ----
    free_original_copy_tables ();
  
    /* Invoke itself on modified loops.  */
!   tree_unswitch_single_loop (nloop, num + 1);
!   tree_unswitch_single_loop (loop, num + 1);
    free (bbs);
    return true;
  }
*************** tree_unswitch_single_loop (struct loops 
*** 277,283 ****
     if impossible, new loop otherwise.  */
  
  static struct loop *
! tree_unswitch_loop (struct loops *loops, struct loop *loop,
  		    basic_block unswitch_on, tree cond)
  {
    basic_block condition_bb;
--- 276,282 ----
     if impossible, new loop otherwise.  */
  
  static struct loop *
! tree_unswitch_loop (struct loop *loop,
  		    basic_block unswitch_on, tree cond)
  {
    basic_block condition_bb;
*************** tree_unswitch_loop (struct loops *loops,
*** 287,292 ****
    gcc_assert (EDGE_COUNT (unswitch_on->succs) == 2);
    gcc_assert (loop->inner == NULL);
  
!   return loop_version (loops, loop, unshare_expr (cond), 
  		       &condition_bb, false);
  }
--- 286,291 ----
    gcc_assert (EDGE_COUNT (unswitch_on->succs) == 2);
    gcc_assert (loop->inner == NULL);
  
!   return loop_version (loop, unshare_expr (cond), 
  		       &condition_bb, false);
  }
Index: cfgloopmanip.c
===================================================================
*** cfgloopmanip.c	(revision 119131)
--- cfgloopmanip.c	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 31,38 ****
  #include "cfghooks.h"
  #include "output.h"
  
! static void duplicate_subloops (struct loops *, struct loop *, struct loop *);
! static void copy_loops_to (struct loops *, struct loop **, int,
  			   struct loop *);
  static void loop_redirect_edge (edge, basic_block);
  static bool loop_delete_branch_edge (edge, int);
--- 31,38 ----
  #include "cfghooks.h"
  #include "output.h"
  
! static void duplicate_subloops (struct loop *, struct loop *);
! static void copy_loops_to (struct loop **, int,
  			   struct loop *);
  static void loop_redirect_edge (edge, basic_block);
  static bool loop_delete_branch_edge (edge, int);
*************** static void remove_bbs (basic_block *, i
*** 40,52 ****
  static bool rpe_enum_p (basic_block, void *);
  static int find_path (edge, basic_block **);
  static bool alp_enum_p (basic_block, void *);
! static void fix_loop_placements (struct loops *, struct loop *, bool *);
! static bool fix_bb_placement (struct loops *, basic_block);
! static void fix_bb_placements (struct loops *, basic_block, bool *);
! static void place_new_loop (struct loops *, struct loop *);
  static void scale_loop_frequencies (struct loop *, int, int);
  static basic_block create_preheader (struct loop *, int);
! static void unloop (struct loops *, struct loop *, bool *);
  
  #define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
  
--- 40,52 ----
  static bool rpe_enum_p (basic_block, void *);
  static int find_path (edge, basic_block **);
  static bool alp_enum_p (basic_block, void *);
! static void fix_loop_placements (struct loop *, bool *);
! static bool fix_bb_placement (basic_block);
! static void fix_bb_placements (basic_block, bool *);
! static void place_new_loop (struct loop *);
  static void scale_loop_frequencies (struct loop *, int, int);
  static basic_block create_preheader (struct loop *, int);
! static void unloop (struct loop *, bool *);
  
  #define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
  
*************** find_path (edge e, basic_block **bbs)
*** 85,91 ****
  			     n_basic_blocks, e->dest);
  }
  
! /* Fix placement of basic block BB inside loop hierarchy stored in LOOPS --
     Let L be a loop to that BB belongs.  Then every successor of BB must either
       1) belong to some superloop of loop L, or
       2) be a header of loop K such that K->outer is superloop of L
--- 85,91 ----
  			     n_basic_blocks, e->dest);
  }
  
! /* Fix placement of basic block BB inside loop hierarchy --
     Let L be a loop to that BB belongs.  Then every successor of BB must either
       1) belong to some superloop of loop L, or
       2) be a header of loop K such that K->outer is superloop of L
*************** find_path (edge e, basic_block **bbs)
*** 93,103 ****
     false if the placement of BB was already correct (provided that placements
     of its successors are correct).  */
  static bool
! fix_bb_placement (struct loops *loops, basic_block bb)
  {
    edge e;
    edge_iterator ei;
!   struct loop *loop = loops->tree_root, *act;
  
    FOR_EACH_EDGE (e, ei, bb->succs)
      {
--- 93,103 ----
     false if the placement of BB was already correct (provided that placements
     of its successors are correct).  */
  static bool
! fix_bb_placement (basic_block bb)
  {
    edge e;
    edge_iterator ei;
!   struct loop *loop = current_loops->tree_root, *act;
  
    FOR_EACH_EDGE (e, ei, bb->succs)
      {
*************** fix_bb_placement (struct loops *loops, b
*** 134,140 ****
     IRRED_INVALIDATED is set to true.  */
  
  static void
! fix_bb_placements (struct loops *loops, basic_block from,
  		   bool *irred_invalidated)
  {
    sbitmap in_queue;
--- 134,140 ----
     IRRED_INVALIDATED is set to true.  */
  
  static void
! fix_bb_placements (basic_block from,
  		   bool *irred_invalidated)
  {
    sbitmap in_queue;
*************** fix_bb_placements (struct loops *loops, 
*** 150,156 ****
       fix_loop_placement.  */
  
    base_loop = from->loop_father;
!   if (base_loop == loops->tree_root)
      return;
  
    in_queue = sbitmap_alloc (last_basic_block);
--- 150,156 ----
       fix_loop_placement.  */
  
    base_loop = from->loop_father;
!   if (base_loop == current_loops->tree_root)
      return;
  
    in_queue = sbitmap_alloc (last_basic_block);
*************** fix_bb_placements (struct loops *loops, 
*** 183,189 ****
        else
  	{
  	  /* Ordinary basic block.  */
! 	  if (!fix_bb_placement (loops, from))
  	    continue;
  	}
  
--- 183,189 ----
        else
  	{
  	  /* Ordinary basic block.  */
! 	  if (!fix_bb_placement (from))
  	    continue;
  	}
  
*************** fix_bb_placements (struct loops *loops, 
*** 235,245 ****
  }
  
  /* Removes path beginning at edge E, i.e. remove basic blocks dominated by E
!    and update loop structure stored in LOOPS and dominators.  Return true if
!    we were able to remove the path, false otherwise (and nothing is affected
!    then).  */
  bool
! remove_path (struct loops *loops, edge e)
  {
    edge ae;
    basic_block *rem_bbs, *bord_bbs, *dom_bbs, from, bb;
--- 235,244 ----
  }
  
  /* Removes path beginning at edge E, i.e. remove basic blocks dominated by E
!    and update loop structures and dominators.  Return true if we were able
!    to remove the path, false otherwise (and nothing is affected then).  */
  bool
! remove_path (edge e)
  {
    edge ae;
    basic_block *rem_bbs, *bord_bbs, *dom_bbs, from, bb;
*************** remove_path (struct loops *loops, edge e
*** 273,279 ****
    while (e->src->loop_father->outer
  	 && dominated_by_p (CDI_DOMINATORS,
  			    e->src->loop_father->latch, e->dest))
!     unloop (loops, e->src->loop_father, &irred_invalidated);
  
    /* Identify the path.  */
    nrem = find_path (e, &rem_bbs);
--- 272,278 ----
    while (e->src->loop_father->outer
  	 && dominated_by_p (CDI_DOMINATORS,
  			    e->src->loop_father->latch, e->dest))
!     unloop (e->src->loop_father, &irred_invalidated);
  
    /* Identify the path.  */
    nrem = find_path (e, &rem_bbs);
*************** remove_path (struct loops *loops, edge e
*** 318,324 ****
    free (rem_bbs);
  
    for (i = 0; i < nreml; i++)
!     cancel_loop_tree (loops, deleted_loop[i]);
    free (deleted_loop);
  
    /* Find blocks whose dominators may be affected.  */
--- 317,323 ----
    free (rem_bbs);
  
    for (i = 0; i < nreml; i++)
!     cancel_loop_tree (deleted_loop[i]);
    free (deleted_loop);
  
    /* Find blocks whose dominators may be affected.  */
*************** remove_path (struct loops *loops, edge e
*** 349,360 ****
  
    /* Fix placements of basic blocks inside loops and the placement of
       loops in the loop tree.  */
!   fix_bb_placements (loops, from, &irred_invalidated);
!   fix_loop_placements (loops, from->loop_father, &irred_invalidated);
  
    if (irred_invalidated
!       && (loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS) != 0)
!     mark_irreducible_loops (loops);
  
    return true;
  }
--- 348,359 ----
  
    /* Fix placements of basic blocks inside loops and the placement of
       loops in the loop tree.  */
!   fix_bb_placements (from, &irred_invalidated);
!   fix_loop_placements (from->loop_father, &irred_invalidated);
  
    if (irred_invalidated
!       && (current_loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS) != 0)
!     mark_irreducible_loops ();
  
    return true;
  }
*************** alp_enum_p (basic_block bb, void *alp_he
*** 367,383 ****
  }
  
  /* Given LOOP structure with filled header and latch, find the body of the
!    corresponding loop and add it to LOOPS tree.  Insert the LOOP as a son of
     outer.  */
  
  static void
! add_loop (struct loops *loops, struct loop *loop, struct loop *outer)
  {
    basic_block *bbs;
    int i, n;
  
    /* Add it to loop structure.  */
!   place_new_loop (loops, loop);
    flow_loop_tree_node_add (outer, loop);
  
    /* Find its nodes.  */
--- 366,382 ----
  }
  
  /* Given LOOP structure with filled header and latch, find the body of the
!    corresponding loop and add it to loops tree.  Insert the LOOP as a son of
     outer.  */
  
  static void
! add_loop (struct loop *loop, struct loop *outer)
  {
    basic_block *bbs;
    int i, n;
  
    /* Add it to loop structure.  */
!   place_new_loop (loop);
    flow_loop_tree_node_add (outer, loop);
  
    /* Find its nodes.  */
*************** scale_loop_frequencies (struct loop *loo
*** 408,414 ****
  }
  
  /* Make area between HEADER_EDGE and LATCH_EDGE a loop by connecting
!    latch to header and update loop tree stored in LOOPS and dominators
     accordingly. Everything between them plus LATCH_EDGE destination must
     be dominated by HEADER_EDGE destination, and back-reachable from
     LATCH_EDGE source.  HEADER_EDGE is redirected to basic block SWITCH_BB,
--- 407,413 ----
  }
  
  /* Make area between HEADER_EDGE and LATCH_EDGE a loop by connecting
!    latch to header and update loop tree and dominators
     accordingly. Everything between them plus LATCH_EDGE destination must
     be dominated by HEADER_EDGE destination, and back-reachable from
     LATCH_EDGE source.  HEADER_EDGE is redirected to basic block SWITCH_BB,
*************** scale_loop_frequencies (struct loop *loo
*** 417,423 ****
     Returns newly created loop.  */
  
  struct loop *
! loopify (struct loops *loops, edge latch_edge, edge header_edge,
  	 basic_block switch_bb, edge true_edge, edge false_edge,
  	 bool redirect_all_edges)
  {
--- 416,422 ----
     Returns newly created loop.  */
  
  struct loop *
! loopify (edge latch_edge, edge header_edge,
  	 basic_block switch_bb, edge true_edge, edge false_edge,
  	 bool redirect_all_edges)
  {
*************** loopify (struct loops *loops, edge latch
*** 462,468 ****
    set_immediate_dominator (CDI_DOMINATORS, succ_bb, switch_bb);
  
    /* Compute new loop.  */
!   add_loop (loops, loop, outer);
  
    /* Add switch_bb to appropriate loop.  */
    if (switch_bb->loop_father)
--- 461,467 ----
    set_immediate_dominator (CDI_DOMINATORS, succ_bb, switch_bb);
  
    /* Compute new loop.  */
!   add_loop (loop, outer);
  
    /* Add switch_bb to appropriate loop.  */
    if (switch_bb->loop_father)
*************** loopify (struct loops *loops, edge latch
*** 510,516 ****
    return loop;
  }
  
! /* Remove the latch edge of a LOOP and update LOOPS tree to indicate that
     the LOOP was removed.  After this function, original loop latch will
     have no successor, which caller is expected to fix somehow.
  
--- 509,515 ----
    return loop;
  }
  
! /* Remove the latch edge of a LOOP and update loops to indicate that
     the LOOP was removed.  After this function, original loop latch will
     have no successor, which caller is expected to fix somehow.
  
*************** loopify (struct loops *loops, edge latch
*** 518,524 ****
     invalid, IRRED_INVALIDATED is set to true.  */
  
  static void
! unloop (struct loops *loops, struct loop *loop, bool *irred_invalidated)
  {
    basic_block *body;
    struct loop *ploop;
--- 517,523 ----
     invalid, IRRED_INVALIDATED is set to true.  */
  
  static void
! unloop (struct loop *loop, bool *irred_invalidated)
  {
    basic_block *body;
    struct loop *ploop;
*************** unloop (struct loops *loops, struct loop
*** 554,560 ****
  
    /* Remove the loop and free its data.  */
    flow_loop_tree_node_remove (loop);
!   loops->parray[loop->num] = NULL;
    flow_loop_free (loop);
  
    remove_edge (single_succ_edge (latch));
--- 553,559 ----
  
    /* 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));
*************** unloop (struct loops *loops, struct loop
*** 562,568 ****
    /* We do not pass IRRED_INVALIDATED to fix_bb_placements here, as even if
       there is an irreducible region inside the cancelled loop, the flags will
       be still correct.  */
!   fix_bb_placements (loops, latch, &dummy);
  }
  
  /* Fix placement of LOOP inside loop tree, i.e. find the innermost superloop
--- 561,567 ----
    /* We do not pass IRRED_INVALIDATED to fix_bb_placements here, as even if
       there is an irreducible region inside the cancelled loop, the flags will
       be still correct.  */
!   fix_bb_placements (latch, &dummy);
  }
  
  /* Fix placement of LOOP inside loop tree, i.e. find the innermost superloop
*************** fix_loop_placement (struct loop *loop)
*** 610,617 ****
     invalidate the information about irreducible regions.  */
  
  static void
! fix_loop_placements (struct loops *loops, struct loop *loop,
! 		     bool *irred_invalidated)
  {
    struct loop *outer;
  
--- 609,615 ----
     invalidate the information about irreducible regions.  */
  
  static void
! fix_loop_placements (struct loop *loop, bool *irred_invalidated)
  {
    struct loop *outer;
  
*************** fix_loop_placements (struct loops *loops
*** 626,656 ****
  	 for its preheader, because the successor is the header and belongs
  	 to the loop.  So call fix_bb_placements to fix up the placement
  	 of the preheader and (possibly) of its predecessors.  */
!       fix_bb_placements (loops, loop_preheader_edge (loop)->src,
  			 irred_invalidated);
        loop = outer;
      }
  }
  
! /* Creates place for a new LOOP in LOOPS structure.  */
  static void
! place_new_loop (struct loops *loops, struct loop *loop)
  {
!   loops->parray =
!     xrealloc (loops->parray, (loops->num + 1) * sizeof (struct loop *));
!   loops->parray[loops->num] = loop;
  
!   loop->num = loops->num++;
  }
  
  /* Copies copy of LOOP as subloop of TARGET loop, placing newly
!    created loop into LOOPS structure.  */
  struct loop *
! duplicate_loop (struct loops *loops, struct loop *loop, struct loop *target)
  {
    struct loop *cloop;
    cloop = XCNEW (struct loop);
!   place_new_loop (loops, cloop);
  
    /* Mark the new loop as copy of LOOP.  */
    loop->copy = cloop;
--- 624,654 ----
  	 for its preheader, because the successor is the header and belongs
  	 to the loop.  So call fix_bb_placements to fix up the placement
  	 of the preheader and (possibly) of its predecessors.  */
!       fix_bb_placements (loop_preheader_edge (loop)->src,
  			 irred_invalidated);
        loop = outer;
      }
  }
  
! /* Creates place for a new LOOP in loops structure.  */
  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
!    created loop into loops structure.  */
  struct loop *
! duplicate_loop (struct loop *loop, struct loop *target)
  {
    struct loop *cloop;
    cloop = XCNEW (struct loop);
!   place_new_loop (cloop);
  
    /* Mark the new loop as copy of LOOP.  */
    loop->copy = cloop;
*************** duplicate_loop (struct loops *loops, str
*** 662,692 ****
  }
  
  /* Copies structure of subloops of LOOP into TARGET loop, placing
!    newly created loops into loop tree stored in LOOPS.  */
  static void
! duplicate_subloops (struct loops *loops, struct loop *loop, struct loop *target)
  {
    struct loop *aloop, *cloop;
  
    for (aloop = loop->inner; aloop; aloop = aloop->next)
      {
!       cloop = duplicate_loop (loops, aloop, target);
!       duplicate_subloops (loops, aloop, cloop);
      }
  }
  
  /* Copies structure of subloops of N loops, stored in array COPIED_LOOPS,
!    into TARGET loop, placing newly created loops into loop tree LOOPS.  */
  static void
! copy_loops_to (struct loops *loops, struct loop **copied_loops, int n, struct loop *target)
  {
    struct loop *aloop;
    int i;
  
    for (i = 0; i < n; i++)
      {
!       aloop = duplicate_loop (loops, copied_loops[i], target);
!       duplicate_subloops (loops, copied_loops[i], aloop);
      }
  }
  
--- 660,690 ----
  }
  
  /* Copies structure of subloops of LOOP into TARGET loop, placing
!    newly created loops into loop tree.  */
  static void
! duplicate_subloops (struct loop *loop, struct loop *target)
  {
    struct loop *aloop, *cloop;
  
    for (aloop = loop->inner; aloop; aloop = aloop->next)
      {
!       cloop = duplicate_loop (aloop, target);
!       duplicate_subloops (aloop, cloop);
      }
  }
  
  /* Copies structure of subloops of N loops, stored in array COPIED_LOOPS,
!    into TARGET loop, placing newly created loops into loop tree.  */
  static void
! copy_loops_to (struct loop **copied_loops, int n, struct loop *target)
  {
    struct loop *aloop;
    int i;
  
    for (i = 0; i < n; i++)
      {
!       aloop = duplicate_loop (copied_loops[i], target);
!       duplicate_subloops (copied_loops[i], aloop);
      }
  }
  
*************** update_single_exit_for_duplicated_loops 
*** 812,818 ****
  }
  
  /* Duplicates body of LOOP to given edge E NDUPL times.  Takes care of updating
!    LOOPS structure and dominators.  E's destination must be LOOP header for
     this to work, i.e. it must be entry or latch edge of this loop; these are
     unique, as the loops must have preheaders for this function to work
     correctly (in case E is latch, the function unrolls the loop, if E is entry
--- 810,816 ----
  }
  
  /* Duplicates body of LOOP to given edge E NDUPL times.  Takes care of updating
!    loop structure and dominators.  E's destination must be LOOP header for
     this to work, i.e. it must be entry or latch edge of this loop; these are
     unique, as the loops must have preheaders for this function to work
     correctly (in case E is latch, the function unrolls the loop, if E is entry
*************** update_single_exit_for_duplicated_loops 
*** 822,828 ****
     flow through them) into TO_REMOVE array.  Returns false if duplication is
     impossible.  */
  bool
! duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
  			       unsigned int ndupl, sbitmap wont_exit,
  			       edge orig, edge *to_remove,
  			       unsigned int *n_to_remove, int flags)
--- 820,826 ----
     flow through them) into TO_REMOVE array.  Returns false if duplication is
     impossible.  */
  bool
! duplicate_loop_to_header_edge (struct loop *loop, edge e,
  			       unsigned int ndupl, sbitmap wont_exit,
  			       edge orig, edge *to_remove,
  			       unsigned int *n_to_remove, int flags)
*************** duplicate_loop_to_header_edge (struct lo
*** 970,976 ****
      }
  
    /* Update the information about single exits.  */
!   if (loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
      update_single_exits_after_duplication (bbs, n, target);
  
    /* Record exit edge in original loop body.  */
--- 968,974 ----
      }
  
    /* Update the information about single exits.  */
!   if (current_loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
      update_single_exits_after_duplication (bbs, n, target);
  
    /* Record exit edge in original loop body.  */
*************** duplicate_loop_to_header_edge (struct lo
*** 984,997 ****
    for (j = 0; j < ndupl; j++)
      {
        /* Copy loops.  */
!       copy_loops_to (loops, orig_loops, n_orig_loops, target);
  
        /* Copy bbs.  */
        copy_bbs (bbs, n, new_bbs, spec_edges, 2, new_spec_edges, loop,
  		place_after);
        place_after = new_spec_edges[SE_LATCH]->src;
  
!       if (loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
  	{
  	  for (i = 0; i < n; i++)
  	    bbs[i]->flags |= BB_DUPLICATED;
--- 982,995 ----
    for (j = 0; j < ndupl; j++)
      {
        /* Copy loops.  */
!       copy_loops_to (orig_loops, n_orig_loops, target);
  
        /* Copy bbs.  */
        copy_bbs (bbs, n, new_bbs, spec_edges, 2, new_spec_edges, loop,
  		place_after);
        place_after = new_spec_edges[SE_LATCH]->src;
  
!       if (current_loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
  	{
  	  for (i = 0; i < n; i++)
  	    bbs[i]->flags |= BB_DUPLICATED;
*************** create_preheader (struct loop *loop, int
*** 1192,1220 ****
    return dummy;
  }
  
! /* Create preheaders for each loop from loop tree stored in LOOPS; for meaning
!    of FLAGS see create_preheader.  */
  void
! create_preheaders (struct loops *loops, int flags)
  {
    unsigned i;
!   for (i = 1; i < loops->num; i++)
!     create_preheader (loops->parray[i], flags);
!   loops->state |= LOOPS_HAVE_PREHEADERS;
  }
  
! /* Forces all loop latches of loops from loop tree LOOPS to have only single
!    successor.  */
  void
! force_single_succ_latches (struct loops *loops)
  {
    unsigned i;
    struct loop *loop;
    edge e;
  
!   for (i = 1; i < loops->num; i++)
      {
!       loop = loops->parray[i];
        if (loop->latch != loop->header && single_succ_p (loop->latch))
  	continue;
  
--- 1190,1218 ----
    return dummy;
  }
  
! /* Create preheaders for each loop; for meaning of FLAGS see create_preheader.  */
! 
  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;
  }
  
! /* Forces all loop latches to have only single successor.  */
! 
  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;
  
*************** force_single_succ_latches (struct loops 
*** 1222,1228 ****
  
        split_edge (e);
      }
!   loops->state |= LOOPS_HAVE_SIMPLE_LATCHES;
  }
  
  /* This function is called from loop_version.  It splits the entry edge
--- 1220,1226 ----
  
        split_edge (e);
      }
!   current_loops->state |= LOOPS_HAVE_SIMPLE_LATCHES;
  }
  
  /* This function is called from loop_version.  It splits the entry edge
*************** lv_adjust_loop_entry_edge (basic_block f
*** 1284,1290 ****
     instruction stream, otherwise it is placed before LOOP.  */
  
  struct loop *
! loop_version (struct loops *loops, struct loop * loop,
  	      void *cond_expr, basic_block *condition_bb,
  	      bool place_after)
  {
--- 1282,1288 ----
     instruction stream, otherwise it is placed before LOOP.  */
  
  struct loop *
! loop_version (struct loop *loop,
  	      void *cond_expr, basic_block *condition_bb,
  	      bool place_after)
  {
*************** loop_version (struct loops *loops, struc
*** 1307,1313 ****
    first_head = entry->dest;
  
    /* Duplicate loop.  */
!   if (!cfg_hook_duplicate_loop_to_header_edge (loop, entry, loops, 1,
  					       NULL, NULL, NULL, NULL, 0))
      return NULL;
  
--- 1305,1311 ----
    first_head = entry->dest;
  
    /* Duplicate loop.  */
!   if (!cfg_hook_duplicate_loop_to_header_edge (loop, entry, 1,
  					       NULL, NULL, NULL, NULL, 0))
      return NULL;
  
*************** loop_version (struct loops *loops, struc
*** 1330,1337 ****
    latch_edge = single_succ_edge (get_bb_copy (loop->latch));
  
    extract_cond_bb_edges (cond_bb, &true_edge, &false_edge);
!   nloop = loopify (loops,
! 		   latch_edge,
  		   single_pred_edge (get_bb_copy (loop->header)),
  		   cond_bb, true_edge, false_edge,
  		   false /* Do not redirect all edges.  */);
--- 1328,1334 ----
    latch_edge = single_succ_edge (get_bb_copy (loop->latch));
  
    extract_cond_bb_edges (cond_bb, &true_edge, &false_edge);
!   nloop = loopify (latch_edge,
  		   single_pred_edge (get_bb_copy (loop->header)),
  		   cond_bb, true_edge, false_edge,
  		   false /* Do not redirect all edges.  */);
*************** loop_version (struct loops *loops, struc
*** 1379,1385 ****
    return nloop;
  }
  
! /* The structure of LOOPS might have changed.  Some loops might get removed
     (and their headers and latches were set to NULL), loop exists might get
     removed (thus the loop nesting may be wrong), and some blocks and edges
     were changed (so the information about bb --> loop mapping does not have
--- 1376,1382 ----
    return nloop;
  }
  
! /* The structure of loops might have changed.  Some loops might get removed
     (and their headers and latches were set to NULL), loop exists might get
     removed (thus the loop nesting may be wrong), and some blocks and edges
     were changed (so the information about bb --> loop mapping does not have
*************** loop_version (struct loops *loops, struc
*** 1391,1397 ****
     marked in it.  */
  
  void
! fix_loop_structure (struct loops *loops, bitmap changed_bbs)
  {
    basic_block bb;
    struct loop *loop, *ploop;
--- 1388,1394 ----
     marked in it.  */
  
  void
! fix_loop_structure (bitmap changed_bbs)
  {
    basic_block bb;
    struct loop *loop, *ploop;
*************** fix_loop_structure (struct loops *loops,
*** 1401,1414 ****
    FOR_EACH_BB (bb)
      {
        bb->aux = (void *) (size_t) bb->loop_father->depth;
!       bb->loop_father = loops->tree_root;
      }
  
    /* Remove the dead loops from structures.  */
!   loops->tree_root->num_nodes = n_basic_blocks;
!   for (i = 1; i < loops->num; i++)
      {
!       loop = loops->parray[i];
        if (!loop)
  	continue;
  
--- 1398,1411 ----
    FOR_EACH_BB (bb)
      {
        bb->aux = (void *) (size_t) bb->loop_father->depth;
!       bb->loop_father = current_loops->tree_root;
      }
  
    /* 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;
  
*************** fix_loop_structure (struct loops *loops,
*** 1425,1436 ****
  
        /* Remove the loop and free its data.  */
        flow_loop_tree_node_remove (loop);
!       loops->parray[loop->num] = NULL;
        flow_loop_free (loop);
      }
  
    /* Rescan the bodies of loops, starting from the outermost.  */
!   loop = loops->tree_root;
    while (1)
      {
        if (loop->inner)
--- 1422,1433 ----
  
        /* 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)
*************** fix_loop_structure (struct loops *loops,
*** 1438,1446 ****
        else
  	{
  	  while (!loop->next
! 		 && loop != loops->tree_root)
  	    loop = loop->outer;
! 	  if (loop == loops->tree_root)
  	    break;
  
  	  loop = loop->next;
--- 1435,1443 ----
        else
  	{
  	  while (!loop->next
! 		 && loop != current_loops->tree_root)
  	    loop = loop->outer;
! 	  if (loop == current_loops->tree_root)
  	    break;
  
  	  loop = loop->next;
*************** fix_loop_structure (struct loops *loops,
*** 1450,1458 ****
      }
  
    /* Now fix the loop nesting.  */
!   for (i = 1; i < loops->num; i++)
      {
!       loop = loops->parray[i];
        if (!loop)
  	continue;
  
--- 1447,1455 ----
      }
  
    /* Now fix the loop nesting.  */
!   for (i = 1; i < current_loops->num; i++)
      {
!       loop = current_loops->parray[i];
        if (!loop)
  	continue;
  
*************** fix_loop_structure (struct loops *loops,
*** 1474,1481 ****
        bb->aux = NULL;
      }
  
!   if (loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
!     mark_single_exit_loops (loops);
!   if (loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
!     mark_irreducible_loops (loops);
  }
--- 1471,1478 ----
        bb->aux = NULL;
      }
  
!   if (current_loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
!     mark_single_exit_loops ();
!   if (current_loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
!     mark_irreducible_loops ();
  }
Index: tree-ssa-loop-manip.c
===================================================================
*** tree-ssa-loop-manip.c	(revision 119131)
--- tree-ssa-loop-manip.c	(working copy)
*************** copy_phi_node_args (unsigned first_new_b
*** 562,577 ****
  
  bool
  tree_duplicate_loop_to_header_edge (struct loop *loop, edge e,
- 				    struct loops *loops,
  				    unsigned int ndupl, sbitmap wont_exit,
  				    edge orig, edge *to_remove,
  				    unsigned int *n_to_remove, int flags)
  {
    unsigned first_new_block;
  
!   if (!(loops->state & LOOPS_HAVE_SIMPLE_LATCHES))
      return false;
!   if (!(loops->state & LOOPS_HAVE_PREHEADERS))
      return false;
  
  #ifdef ENABLE_CHECKING
--- 562,576 ----
  
  bool
  tree_duplicate_loop_to_header_edge (struct loop *loop, edge e,
  				    unsigned int ndupl, sbitmap wont_exit,
  				    edge orig, edge *to_remove,
  				    unsigned int *n_to_remove, int flags)
  {
    unsigned first_new_block;
  
!   if (!(current_loops->state & LOOPS_HAVE_SIMPLE_LATCHES))
      return false;
!   if (!(current_loops->state & LOOPS_HAVE_PREHEADERS))
      return false;
  
  #ifdef ENABLE_CHECKING
*************** tree_duplicate_loop_to_header_edge (stru
*** 579,585 ****
  #endif
  
    first_new_block = last_basic_block;
!   if (!duplicate_loop_to_header_edge (loop, e, loops, ndupl, wont_exit,
  				      orig, to_remove, n_to_remove, flags))
      return false;
  
--- 578,584 ----
  #endif
  
    first_new_block = last_basic_block;
!   if (!duplicate_loop_to_header_edge (loop, e, ndupl, wont_exit,
  				      orig, to_remove, n_to_remove, flags))
      return false;
  
*************** determine_exit_conditions (struct loop *
*** 757,766 ****
    *exit_bound = bound;
  }
  
! /* Unroll LOOP FACTOR times.  LOOPS is the loops tree.  DESC describes
!    number of iterations of LOOP.  EXIT is the exit of the loop to that
!    DESC corresponds.
!    
     If N is number of iterations of the loop and MAY_BE_ZERO is the condition
     under that loop exits in the first iteration even if N != 0,
     
--- 756,764 ----
    *exit_bound = bound;
  }
  
! /* Unroll LOOP FACTOR times.  DESC describes number of iterations of LOOP.
!    EXIT is the exit of the loop to that DESC corresponds.
! 
     If N is number of iterations of the loop and MAY_BE_ZERO is the condition
     under that loop exits in the first iteration even if N != 0,
     
*************** determine_exit_conditions (struct loop *
*** 809,815 ****
       } */
  
  void
! tree_unroll_loop (struct loops *loops, struct loop *loop, unsigned factor,
  		  edge exit, struct tree_niter_desc *desc)
  {
    tree dont_exit, exit_if, ctr_before, ctr_after;
--- 807,813 ----
       } */
  
  void
! tree_unroll_loop (struct loop *loop, unsigned factor,
  		  edge exit, struct tree_niter_desc *desc)
  {
    tree dont_exit, exit_if, ctr_before, ctr_after;
*************** tree_unroll_loop (struct loops *loops, s
*** 832,838 ****
  			     &enter_main_cond, &exit_base, &exit_step,
  			     &exit_cmp, &exit_bound);
  
!   new_loop = loop_version (loops, loop, enter_main_cond, NULL, true);
    gcc_assert (new_loop != NULL);
    update_ssa (TODO_update_ssa);
  
--- 830,836 ----
  			     &enter_main_cond, &exit_base, &exit_step,
  			     &exit_cmp, &exit_bound);
  
!   new_loop = loop_version (loop, enter_main_cond, NULL, true);
    gcc_assert (new_loop != NULL);
    update_ssa (TODO_update_ssa);
  
*************** tree_unroll_loop (struct loops *loops, s
*** 855,861 ****
    wont_exit = sbitmap_alloc (factor);
    sbitmap_ones (wont_exit);
    ok = tree_duplicate_loop_to_header_edge
! 	  (loop, loop_latch_edge (loop), loops, factor - 1,
  	   wont_exit, NULL, NULL, NULL, DLTHE_FLAG_UPDATE_FREQ);
    free (wont_exit);
    gcc_assert (ok);
--- 853,859 ----
    wont_exit = sbitmap_alloc (factor);
    sbitmap_ones (wont_exit);
    ok = tree_duplicate_loop_to_header_edge
! 	  (loop, loop_latch_edge (loop), factor - 1,
  	   wont_exit, NULL, NULL, NULL, DLTHE_FLAG_UPDATE_FREQ);
    free (wont_exit);
    gcc_assert (ok);
*************** tree_unroll_loop (struct loops *loops, s
*** 926,932 ****
  #ifdef ENABLE_CHECKING
    verify_flow_info ();
    verify_dominators (CDI_DOMINATORS);
!   verify_loop_structure (loops);
    verify_loop_closed_ssa ();
  #endif
  }
--- 924,930 ----
  #ifdef ENABLE_CHECKING
    verify_flow_info ();
    verify_dominators (CDI_DOMINATORS);
!   verify_loop_structure ();
    verify_loop_closed_ssa ();
  #endif
  }
Index: tree-ssa-loop-ch.c
===================================================================
*** tree-ssa-loop-ch.c	(revision 119131)
--- tree-ssa-loop-ch.c	(working copy)
*************** copy_loop_headers (void)
*** 137,143 ****
      return 0;
  
  #ifdef ENABLE_CHECKING
!   verify_loop_structure (current_loops);
  #endif
  
    bbs = XNEWVEC (basic_block, n_basic_blocks);
--- 137,143 ----
      return 0;
  
  #ifdef ENABLE_CHECKING
!   verify_loop_structure ();
  #endif
  
    bbs = XNEWVEC (basic_block, n_basic_blocks);
Index: tree-scalar-evolution.c
===================================================================
*** tree-scalar-evolution.c	(revision 119131)
--- tree-scalar-evolution.c	(working copy)
*************** get_exit_conditions_rec (struct loop *lo
*** 1015,1024 ****
     initializes the EXIT_CONDITIONS array.  */
  
  static void
! select_loops_exit_conditions (struct loops *loops, 
! 			      VEC(tree,heap) **exit_conditions)
  {
!   struct loop *function_body = loops->parray[0];
    
    get_exit_conditions_rec (function_body->inner, exit_conditions);
  }
--- 1015,1023 ----
     initializes the EXIT_CONDITIONS array.  */
  
  static void
! select_loops_exit_conditions (VEC(tree,heap) **exit_conditions)
  {
!   struct loop *function_body = current_loops->tree_root;
    
    get_exit_conditions_rec (function_body->inner, exit_conditions);
  }
*************** initialize_scalar_evolutions_analyzer (v
*** 2745,2754 ****
  /* Initialize the analysis of scalar evolutions for LOOPS.  */
  
  void
! scev_initialize (struct loops *loops)
  {
    unsigned i;
-   current_loops = loops;
  
    scalar_evolution_info = htab_create (100, hash_scev_info,
  				       eq_scev_info, del_scev_info);
--- 2744,2752 ----
  /* Initialize the analysis of scalar evolutions for LOOPS.  */
  
  void
! scev_initialize (void)
  {
    unsigned i;
  
    scalar_evolution_info = htab_create (100, hash_scev_info,
  				       eq_scev_info, del_scev_info);
*************** scev_initialize (struct loops *loops)
*** 2756,2764 ****
    
    initialize_scalar_evolutions_analyzer ();
  
!   for (i = 1; i < loops->num; i++)
!     if (loops->parray[i])
!       loops->parray[i]->nb_iterations = NULL_TREE;
  }
  
  /* Cleans up the information cached by the scalar evolutions analysis.  */
--- 2754,2762 ----
    
    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.  */
*************** scev_analysis (void)
*** 2850,2856 ****
    VEC(tree,heap) *exit_conditions;
    
    exit_conditions = VEC_alloc (tree, heap, 37);
!   select_loops_exit_conditions (current_loops, &exit_conditions);
  
    if (dump_file && (dump_flags & TDF_STATS))
      analyze_scalar_evolution_for_all_loop_phi_nodes (&exit_conditions);
--- 2848,2854 ----
    VEC(tree,heap) *exit_conditions;
    
    exit_conditions = VEC_alloc (tree, heap, 37);
!   select_loops_exit_conditions (&exit_conditions);
  
    if (dump_file && (dump_flags & TDF_STATS))
      analyze_scalar_evolution_for_all_loop_phi_nodes (&exit_conditions);
Index: tree-scalar-evolution.h
===================================================================
*** tree-scalar-evolution.h	(revision 119131)
--- tree-scalar-evolution.h	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 25,31 ****
  extern tree number_of_iterations_in_loop (struct loop *);
  extern tree get_loop_exit_condition (struct loop *);
  
! extern void scev_initialize (struct loops *loops);
  extern void scev_reset (void);
  extern void scev_finalize (void);
  extern tree analyze_scalar_evolution (struct loop *, tree);
--- 25,31 ----
  extern tree number_of_iterations_in_loop (struct loop *);
  extern tree get_loop_exit_condition (struct loop *);
  
! extern void scev_initialize (void);
  extern void scev_reset (void);
  extern void scev_finalize (void);
  extern tree analyze_scalar_evolution (struct loop *, tree);
Index: cfghooks.c
===================================================================
*** cfghooks.c	(revision 119131)
--- cfghooks.c	(working copy)
*************** lv_flush_pending_stmts (edge e)
*** 937,949 ****
     than duplicate_loop_to_header_edge when we are in tree mode.  */
  bool
  cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge e,
! 					struct loops *loops, unsigned int ndupl,
  					sbitmap wont_exit, edge orig,
  					edge *to_remove,
  					unsigned int *n_to_remove, int flags)
  {
    gcc_assert (cfg_hooks->cfg_hook_duplicate_loop_to_header_edge);
!   return cfg_hooks->cfg_hook_duplicate_loop_to_header_edge (loop, e, loops,
  							    ndupl, wont_exit,
  							    orig, to_remove,
  							    n_to_remove, flags);
--- 937,949 ----
     than duplicate_loop_to_header_edge when we are in tree mode.  */
  bool
  cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge e,
! 					unsigned int ndupl,
  					sbitmap wont_exit, edge orig,
  					edge *to_remove,
  					unsigned int *n_to_remove, int flags)
  {
    gcc_assert (cfg_hooks->cfg_hook_duplicate_loop_to_header_edge);
!   return cfg_hooks->cfg_hook_duplicate_loop_to_header_edge (loop, e,
  							    ndupl, wont_exit,
  							    orig, to_remove,
  							    n_to_remove, flags);
Index: cfghooks.h
===================================================================
*** cfghooks.h	(revision 119131)
--- cfghooks.h	(working copy)
*************** struct cfg_hooks
*** 112,118 ****
    /* A hook for duplicating loop in CFG, currently this is used
       in loop versioning.  */
    bool (*cfg_hook_duplicate_loop_to_header_edge) (struct loop *loop, edge e,
- 						  struct loops *loops,
  						  unsigned int ndupl,
  						  sbitmap wont_exit,
  						  edge orig, edge *to_remove,
--- 112,117 ----
*************** extern int flow_call_edges_add (sbitmap)
*** 164,170 ****
  extern void execute_on_growing_pred (edge);
  extern void execute_on_shrinking_pred (edge);
  extern bool cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge,
- 						    struct loops *loops,
  						    unsigned int ndupl,
  						    sbitmap wont_exit,
  						    edge orig, edge *to_remove,
--- 163,168 ----
Index: cfgloopanal.c
===================================================================
*** cfgloopanal.c	(revision 119131)
--- cfgloopanal.c	(working copy)
*************** free_graph (struct graph *g)
*** 266,279 ****
  #define BB_REPR(BB) ((BB)->index + 1)
  
  void
! mark_irreducible_loops (struct loops *loops)
  {
    basic_block act;
    edge e;
    edge_iterator ei;
    int i, src, dest;
    struct graph *g;
!   int num = loops ? loops->num : 1;
    int *queue1 = XNEWVEC (int, last_basic_block + num);
    int *queue2 = XNEWVEC (int, last_basic_block + num);
    int nq, depth;
--- 266,279 ----
  #define BB_REPR(BB) ((BB)->index + 1)
  
  void
! mark_irreducible_loops (void)
  {
    basic_block act;
    edge e;
    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;
*************** mark_irreducible_loops (struct loops *lo
*** 300,306 ****
  	src = BB_REPR (act);
  	dest = BB_REPR (e->dest);
  
! 	if (loops)
  	  {
  	    /* Ignore latch edges.  */
  	    if (e->dest->loop_father->header == e->dest
--- 300,306 ----
  	src = BB_REPR (act);
  	dest = BB_REPR (e->dest);
  
! 	if (current_loops)
  	  {
  	    /* Ignore latch edges.  */
  	    if (e->dest->loop_father->header == e->dest
*************** mark_irreducible_loops (struct loops *lo
*** 344,351 ****
        queue1[nq++] = BB_REPR (act);
      }
    for (i = 1; i < num; i++)
!     if (loops->parray[i])
!       queue1[nq++] = LOOP_REPR (loops->parray[i]);
    dfs (g, queue1, nq, queue2, false);
    for (i = 0; i < nq; i++)
      queue1[i] = queue2[nq - i - 1];
--- 344,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];
*************** mark_irreducible_loops (struct loops *lo
*** 358,365 ****
    free (queue1);
    free (queue2);
  
!   if (loops)
!     loops->state |= LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS;
  }
  
  /* Counts number of insns inside LOOP.  */
--- 358,365 ----
    free (queue1);
    free (queue2);
  
!   if (current_loops)
!     current_loops->state |= LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS;
  }
  
  /* Counts number of insns inside LOOP.  */
*************** global_cost_for_size (unsigned size, uns
*** 572,586 ****
    return cost;
  }
  
! /* Sets EDGE_LOOP_EXIT flag for all exits of LOOPS.  */
  
  void
! mark_loop_exit_edges (struct loops *loops)
  {
    basic_block bb;
    edge e;
  
!   if (loops->num <= 1)
      return;
  
    FOR_EACH_BB (bb)
--- 572,586 ----
    return cost;
  }
  
! /* Sets EDGE_LOOP_EXIT flag for all loop exits.  */
  
  void
! mark_loop_exit_edges (void)
  {
    basic_block bb;
    edge e;
  
!   if (!current_loops)
      return;
  
    FOR_EACH_BB (bb)
Index: tree-ssa-loop-ivopts.c
===================================================================
*** tree-ssa-loop-ivopts.c	(revision 119131)
--- tree-ssa-loop-ivopts.c	(working copy)
*************** finish:
*** 5878,5887 ****
    return changed;
  }
  
! /* Main entry point.  Optimizes induction variables in LOOPS.  */
  
  void
! tree_ssa_iv_optimize (struct loops *loops)
  {
    struct loop *loop;
    struct ivopts_data data;
--- 5878,5887 ----
    return changed;
  }
  
! /* Main entry point.  Optimizes induction variables in loops.  */
  
  void
! tree_ssa_iv_optimize (void)
  {
    struct loop *loop;
    struct ivopts_data data;
*************** tree_ssa_iv_optimize (struct loops *loop
*** 5889,5900 ****
    tree_ssa_iv_optimize_init (&data);
  
    /* Optimize the loops starting with the innermost ones.  */
!   loop = loops->tree_root;
    while (loop->inner)
      loop = loop->inner;
  
    /* Scan the loops, inner ones first.  */
!   while (loop != loops->tree_root)
      {
        if (dump_file && (dump_flags & TDF_DETAILS))
  	flow_loop_dump (loop, dump_file, NULL, 1);
--- 5889,5900 ----
    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);
Index: modulo-sched.c
===================================================================
*** modulo-sched.c	(revision 119131)
--- modulo-sched.c	(working copy)
*************** sms_schedule (void)
*** 1176,1183 ****
  		  rtx comp_rtx = gen_rtx_fmt_ee (GT, VOIDmode, count_reg,
  						 GEN_INT(stage_count));
  
! 		  nloop = loop_version (current_loops, loop, comp_rtx,
! 					&condition_bb, true);
  		}
  
  	      /* Set new iteration count of loop kernel.  */
--- 1176,1182 ----
  		  rtx comp_rtx = gen_rtx_fmt_ee (GT, VOIDmode, count_reg,
  						 GEN_INT(stage_count));
  
! 		  nloop = loop_version (loop, comp_rtx, &condition_bb, true);
  		}
  
  	      /* Set new iteration count of loop kernel.  */
Index: tree-ssa-dom.c
===================================================================
*** tree-ssa-dom.c	(revision 119131)
--- tree-ssa-dom.c	(working copy)
*************** tree_ssa_dominator_optimize (void)
*** 278,284 ****
    loop_optimizer_init (0);
    if (current_loops)
      {
!       mark_loop_exit_edges (current_loops);
        loop_optimizer_finalize ();
      }
  
--- 278,284 ----
    loop_optimizer_init (0);
    if (current_loops)
      {
!       mark_loop_exit_edges ();
        loop_optimizer_finalize ();
      }
  
Index: loop-init.c
===================================================================
*** loop-init.c	(revision 119131)
--- loop-init.c	(working copy)
*************** loop_optimizer_init (unsigned flags)
*** 77,101 ****
  
    /* Create pre-headers.  */
    if (flags & LOOPS_HAVE_PREHEADERS)
!     create_preheaders (current_loops, CP_SIMPLE_PREHEADERS);
  
    /* Force all latches to have only single successor.  */
    if (flags & LOOPS_HAVE_SIMPLE_LATCHES)
!     force_single_succ_latches (current_loops);
  
    /* Mark irreducible loops.  */
    if (flags & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
!     mark_irreducible_loops (current_loops);
  
    if (flags & LOOPS_HAVE_MARKED_SINGLE_EXITS)
!     mark_single_exit_loops (current_loops);
  
    /* Dump loops.  */
!   flow_loops_dump (current_loops, dump_file, NULL, 1);
  
  #ifdef ENABLE_CHECKING
    verify_dominators (CDI_DOMINATORS);
!   verify_loop_structure (current_loops);
  #endif
  }
  
--- 77,101 ----
  
    /* Create pre-headers.  */
    if (flags & LOOPS_HAVE_PREHEADERS)
!     create_preheaders (CP_SIMPLE_PREHEADERS);
  
    /* Force all latches to have only single successor.  */
    if (flags & LOOPS_HAVE_SIMPLE_LATCHES)
!     force_single_succ_latches ();
  
    /* Mark irreducible loops.  */
    if (flags & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
!     mark_irreducible_loops ();
  
    if (flags & LOOPS_HAVE_MARKED_SINGLE_EXITS)
!     mark_single_exit_loops ();
  
    /* Dump loops.  */
!   flow_loops_dump (dump_file, NULL, 1);
  
  #ifdef ENABLE_CHECKING
    verify_dominators (CDI_DOMINATORS);
!   verify_loop_structure ();
  #endif
  }
  
*************** static unsigned int
*** 253,259 ****
  rtl_move_loop_invariants (void)
  {
    if (current_loops)
!     move_loop_invariants (current_loops);
    return 0;
  }
  
--- 253,259 ----
  rtl_move_loop_invariants (void)
  {
    if (current_loops)
!     move_loop_invariants ();
    return 0;
  }
  
*************** static unsigned int
*** 286,292 ****
  rtl_unswitch (void)
  {
    if (current_loops)
!     unswitch_loops (current_loops);
    return 0;
  }
  
--- 286,292 ----
  rtl_unswitch (void)
  {
    if (current_loops)
!     unswitch_loops ();
    return 0;
  }
  
*************** rtl_unroll_and_peel_loops (void)
*** 329,335 ****
        if (flag_unroll_all_loops)
  	flags |= UAP_UNROLL_ALL;
  
!       unroll_and_peel_loops (current_loops, flags);
      }
    return 0;
  }
--- 329,335 ----
        if (flag_unroll_all_loops)
  	flags |= UAP_UNROLL_ALL;
  
!       unroll_and_peel_loops (flags);
      }
    return 0;
  }
*************** rtl_doloop (void)
*** 368,374 ****
  {
  #ifdef HAVE_doloop_end
    if (current_loops)
!     doloop_optimize_loops (current_loops);
  #endif
    return 0;
  }
--- 368,374 ----
  {
  #ifdef HAVE_doloop_end
    if (current_loops)
!     doloop_optimize_loops ();
  #endif
    return 0;
  }
Index: ifcvt.c
===================================================================
*** ifcvt.c	(revision 119131)
--- ifcvt.c	(working copy)
*************** if_convert (int x_life_data_ok)
*** 3857,3863 ****
        loop_optimizer_init (0);
        if (current_loops)
  	{
! 	  mark_loop_exit_edges (current_loops);
  	  loop_optimizer_finalize ();
  	}
        free_dominance_info (CDI_DOMINATORS);
--- 3857,3863 ----
        loop_optimizer_init (0);
        if (current_loops)
  	{
! 	  mark_loop_exit_edges ();
  	  loop_optimizer_finalize ();
  	}
        free_dominance_info (CDI_DOMINATORS);
Index: tree-ssa-loop-ivcanon.c
===================================================================
*** tree-ssa-loop-ivcanon.c	(revision 119131)
--- tree-ssa-loop-ivcanon.c	(working copy)
*************** estimated_unrolled_size (unsigned HOST_W
*** 154,166 ****
    return unr_insns;
  }
  
! /* Tries to unroll LOOP completely, i.e. NITER times.  LOOPS is the
!    loop tree.  UL determines which loops we are allowed to unroll. 
     EXIT is the exit of the loop that should be eliminated.  */
  
  static bool
! try_unroll_loop_completely (struct loops *loops ATTRIBUTE_UNUSED,
! 			    struct loop *loop,
  			    edge exit, tree niter,
  			    enum unroll_level ul)
  {
--- 154,165 ----
    return unr_insns;
  }
  
! /* Tries to unroll LOOP completely, i.e. NITER times.
!    UL determines which loops we are allowed to unroll. 
     EXIT is the exit of the loop that should be eliminated.  */
  
  static bool
! try_unroll_loop_completely (struct loop *loop,
  			    edge exit, tree niter,
  			    enum unroll_level ul)
  {
*************** try_unroll_loop_completely (struct loops
*** 237,243 ****
        RESET_BIT (wont_exit, 0);
  
        if (!tree_duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 					       loops, n_unroll, wont_exit,
  					       exit, edges_to_remove,
  					       &n_to_remove,
  					       DLTHE_FLAG_UPDATE_FREQ
--- 236,242 ----
        RESET_BIT (wont_exit, 0);
  
        if (!tree_duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 					       n_unroll, wont_exit,
  					       exit, edges_to_remove,
  					       &n_to_remove,
  					       DLTHE_FLAG_UPDATE_FREQ
*************** try_unroll_loop_completely (struct loops
*** 266,279 ****
    return true;
  }
  
! /* Adds a canonical induction variable to LOOP if suitable.  LOOPS is the loops
!    tree.  CREATE_IV is true if we may create a new iv.  UL determines 
     which loops we are allowed to completely unroll.  If TRY_EVAL is true, we try
     to determine the number of iterations of a loop by direct evaluation. 
     Returns true if cfg is changed.  */
  
  static bool
! canonicalize_loop_induction_variables (struct loops *loops, struct loop *loop,
  				       bool create_iv, enum unroll_level ul,
  				       bool try_eval)
  {
--- 265,278 ----
    return true;
  }
  
! /* Adds a canonical induction variable to LOOP if suitable.
!    CREATE_IV is true if we may create a new iv.  UL determines 
     which loops we are allowed to completely unroll.  If TRY_EVAL is true, we try
     to determine the number of iterations of a loop by direct evaluation. 
     Returns true if cfg is changed.  */
  
  static bool
! canonicalize_loop_induction_variables (struct loop *loop,
  				       bool create_iv, enum unroll_level ul,
  				       bool try_eval)
  {
*************** canonicalize_loop_induction_variables (s
*** 318,324 ****
        fprintf (dump_file, " times.\n");
      }
  
!   if (try_unroll_loop_completely (loops, loop, exit, niter, ul))
      return true;
  
    if (create_iv)
--- 317,323 ----
        fprintf (dump_file, " times.\n");
      }
  
!   if (try_unroll_loop_completely (loop, exit, niter, ul))
      return true;
  
    if (create_iv)
*************** canonicalize_loop_induction_variables (s
*** 328,348 ****
  }
  
  /* The main entry point of the pass.  Adds canonical induction variables
!    to the suitable LOOPS.  */
  
  unsigned int
! canonicalize_induction_variables (struct loops *loops)
  {
    unsigned i;
    struct loop *loop;
    bool changed = false;
    
!   for (i = 1; i < loops->num; i++)
      {
!       loop = loops->parray[i];
  
        if (loop)
! 	changed |= canonicalize_loop_induction_variables (loops, loop,
  							  true, UL_SINGLE_ITER,
  							  true);
      }
--- 327,347 ----
  }
  
  /* The main entry point of the pass.  Adds canonical induction variables
!    to the suitable loops.  */
  
  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);
      }
*************** canonicalize_induction_variables (struct
*** 361,376 ****
     size of the code does not increase.  */
  
  unsigned int
! tree_unroll_loops_completely (struct loops *loops, bool may_increase_size)
  {
    unsigned i;
    struct loop *loop;
    bool changed = false;
    enum unroll_level ul;
  
!   for (i = 1; i < loops->num; i++)
      {
!       loop = loops->parray[i];
  
        if (!loop)
  	continue;
--- 360,375 ----
     size of the code does not increase.  */
  
  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;
*************** tree_unroll_loops_completely (struct loo
*** 379,385 ****
  	ul = UL_ALL;
        else
  	ul = UL_NO_GROWTH;
!       changed |= canonicalize_loop_induction_variables (loops, loop,
  							false, ul,
  							!flag_tree_loop_ivcanon);
      }
--- 378,384 ----
  	ul = UL_ALL;
        else
  	ul = UL_NO_GROWTH;
!       changed |= canonicalize_loop_induction_variables (loop,
  							false, ul,
  							!flag_tree_loop_ivcanon);
      }
*************** try_remove_empty_loop (struct loop *loop
*** 562,576 ****
    return true;
  }
  
! /* Remove the empty LOOPS.  */
  
  unsigned int
! remove_empty_loops (struct loops *loops)
  {
    bool changed = false;
    struct loop *loop;
  
!   for (loop = loops->tree_root->inner; loop; loop = loop->next)
      try_remove_empty_loop (loop, &changed);
  
    if (changed)
--- 561,575 ----
    return true;
  }
  
! /* Remove the empty loops.  */
  
  unsigned int
! remove_empty_loops (void)
  {
    bool changed = false;
    struct loop *loop;
  
!   for (loop = current_loops->tree_root->inner; loop; loop = loop->next)
      try_remove_empty_loop (loop, &changed);
  
    if (changed)
Index: tree-ssa-loop.c
===================================================================
*** tree-ssa-loop.c	(revision 119131)
--- tree-ssa-loop.c	(working copy)
*************** tree_ssa_loop_init (void)
*** 85,91 ****
    if (!current_loops)
      return 0;
  
!   scev_initialize (current_loops);
    return 0;
  }
    
--- 85,91 ----
    if (!current_loops)
      return 0;
  
!   scev_initialize ();
    return 0;
  }
    
*************** tree_ssa_loop_im (void)
*** 114,120 ****
    if (!current_loops)
      return 0;
  
!   tree_ssa_lim (current_loops);
    return 0;
  }
  
--- 114,120 ----
    if (!current_loops)
      return 0;
  
!   tree_ssa_lim ();
    return 0;
  }
  
*************** tree_ssa_loop_unswitch (void)
*** 149,155 ****
    if (!current_loops)
      return 0;
  
!   return tree_ssa_unswitch_loops (current_loops);
  }
  
  static bool
--- 149,155 ----
    if (!current_loops)
      return 0;
  
!   return tree_ssa_unswitch_loops ();
  }
  
  static bool
*************** struct tree_opt_pass pass_tree_unswitch 
*** 180,186 ****
  static unsigned int
  tree_vectorize (void)
  {
!   return vectorize_loops (current_loops);
  }
  
  static bool
--- 180,186 ----
  static unsigned int
  tree_vectorize (void)
  {
!   return vectorize_loops ();
  }
  
  static bool
*************** tree_linear_transform (void)
*** 214,220 ****
    if (!current_loops)
      return 0;
  
!   linear_transform_loops (current_loops);
    return 0;
  }
  
--- 214,220 ----
    if (!current_loops)
      return 0;
  
!   linear_transform_loops ();
    return 0;
  }
  
*************** tree_ssa_loop_ivcanon (void)
*** 249,255 ****
    if (!current_loops)
      return 0;
  
!   return canonicalize_induction_variables (current_loops);
  }
  
  static bool
--- 249,255 ----
    if (!current_loops)
      return 0;
  
!   return canonicalize_induction_variables ();
  }
  
  static bool
*************** tree_ssa_empty_loop (void)
*** 310,316 ****
    if (!current_loops)
      return 0;
  
!   return remove_empty_loops (current_loops);
  }
  
  struct tree_opt_pass pass_empty_loop =
--- 310,316 ----
    if (!current_loops)
      return 0;
  
!   return remove_empty_loops ();
  }
  
  struct tree_opt_pass pass_empty_loop =
*************** tree_ssa_loop_bounds (void)
*** 338,344 ****
    if (!current_loops)
      return 0;
  
!   estimate_numbers_of_iterations (current_loops);
    scev_reset ();
    return 0;
  }
--- 338,344 ----
    if (!current_loops)
      return 0;
  
!   estimate_numbers_of_iterations ();
    scev_reset ();
    return 0;
  }
*************** tree_complete_unroll (void)
*** 368,377 ****
    if (!current_loops)
      return 0;
  
!   return tree_unroll_loops_completely (current_loops,
! 				       flag_unroll_loops
! 					|| flag_peel_loops
! 					|| optimize >= 3);
  }
  
  static bool
--- 368,376 ----
    if (!current_loops)
      return 0;
  
!   return tree_unroll_loops_completely (flag_unroll_loops
! 				       || flag_peel_loops
! 				       || optimize >= 3);
  }
  
  static bool
*************** tree_ssa_loop_prefetch (void)
*** 405,411 ****
    if (!current_loops)
      return 0;
  
!   return tree_ssa_prefetch_arrays (current_loops);
  }
  
  static bool
--- 404,410 ----
    if (!current_loops)
      return 0;
  
!   return tree_ssa_prefetch_arrays ();
  }
  
  static bool
*************** tree_ssa_loop_ivopts (void)
*** 439,445 ****
    if (!current_loops)
      return 0;
  
!   tree_ssa_iv_optimize (current_loops);
    return 0;
  }
  
--- 438,444 ----
    if (!current_loops)
      return 0;
  
!   tree_ssa_iv_optimize ();
    return 0;
  }
  
*************** tree_ssa_loop_done (void)
*** 476,482 ****
    if (!current_loops)
      return 0;
  
!   free_numbers_of_iterations_estimates (current_loops);
    scev_finalize ();
    loop_optimizer_finalize ();
    return 0;
--- 475,481 ----
    if (!current_loops)
      return 0;
  
!   free_numbers_of_iterations_estimates ();
    scev_finalize ();
    loop_optimizer_finalize ();
    return 0;
Index: predict.c
===================================================================
*** predict.c	(revision 119131)
--- predict.c	(working copy)
*************** static sreal real_zero, real_one, real_a
*** 74,85 ****
  
  static void combine_predictions_for_insn (rtx, basic_block);
  static void dump_prediction (FILE *, enum br_predictor, int, basic_block, int);
- static void estimate_bb_frequencies (struct loops *);
  static void predict_paths_leading_to (basic_block, int *, enum br_predictor, enum prediction);
  static bool last_basic_block_p (basic_block);
  static void compute_function_frequency (void);
  static void choose_function_section (void);
  static bool can_predict_insn_p (rtx);
  
  /* Information we hold about each branch predictor.
     Filled using information from predict.def.  */
--- 74,85 ----
  
  static void combine_predictions_for_insn (rtx, basic_block);
  static void dump_prediction (FILE *, enum br_predictor, int, basic_block, int);
  static void predict_paths_leading_to (basic_block, int *, enum br_predictor, enum prediction);
  static bool last_basic_block_p (basic_block);
  static void compute_function_frequency (void);
  static void choose_function_section (void);
  static bool can_predict_insn_p (rtx);
+ static void estimate_bb_frequencies (void);
  
  /* Information we hold about each branch predictor.
     Filled using information from predict.def.  */
*************** combine_predictions_for_bb (basic_block 
*** 625,647 ****
      }
  }
  
! /* Predict edge probabilities by exploiting loop structure.
!    When RTLSIMPLELOOPS is set, attempt to count number of iterations by analyzing
!    RTL otherwise use tree based approach.  */
  static void
! predict_loops (struct loops *loops_info)
  {
    unsigned i;
  
!   scev_initialize (loops_info);
  
    /* Try to predict out blocks in a loop that are not part of a
       natural loop.  */
!   for (i = 1; i < loops_info->num; i++)
      {
        basic_block bb, *bbs;
        unsigned j, n_exits;
!       struct loop *loop = loops_info->parray[i];
        VEC (edge, heap) *exits;
        struct tree_niter_desc niter_desc;
        edge ex;
--- 625,646 ----
      }
  }
  
! /* Predict edge probabilities by exploiting loop structure.  */
! 
  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;
*************** tree_estimate_probability (void)
*** 1252,1258 ****
  
    loop_optimizer_init (0);
    if (current_loops && dump_file && (dump_flags & TDF_DETAILS))
!     flow_loops_dump (current_loops, dump_file, NULL, 0);
  
    add_noreturn_fake_exit_edges ();
    connect_infinite_loops_to_exit ();
--- 1251,1257 ----
  
    loop_optimizer_init (0);
    if (current_loops && dump_file && (dump_flags & TDF_DETAILS))
!     flow_loops_dump (dump_file, NULL, 0);
  
    add_noreturn_fake_exit_edges ();
    connect_infinite_loops_to_exit ();
*************** tree_estimate_probability (void)
*** 1261,1269 ****
  
    tree_bb_level_predictions ();
  
!   mark_irreducible_loops (current_loops);
    if (current_loops)
!     predict_loops (current_loops);
  
    FOR_EACH_BB (bb)
      {
--- 1260,1268 ----
  
    tree_bb_level_predictions ();
  
!   mark_irreducible_loops ();
    if (current_loops)
!     predict_loops ();
  
    FOR_EACH_BB (bb)
      {
*************** tree_estimate_probability (void)
*** 1325,1331 ****
      combine_predictions_for_bb (bb);
  
    strip_builtin_expect ();
!   estimate_bb_frequencies (current_loops);
    free_dominance_info (CDI_POST_DOMINATORS);
    remove_fake_exit_edges ();
    loop_optimizer_finalize ();
--- 1324,1330 ----
      combine_predictions_for_bb (bb);
  
    strip_builtin_expect ();
!   estimate_bb_frequencies ();
    free_dominance_info (CDI_POST_DOMINATORS);
    remove_fake_exit_edges ();
    loop_optimizer_finalize ();
*************** estimate_loops_at_level (struct loop *fi
*** 1602,1618 ****
      }
  }
  
! /* Propates frequencies through structure of LOOPS.  */
  
  static void
! estimate_loops (struct loops *loops)
  {
    bitmap tovisit = BITMAP_ALLOC (NULL);
    basic_block bb;
  
    /* Start by estimating the frequencies in the loops.  */
!   if (loops)
!     estimate_loops_at_level (loops->tree_root->inner);
  
    /* Now propagate the frequencies through all the blocks.  */
    FOR_ALL_BB (bb)
--- 1601,1617 ----
      }
  }
  
! /* Propates frequencies through structure of loops.  */
  
  static void
! estimate_loops (void)
  {
    bitmap tovisit = BITMAP_ALLOC (NULL);
    basic_block bb;
  
    /* Start by estimating the frequencies in the loops.  */
!   if (current_loops)
!     estimate_loops_at_level (current_loops->tree_root->inner);
  
    /* Now propagate the frequencies through all the blocks.  */
    FOR_ALL_BB (bb)
*************** expensive_function_p (int threshold)
*** 1685,1691 ****
  /* Estimate basic blocks frequency by given branch probabilities.  */
  
  static void
! estimate_bb_frequencies (struct loops *loops)
  {
    basic_block bb;
    sreal freq_max;
--- 1684,1690 ----
  /* Estimate basic blocks frequency by given branch probabilities.  */
  
  static void
! estimate_bb_frequencies (void)
  {
    basic_block bb;
    sreal freq_max;
*************** estimate_bb_frequencies (struct loops *l
*** 1729,1735 ****
  
        /* First compute probabilities locally for each loop from innermost
           to outermost to examine probabilities for back edges.  */
!       estimate_loops (loops);
  
        memcpy (&freq_max, &real_zero, sizeof (real_zero));
        FOR_EACH_BB (bb)
--- 1728,1734 ----
  
        /* First compute probabilities locally for each loop from innermost
           to outermost to examine probabilities for back edges.  */
!       estimate_loops ();
  
        memcpy (&freq_max, &real_zero, sizeof (real_zero));
        FOR_EACH_BB (bb)
Index: tree-vectorizer.c
===================================================================
*** tree-vectorizer.c	(revision 119131)
--- tree-vectorizer.c	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 150,157 ****
  /*************************************************************************
    Simple Loop Peeling Utilities
   *************************************************************************/
- static struct loop *slpeel_tree_duplicate_loop_to_edge_cfg 
-   (struct loop *, struct loops *, edge);
  static void slpeel_update_phis_for_duplicate_loop 
    (struct loop *, struct loop *, bool after);
  static void slpeel_update_phi_nodes_for_guard1 
--- 150,155 ----
*************** slpeel_make_loop_iterate_ntimes (struct 
*** 823,830 ****
     on E which is either the entry or exit of LOOP.  */
  
  static struct loop *
! slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, struct loops *loops, 
! 					edge e)
  {
    struct loop *new_loop;
    basic_block *new_bbs, *bbs;
--- 821,827 ----
     on E which is either the entry or exit of LOOP.  */
  
  static struct loop *
! slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, edge e)
  {
    struct loop *new_loop;
    basic_block *new_bbs, *bbs;
*************** slpeel_tree_duplicate_loop_to_edge_cfg (
*** 848,854 ****
      }
  
    /* Generate new loop structure.  */
!   new_loop = duplicate_loop (loops, loop, loop->outer);
    if (!new_loop)
      {
        free (bbs);
--- 845,851 ----
      }
  
    /* Generate new loop structure.  */
!   new_loop = duplicate_loop (loop, loop->outer);
    if (!new_loop)
      {
        free (bbs);
*************** slpeel_verify_cfg_after_peeling (struct 
*** 1067,1073 ****
  */
  
  struct loop*
! slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops, 
  			       edge e, tree first_niters, 
  			       tree niters, bool update_first_loop_count)
  {
--- 1064,1070 ----
  */
  
  struct loop*
! slpeel_tree_peel_loop_to_edge (struct loop *loop, 
  			       edge e, tree first_niters, 
  			       tree niters, bool update_first_loop_count)
  {
*************** slpeel_tree_peel_loop_to_edge (struct lo
*** 1106,1112 ****
          orig_exit_bb:
     */
    
!   if (!(new_loop = slpeel_tree_duplicate_loop_to_edge_cfg (loop, loops, e)))
      {
        loop_loc = find_loop_location (loop);
        if (dump_file && (dump_flags & TDF_DETAILS))
--- 1103,1109 ----
          orig_exit_bb:
     */
    
!   if (!(new_loop = slpeel_tree_duplicate_loop_to_edge_cfg (loop, e)))
      {
        loop_loc = find_loop_location (loop);
        if (dump_file && (dump_flags & TDF_DETAILS))
*************** vect_is_simple_iv_evolution (unsigned lo
*** 2156,2162 ****
     Entry Point to loop vectorization phase.  */
  
  unsigned
! vectorize_loops (struct loops *loops)
  {
    unsigned int i;
    unsigned int num_vectorized_loops = 0;
--- 2153,2159 ----
     Entry Point to loop vectorization phase.  */
  
  unsigned
! vectorize_loops (void)
  {
    unsigned int i;
    unsigned int num_vectorized_loops = 0;
*************** vectorize_loops (struct loops *loops)
*** 2173,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 = loops->num;
    for (i = 1; i < vect_loops_num; i++)
      {
        loop_vec_info loop_vinfo;
!       struct loop *loop = loops->parray[i];
  
        if (!loop)
          continue;
--- 2170,2180 ----
    /* 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;
*************** vectorize_loops (struct loops *loops)
*** 2189,2195 ****
        if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo))
  	continue;
  
!       vect_transform_loop (loop_vinfo, loops);
        num_vectorized_loops++;
      }
    vect_loop_location = UNKNOWN_LOC;
--- 2186,2192 ----
        if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo))
  	continue;
  
!       vect_transform_loop (loop_vinfo);
        num_vectorized_loops++;
      }
    vect_loop_location = UNKNOWN_LOC;
*************** vectorize_loops (struct loops *loops)
*** 2204,2210 ****
  
    for (i = 1; i < vect_loops_num; i++)
      {
!       struct loop *loop = loops->parray[i];
        loop_vec_info loop_vinfo;
  
        if (!loop)
--- 2201,2207 ----
  
    for (i = 1; i < vect_loops_num; i++)
      {
!       struct loop *loop = current_loops->parray[i];
        loop_vec_info loop_vinfo;
  
        if (!loop)
Index: tree-vectorizer.h
===================================================================
*** tree-vectorizer.h	(revision 119131)
--- tree-vectorizer.h	(working copy)
*************** extern bitmap vect_vnames_to_rename;
*** 347,353 ****
     divide by the vectorization factor, and to peel the first few iterations
     to force the alignment of data references in the loop.  */
  extern struct loop *slpeel_tree_peel_loop_to_edge 
!   (struct loop *, struct loops *, edge, tree, tree, bool);
  extern void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
  extern bool slpeel_can_duplicate_loop_p (struct loop *, edge);
  #ifdef ENABLE_CHECKING
--- 347,353 ----
     divide by the vectorization factor, and to peel the first few iterations
     to force the alignment of data references in the loop.  */
  extern struct loop *slpeel_tree_peel_loop_to_edge 
!   (struct loop *, edge, tree, tree, bool);
  extern void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
  extern bool slpeel_can_duplicate_loop_p (struct loop *, edge);
  #ifdef ENABLE_CHECKING
*************** extern bool vectorizable_condition (tree
*** 401,407 ****
  extern bool vectorizable_live_operation (tree, block_stmt_iterator *, tree *);
  extern bool vectorizable_reduction (tree, block_stmt_iterator *, tree *);
  /* Driver for transformation stage.  */
! extern void vect_transform_loop (loop_vec_info, struct loops *);
  
  /*************************************************************************
    Vectorization Debug Information - in tree-vectorizer.c
--- 401,407 ----
  extern bool vectorizable_live_operation (tree, block_stmt_iterator *, tree *);
  extern bool vectorizable_reduction (tree, block_stmt_iterator *, tree *);
  /* Driver for transformation stage.  */
! extern void vect_transform_loop (loop_vec_info);
  
  /*************************************************************************
    Vectorization Debug Information - in tree-vectorizer.c
Index: loop-unroll.c
===================================================================
*** loop-unroll.c	(revision 119131)
--- loop-unroll.c	(working copy)
*************** struct opt_info
*** 114,132 ****
    basic_block loop_preheader;      /* The loop preheader basic block.  */
  };
  
! static void decide_unrolling_and_peeling (struct loops *, int);
! static void peel_loops_completely (struct loops *, int);
  static void decide_peel_simple (struct loop *, int);
  static void decide_peel_once_rolling (struct loop *, int);
  static void decide_peel_completely (struct loop *, int);
  static void decide_unroll_stupid (struct loop *, int);
  static void decide_unroll_constant_iterations (struct loop *, int);
  static void decide_unroll_runtime_iterations (struct loop *, int);
! static void peel_loop_simple (struct loops *, struct loop *);
! static void peel_loop_completely (struct loops *, struct loop *);
! static void unroll_loop_stupid (struct loops *, struct loop *);
! static void unroll_loop_constant_iterations (struct loops *, struct loop *);
! static void unroll_loop_runtime_iterations (struct loops *, struct loop *);
  static struct opt_info *analyze_insns_in_loop (struct loop *);
  static void opt_info_start_duplication (struct opt_info *);
  static void apply_opt_in_copies (struct opt_info *, unsigned, bool, bool);
--- 114,132 ----
    basic_block loop_preheader;      /* The loop preheader basic block.  */
  };
  
! static void decide_unrolling_and_peeling (int);
! static void peel_loops_completely (int);
  static void decide_peel_simple (struct loop *, int);
  static void decide_peel_once_rolling (struct loop *, int);
  static void decide_peel_completely (struct loop *, int);
  static void decide_unroll_stupid (struct loop *, int);
  static void decide_unroll_constant_iterations (struct loop *, int);
  static void decide_unroll_runtime_iterations (struct loop *, int);
! static void peel_loop_simple (struct loop *);
! static void peel_loop_completely (struct loop *);
! static void unroll_loop_stupid (struct loop *);
! static void unroll_loop_constant_iterations (struct loop *);
! static void unroll_loop_runtime_iterations (struct loop *);
  static struct opt_info *analyze_insns_in_loop (struct loop *);
  static void opt_info_start_duplication (struct opt_info *);
  static void apply_opt_in_copies (struct opt_info *, unsigned, bool, bool);
*************** static rtx get_expansion (struct var_to_
*** 142,165 ****
  
  /* Unroll and/or peel (depending on FLAGS) LOOPS.  */
  void
! unroll_and_peel_loops (struct loops *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).  */
!   peel_loops_completely (loops, flags);
  
    /* Now decide rest of unrolling and peeling.  */
!   decide_unrolling_and_peeling (loops, flags);
  
!   loop = loops->tree_root;
    while (loop->inner)
      loop = loop->inner;
  
    /* Scan the loops, inner ones first.  */
!   while (loop != loops->tree_root)
      {
        if (loop->next)
  	{
--- 142,165 ----
  
  /* Unroll and/or peel (depending on FLAGS) LOOPS.  */
  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).  */
!   peel_loops_completely (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)
      {
        if (loop->next)
  	{
*************** unroll_and_peel_loops (struct loops *loo
*** 178,193 ****
  	  /* Already done.  */
  	  gcc_unreachable ();
  	case LPT_PEEL_SIMPLE:
! 	  peel_loop_simple (loops, loop);
  	  break;
  	case LPT_UNROLL_CONSTANT:
! 	  unroll_loop_constant_iterations (loops, loop);
  	  break;
  	case LPT_UNROLL_RUNTIME:
! 	  unroll_loop_runtime_iterations (loops, loop);
  	  break;
  	case LPT_UNROLL_STUPID:
! 	  unroll_loop_stupid (loops, loop);
  	  break;
  	case LPT_NONE:
  	  check = false;
--- 178,193 ----
  	  /* Already done.  */
  	  gcc_unreachable ();
  	case LPT_PEEL_SIMPLE:
! 	  peel_loop_simple (loop);
  	  break;
  	case LPT_UNROLL_CONSTANT:
! 	  unroll_loop_constant_iterations (loop);
  	  break;
  	case LPT_UNROLL_RUNTIME:
! 	  unroll_loop_runtime_iterations (loop);
  	  break;
  	case LPT_UNROLL_STUPID:
! 	  unroll_loop_stupid (loop);
  	  break;
  	case LPT_NONE:
  	  check = false;
*************** unroll_and_peel_loops (struct loops *loo
*** 199,205 ****
  	{
  #ifdef ENABLE_CHECKING
  	  verify_dominators (CDI_DOMINATORS);
! 	  verify_loop_structure (loops);
  #endif
  	}
        loop = next;
--- 199,205 ----
  	{
  #ifdef ENABLE_CHECKING
  	  verify_dominators (CDI_DOMINATORS);
! 	  verify_loop_structure ();
  #endif
  	}
        loop = next;
*************** loop_exit_at_end_p (struct loop *loop)
*** 229,245 ****
    return true;
  }
  
! /* Check whether to peel LOOPS (depending on FLAGS) completely and do so.  */
  static void
! peel_loops_completely (struct loops *loops, int flags)
  {
    struct loop *loop;
    unsigned i;
  
    /* Scan the loops, the inner ones first.  */
!   for (i = loops->num - 1; i > 0; i--)
      {
!       loop = loops->parray[i];
        if (!loop)
  	continue;
  
--- 229,245 ----
    return true;
  }
  
! /* Depending on FLAGS, check whether to peel loops completely and do so.  */
  static void
! 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;
  
*************** peel_loops_completely (struct loops *loo
*** 258,283 ****
  
        if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
  	{
! 	  peel_loop_completely (loops, loop);
  #ifdef ENABLE_CHECKING
  	  verify_dominators (CDI_DOMINATORS);
! 	  verify_loop_structure (loops);
  #endif
  	}
      }
  }
  
! /* Decide whether unroll or peel LOOPS (depending on FLAGS) and how much.  */
  static void
! decide_unrolling_and_peeling (struct loops *loops, int flags)
  {
!   struct loop *loop = loops->tree_root, *next;
  
    while (loop->inner)
      loop = loop->inner;
  
    /* Scan the loops, inner ones first.  */
!   while (loop != loops->tree_root)
      {
        if (loop->next)
  	{
--- 258,283 ----
  
        if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
  	{
! 	  peel_loop_completely (loop);
  #ifdef ENABLE_CHECKING
  	  verify_dominators (CDI_DOMINATORS);
! 	  verify_loop_structure ();
  #endif
  	}
      }
  }
  
! /* Decide whether unroll or peel loops (depending on FLAGS) and how much.  */
  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)
  	{
*************** decide_peel_completely (struct loop *loo
*** 475,481 ****
     body; i++;
     */
  static void
! peel_loop_completely (struct loops *loops, struct loop *loop)
  {
    sbitmap wont_exit;
    unsigned HOST_WIDE_INT npeel;
--- 475,481 ----
     body; i++;
     */
  static void
! peel_loop_completely (struct loop *loop)
  {
    sbitmap wont_exit;
    unsigned HOST_WIDE_INT npeel;
*************** peel_loop_completely (struct loops *loop
*** 504,510 ****
        
        opt_info_start_duplication (opt_info);
        ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 					  loops, npeel,
  					  wont_exit, desc->out_edge,
  					  remove_edges, &n_remove_edges,
  					  DLTHE_FLAG_UPDATE_FREQ
--- 504,510 ----
        
        opt_info_start_duplication (opt_info);
        ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 					  npeel,
  					  wont_exit, desc->out_edge,
  					  remove_edges, &n_remove_edges,
  					  DLTHE_FLAG_UPDATE_FREQ
*************** peel_loop_completely (struct loops *loop
*** 523,529 ****
  
        /* Remove the exit edges.  */
        for (i = 0; i < n_remove_edges; i++)
! 	remove_path (loops, remove_edges[i]);
        free (remove_edges);
      }
  
--- 523,529 ----
  
        /* Remove the exit edges.  */
        for (i = 0; i < n_remove_edges; i++)
! 	remove_path (remove_edges[i]);
        free (remove_edges);
      }
  
*************** peel_loop_completely (struct loops *loop
*** 532,538 ****
  
    /* Now remove the unreachable part of the last iteration and cancel
       the loop.  */
!   remove_path (loops, ein);
  
    if (dump_file)
      fprintf (dump_file, ";; Peeled loop completely, %d times\n", (int) npeel);
--- 532,538 ----
  
    /* Now remove the unreachable part of the last iteration and cancel
       the loop.  */
!   remove_path (ein);
  
    if (dump_file)
      fprintf (dump_file, ";; Peeled loop completely, %d times\n", (int) npeel);
*************** decide_unroll_constant_iterations (struc
*** 658,664 ****
       }
    */
  static void
! unroll_loop_constant_iterations (struct loops *loops, struct loop *loop)
  {
    unsigned HOST_WIDE_INT niter;
    unsigned exit_mod;
--- 658,664 ----
       }
    */
  static void
! unroll_loop_constant_iterations (struct loop *loop)
  {
    unsigned HOST_WIDE_INT niter;
    unsigned exit_mod;
*************** unroll_loop_constant_iterations (struct 
*** 705,711 ****
  	{
  	  opt_info_start_duplication (opt_info);
            ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 					      loops, exit_mod,
  					      wont_exit, desc->out_edge,
  					      remove_edges, &n_remove_edges,
  					      DLTHE_FLAG_UPDATE_FREQ
--- 705,711 ----
  	{
  	  opt_info_start_duplication (opt_info);
            ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 					      exit_mod,
  					      wont_exit, desc->out_edge,
  					      remove_edges, &n_remove_edges,
  					      DLTHE_FLAG_UPDATE_FREQ
*************** unroll_loop_constant_iterations (struct 
*** 744,750 ****
           
            opt_info_start_duplication (opt_info);
  	  ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 					      loops, exit_mod + 1,
  					      wont_exit, desc->out_edge,
  					      remove_edges, &n_remove_edges,
  					      DLTHE_FLAG_UPDATE_FREQ
--- 744,750 ----
           
            opt_info_start_duplication (opt_info);
  	  ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 					      exit_mod + 1,
  					      wont_exit, desc->out_edge,
  					      remove_edges, &n_remove_edges,
  					      DLTHE_FLAG_UPDATE_FREQ
*************** unroll_loop_constant_iterations (struct 
*** 771,777 ****
    
    opt_info_start_duplication (opt_info);
    ok = duplicate_loop_to_header_edge (loop, loop_latch_edge (loop),
! 				      loops, max_unroll,
  				      wont_exit, desc->out_edge,
  				      remove_edges, &n_remove_edges,
  				      DLTHE_FLAG_UPDATE_FREQ
--- 771,777 ----
    
    opt_info_start_duplication (opt_info);
    ok = duplicate_loop_to_header_edge (loop, loop_latch_edge (loop),
! 				      max_unroll,
  				      wont_exit, desc->out_edge,
  				      remove_edges, &n_remove_edges,
  				      DLTHE_FLAG_UPDATE_FREQ
*************** unroll_loop_constant_iterations (struct 
*** 811,817 ****
  
    /* Remove the edges.  */
    for (i = 0; i < n_remove_edges; i++)
!     remove_path (loops, remove_edges[i]);
    free (remove_edges);
  
    if (dump_file)
--- 811,817 ----
  
    /* Remove the edges.  */
    for (i = 0; i < n_remove_edges; i++)
!     remove_path (remove_edges[i]);
    free (remove_edges);
  
    if (dump_file)
*************** split_edge_and_insert (edge e, rtx insns
*** 948,954 ****
       }
     */
  static void
! unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
  {
    rtx old_niter, niter, init_code, branch_code, tmp;
    unsigned i, j, p;
--- 948,954 ----
       }
     */
  static void
! unroll_loop_runtime_iterations (struct loop *loop)
  {
    rtx old_niter, niter, init_code, branch_code, tmp;
    unsigned i, j, p;
*************** unroll_loop_runtime_iterations (struct l
*** 1043,1050 ****
      SET_BIT (wont_exit, 1);
    ezc_swtch = loop_preheader_edge (loop)->src;
    ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 				      loops, 1,
! 				      wont_exit, desc->out_edge,
  				      remove_edges, &n_remove_edges,
  				      DLTHE_FLAG_UPDATE_FREQ);
    gcc_assert (ok);
--- 1043,1049 ----
      SET_BIT (wont_exit, 1);
    ezc_swtch = loop_preheader_edge (loop)->src;
    ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 				      1, wont_exit, desc->out_edge,
  				      remove_edges, &n_remove_edges,
  				      DLTHE_FLAG_UPDATE_FREQ);
    gcc_assert (ok);
*************** unroll_loop_runtime_iterations (struct l
*** 1059,1066 ****
        if (i != n_peel - 1 || !last_may_exit)
  	SET_BIT (wont_exit, 1);
        ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 					  loops, 1,
! 					  wont_exit, desc->out_edge,
  					  remove_edges, &n_remove_edges,
  					  DLTHE_FLAG_UPDATE_FREQ);
        gcc_assert (ok);
--- 1058,1064 ----
        if (i != n_peel - 1 || !last_may_exit)
  	SET_BIT (wont_exit, 1);
        ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 					  1, wont_exit, desc->out_edge,
  					  remove_edges, &n_remove_edges,
  					  DLTHE_FLAG_UPDATE_FREQ);
        gcc_assert (ok);
*************** unroll_loop_runtime_iterations (struct l
*** 1115,1121 ****
    opt_info_start_duplication (opt_info);
    
    ok = duplicate_loop_to_header_edge (loop, loop_latch_edge (loop),
! 				      loops, max_unroll,
  				      wont_exit, desc->out_edge,
  				      remove_edges, &n_remove_edges,
  				      DLTHE_FLAG_UPDATE_FREQ
--- 1113,1119 ----
    opt_info_start_duplication (opt_info);
    
    ok = duplicate_loop_to_header_edge (loop, loop_latch_edge (loop),
! 				      max_unroll,
  				      wont_exit, desc->out_edge,
  				      remove_edges, &n_remove_edges,
  				      DLTHE_FLAG_UPDATE_FREQ
*************** unroll_loop_runtime_iterations (struct l
*** 1152,1158 ****
  
    /* Remove the edges.  */
    for (i = 0; i < n_remove_edges; i++)
!     remove_path (loops, remove_edges[i]);
    free (remove_edges);
  
    /* We must be careful when updating the number of iterations due to
--- 1150,1156 ----
  
    /* Remove the edges.  */
    for (i = 0; i < n_remove_edges; i++)
!     remove_path (remove_edges[i]);
    free (remove_edges);
  
    /* We must be careful when updating the number of iterations due to
*************** decide_peel_simple (struct loop *loop, i
*** 1282,1288 ****
     end: ;
     */
  static void
! peel_loop_simple (struct loops *loops, struct loop *loop)
  {
    sbitmap wont_exit;
    unsigned npeel = loop->lpt_decision.times;
--- 1280,1286 ----
     end: ;
     */
  static void
! peel_loop_simple (struct loop *loop)
  {
    sbitmap wont_exit;
    unsigned npeel = loop->lpt_decision.times;
*************** peel_loop_simple (struct loops *loops, s
*** 1299,1305 ****
    opt_info_start_duplication (opt_info);
    
    ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 				      loops, npeel, wont_exit,
  				      NULL, NULL,
  				      NULL, DLTHE_FLAG_UPDATE_FREQ
  				      | (opt_info
--- 1297,1303 ----
    opt_info_start_duplication (opt_info);
    
    ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 				      npeel, wont_exit,
  				      NULL, NULL,
  				      NULL, DLTHE_FLAG_UPDATE_FREQ
  				      | (opt_info
*************** decide_unroll_stupid (struct loop *loop,
*** 1432,1438 ****
       }
     */
  static void
! unroll_loop_stupid (struct loops *loops, struct loop *loop)
  {
    sbitmap wont_exit;
    unsigned nunroll = loop->lpt_decision.times;
--- 1430,1436 ----
       }
     */
  static void
! unroll_loop_stupid (struct loop *loop)
  {
    sbitmap wont_exit;
    unsigned nunroll = loop->lpt_decision.times;
*************** unroll_loop_stupid (struct loops *loops,
*** 1450,1456 ****
    opt_info_start_duplication (opt_info);
    
    ok = duplicate_loop_to_header_edge (loop, loop_latch_edge (loop),
! 				      loops, nunroll, wont_exit,
  				      NULL, NULL, NULL,
  				      DLTHE_FLAG_UPDATE_FREQ
  				      | (opt_info
--- 1448,1454 ----
    opt_info_start_duplication (opt_info);
    
    ok = duplicate_loop_to_header_edge (loop, loop_latch_edge (loop),
! 				      nunroll, wont_exit,
  				      NULL, NULL, NULL,
  				      DLTHE_FLAG_UPDATE_FREQ
  				      | (opt_info
Index: loop-doloop.c
===================================================================
*** loop-doloop.c	(revision 119131)
--- loop-doloop.c	(working copy)
*************** doloop_optimize (struct loop *loop)
*** 616,632 ****
    return true;
  }
  
! /* This is the main entry point.  Process all LOOPS using doloop_optimize.  */
  
  void
! doloop_optimize_loops (struct loops *loops)
  {
    unsigned i;
    struct loop *loop;
  
!   for (i = 1; i < loops->num; i++)
      {
!       loop = loops->parray[i];
        if (!loop)
  	continue;
  
--- 616,632 ----
    return true;
  }
  
! /* This is the main entry point.  Process all loops using doloop_optimize.  */
  
  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_loops (struct loops *loo
*** 637,643 ****
  
  #ifdef ENABLE_CHECKING
    verify_dominators (CDI_DOMINATORS);
!   verify_loop_structure (loops);
  #endif
  }
  #endif /* HAVE_doloop_end */
--- 637,643 ----
  
  #ifdef ENABLE_CHECKING
    verify_dominators (CDI_DOMINATORS);
!   verify_loop_structure ();
  #endif
  }
  #endif /* HAVE_doloop_end */
Index: tree-cfgcleanup.c
===================================================================
*** tree-cfgcleanup.c	(revision 119131)
--- tree-cfgcleanup.c	(working copy)
*************** cleanup_tree_cfg_loop (void)
*** 589,595 ****
    if (changed)
      {
        bitmap changed_bbs = BITMAP_ALLOC (NULL);
!       fix_loop_structure (current_loops, changed_bbs);
        calculate_dominance_info (CDI_DOMINATORS);
  
        /* This usually does nothing.  But sometimes parts of cfg that originally
--- 589,595 ----
    if (changed)
      {
        bitmap changed_bbs = BITMAP_ALLOC (NULL);
!       fix_loop_structure (changed_bbs);
        calculate_dominance_info (CDI_DOMINATORS);
  
        /* This usually does nothing.  But sometimes parts of cfg that originally
*************** cleanup_tree_cfg_loop (void)
*** 600,606 ****
        BITMAP_FREE (changed_bbs);
  
  #ifdef ENABLE_CHECKING
!       verify_loop_structure (current_loops);
  #endif
        scev_reset ();
      }
--- 600,606 ----
        BITMAP_FREE (changed_bbs);
  
  #ifdef ENABLE_CHECKING
!       verify_loop_structure ();
  #endif
        scev_reset ();
      }
Index: loop-invariant.c
===================================================================
*** loop-invariant.c	(revision 119131)
--- loop-invariant.c	(working copy)
*************** free_loop_data (struct loop *loop)
*** 1312,1321 ****
    loop->aux = NULL;
  }
  
! /* Move the invariants out of the LOOPS.  */
  
  void
! move_loop_invariants (struct loops *loops)
  {
    struct loop *loop;
    unsigned i;
--- 1312,1321 ----
    loop->aux = NULL;
  }
  
! /* Move the invariants out of the loops.  */
  
  void
! move_loop_invariants (void)
  {
    struct loop *loop;
    unsigned i;
*************** move_loop_invariants (struct loops *loop
*** 1324,1334 ****
    df_chain_add_problem (df, DF_UD_CHAIN);
   
    /* Process the loops, innermost first.  */
!   loop = loops->tree_root;
    while (loop->inner)
      loop = loop->inner;
  
!   while (loop != loops->tree_root)
      {
        move_single_loop_invariants (loop);
  
--- 1324,1334 ----
    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);
  
*************** move_loop_invariants (struct loops *loop
*** 1342,1350 ****
  	loop = loop->outer;
      }
  
!   for (i = 1; i < loops->num; i++)
!     if (loops->parray[i])
!       free_loop_data (loops->parray[i]);
  
    df_finish (df);
    df = NULL;
--- 1342,1350 ----
  	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;
Index: lambda.h
===================================================================
*** lambda.h	(revision 119131)
--- lambda.h	(working copy)
*************** typedef struct
*** 141,147 ****
  lambda_loopnest lambda_loopnest_new (int, int);
  lambda_loopnest lambda_loopnest_transform (lambda_loopnest, lambda_trans_matrix);
  struct loop;
- struct loops;
  bool perfect_nest_p (struct loop *);
  void print_lambda_loopnest (FILE *, lambda_loopnest, char);
  
--- 141,146 ----
*************** lambda_body_vector lambda_body_vector_ne
*** 196,203 ****
  lambda_body_vector lambda_body_vector_compute_new (lambda_trans_matrix, 
  						   lambda_body_vector);
  void print_lambda_body_vector (FILE *, lambda_body_vector);
! lambda_loopnest gcc_loopnest_to_lambda_loopnest (struct loops *,
! 						 struct loop *,
  						 VEC(tree,heap) **,
  						 VEC(tree,heap) **);
  void lambda_loopnest_to_gcc_loopnest (struct loop *,
--- 195,201 ----
  lambda_body_vector lambda_body_vector_compute_new (lambda_trans_matrix, 
  						   lambda_body_vector);
  void print_lambda_body_vector (FILE *, lambda_body_vector);
! lambda_loopnest gcc_loopnest_to_lambda_loopnest (struct loop *,
  						 VEC(tree,heap) **,
  						 VEC(tree,heap) **);
  void lambda_loopnest_to_gcc_loopnest (struct loop *,
Index: tree-ssa-dce.c
===================================================================
*** tree-ssa-dce.c	(revision 119131)
--- tree-ssa-dce.c	(working copy)
*************** static unsigned int
*** 933,939 ****
  tree_ssa_dce_loop (void)
  {
    perform_tree_ssa_dce (/*aggressive=*/false);
!   free_numbers_of_iterations_estimates (current_loops);
    scev_reset ();
    return 0;
  }
--- 933,939 ----
  tree_ssa_dce_loop (void)
  {
    perform_tree_ssa_dce (/*aggressive=*/false);
!   free_numbers_of_iterations_estimates ();
    scev_reset ();
    return 0;
  }
Index: tree-ssa-loop-prefetch.c
===================================================================
*** tree-ssa-loop-prefetch.c	(revision 119131)
--- tree-ssa-loop-prefetch.c	(working copy)
*************** determine_unroll_factor (struct loop *lo
*** 936,946 ****
  }
  
  /* Issue prefetch instructions for array references in LOOP.  Returns
!    true if the LOOP was unrolled.  LOOPS is the array containing all
!    loops.  */
  
  static bool
! loop_prefetch_arrays (struct loops *loops, struct loop *loop)
  {
    struct mem_ref_group *refs;
    unsigned ahead, ninsns, unroll_factor;
--- 936,945 ----
  }
  
  /* Issue prefetch instructions for array references in LOOP.  Returns
!    true if the LOOP was unrolled.  */
  
  static bool
! loop_prefetch_arrays (struct loop *loop)
  {
    struct mem_ref_group *refs;
    unsigned ahead, ninsns, unroll_factor;
*************** loop_prefetch_arrays (struct loops *loop
*** 981,987 ****
       iterations so that we do not issue superfluous prefetches.  */
    if (unroll_factor != 1)
      {
!       tree_unroll_loop (loops, loop, unroll_factor,
  			single_dom_exit (loop), &desc);
        unrolled = true;
      }
--- 980,986 ----
       iterations so that we do not issue superfluous prefetches.  */
    if (unroll_factor != 1)
      {
!       tree_unroll_loop (loop, unroll_factor,
  			single_dom_exit (loop), &desc);
        unrolled = true;
      }
*************** fail:
*** 994,1003 ****
    return unrolled;
  }
  
! /* Issue prefetch instructions for array references in LOOPS.  */
  
  unsigned int
! tree_ssa_prefetch_arrays (struct loops *loops)
  {
    unsigned i;
    struct loop *loop;
--- 993,1002 ----
    return unrolled;
  }
  
! /* Issue prefetch instructions for array references in loops.  */
  
  unsigned int
! tree_ssa_prefetch_arrays (void)
  {
    unsigned i;
    struct loop *loop;
*************** tree_ssa_prefetch_arrays (struct loops *
*** 1044,1059 ****
       here.  */
    gcc_assert ((PREFETCH_BLOCK & (PREFETCH_BLOCK - 1)) == 0);
  
!   for (i = loops->num - 1; i > 0; i--)
      {
!       loop = loops->parray[i];
        if (!loop)
  	continue;
  
        if (dump_file && (dump_flags & TDF_DETAILS))
  	fprintf (dump_file, "Processing loop %d:\n", loop->num);
  
!       unrolled |= loop_prefetch_arrays (loops, loop);
  
        if (dump_file && (dump_flags & TDF_DETAILS))
  	fprintf (dump_file, "\n\n");
--- 1043,1058 ----
       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);
  
!       unrolled |= loop_prefetch_arrays (loop);
  
        if (dump_file && (dump_flags & TDF_DETAILS))
  	fprintf (dump_file, "\n\n");
Index: lambda-code.c
===================================================================
*** lambda-code.c	(revision 119131)
--- lambda-code.c	(working copy)
***************
*** 115,122 ****
   Fourier-Motzkin elimination is used to compute the bounds of the base space
   of the lattice.  */
  
! static bool perfect_nestify (struct loops *, 
! 			     struct loop *, VEC(tree,heap) *, 
  			     VEC(tree,heap) *, VEC(int,heap) *,
  			     VEC(tree,heap) *);
  /* Lattice stuff that is internal to the code generation algorithm.  */
--- 115,121 ----
   Fourier-Motzkin elimination is used to compute the bounds of the base space
   of the lattice.  */
  
! static bool perfect_nestify (struct loop *, VEC(tree,heap) *, 
  			     VEC(tree,heap) *, VEC(int,heap) *,
  			     VEC(tree,heap) *);
  /* Lattice stuff that is internal to the code generation algorithm.  */
*************** DEF_VEC_ALLOC_P(lambda_loop,heap);
*** 1457,1464 ****
     during this process.  */
  
  lambda_loopnest
! gcc_loopnest_to_lambda_loopnest (struct loops *currloops,
! 				 struct loop *loop_nest,
  				 VEC(tree,heap) **inductionvars,
  				 VEC(tree,heap) **invariants)
  {
--- 1456,1462 ----
     during this process.  */
  
  lambda_loopnest
! gcc_loopnest_to_lambda_loopnest (struct loop *loop_nest,
  				 VEC(tree,heap) **inductionvars,
  				 VEC(tree,heap) **invariants)
  {
*************** gcc_loopnest_to_lambda_loopnest (struct 
*** 1493,1500 ****
  
    if (!perfect_nest)
      {
!       if (!perfect_nestify (currloops, loop_nest, 
! 			    lboundvars, uboundvars, steps, *inductionvars))
  	{
  	  if (dump_file)
  	    fprintf (dump_file,
--- 1491,1498 ----
  
    if (!perfect_nest)
      {
!       if (!perfect_nestify (loop_nest, lboundvars, uboundvars, steps,
! 			    *inductionvars))
  	{
  	  if (dump_file)
  	    fprintf (dump_file,
*************** can_convert_to_perfect_nest (struct loop
*** 2402,2408 ****
  }
  
  /* Transform the loop nest into a perfect nest, if possible.
-    LOOPS is the current struct loops *
     LOOP is the loop nest to transform into a perfect nest
     LBOUNDS are the lower bounds for the loops to transform
     UBOUNDS are the upper bounds for the loops to transform
--- 2400,2405 ----
*************** can_convert_to_perfect_nest (struct loop
*** 2439,2446 ****
     Return FALSE if we can't make this loop into a perfect nest.  */
  
  static bool
! perfect_nestify (struct loops *loops,
! 		 struct loop *loop,
  		 VEC(tree,heap) *lbounds,
  		 VEC(tree,heap) *ubounds,
  		 VEC(int,heap) *steps,
--- 2436,2442 ----
     Return FALSE if we can't make this loop into a perfect nest.  */
  
  static bool
! perfect_nestify (struct loop *loop,
  		 VEC(tree,heap) *lbounds,
  		 VEC(tree,heap) *ubounds,
  		 VEC(int,heap) *steps,
*************** perfect_nestify (struct loops *loops,
*** 2514,2520 ****
    make_edge (latchbb, headerbb, EDGE_FALLTHRU);
  
    /* Update the loop structures.  */
!   newloop = duplicate_loop (loops, loop, olddest->loop_father);  
    newloop->header = headerbb;
    newloop->latch = latchbb;
    set_single_exit (newloop, e);
--- 2510,2516 ----
    make_edge (latchbb, headerbb, EDGE_FALLTHRU);
  
    /* Update the loop structures.  */
!   newloop = duplicate_loop (loop, olddest->loop_father);  
    newloop->header = headerbb;
    newloop->latch = latchbb;
    set_single_exit (newloop, e);
Index: tree-vect-transform.c
===================================================================
*** tree-vect-transform.c	(revision 119131)
--- tree-vect-transform.c	(working copy)
*************** static void vect_update_ivs_after_vector
*** 70,78 ****
  static tree vect_gen_niters_for_prolog_loop (loop_vec_info, tree);
  static void vect_update_init_of_dr (struct data_reference *, tree niters);
  static void vect_update_inits_of_drs (loop_vec_info, tree);
- static void vect_do_peeling_for_alignment (loop_vec_info, struct loops *);
- static void vect_do_peeling_for_loop_bound 
-   (loop_vec_info, tree *, struct loops *);
  static int vect_min_worthwhile_factor (enum tree_code);
  
  
--- 70,75 ----
*************** vect_update_ivs_after_vectorizer (loop_v
*** 4070,4077 ****
     NITERS / VECTORIZATION_FACTOR times (this value is placed into RATIO).  */
  
  static void 
! vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio,
! 				struct loops *loops)
  {
    tree ni_name, ratio_mult_vf_name;
    struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
--- 4067,4073 ----
     NITERS / VECTORIZATION_FACTOR times (this value is placed into RATIO).  */
  
  static void 
! vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio)
  {
    tree ni_name, ratio_mult_vf_name;
    struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
*************** vect_do_peeling_for_loop_bound (loop_vec
*** 4094,4100 ****
  				   &ratio_mult_vf_name, ratio);
  
    loop_num  = loop->num; 
!   new_loop = slpeel_tree_peel_loop_to_edge (loop, loops, single_exit (loop),
  					    ratio_mult_vf_name, ni_name, false);
    gcc_assert (new_loop);
    gcc_assert (loop_num == loop->num);
--- 4090,4096 ----
  				   &ratio_mult_vf_name, ratio);
  
    loop_num  = loop->num; 
!   new_loop = slpeel_tree_peel_loop_to_edge (loop, single_exit (loop),
  					    ratio_mult_vf_name, ni_name, false);
    gcc_assert (new_loop);
    gcc_assert (loop_num == loop->num);
*************** vect_update_inits_of_drs (loop_vec_info 
*** 4302,4308 ****
     peeling is recorded in LOOP_VINFO_UNALIGNED_DR.  */
  
  static void
! vect_do_peeling_for_alignment (loop_vec_info loop_vinfo, struct loops *loops)
  {
    struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
    tree niters_of_prolog_loop, ni_name;
--- 4298,4304 ----
     peeling is recorded in LOOP_VINFO_UNALIGNED_DR.  */
  
  static void
! vect_do_peeling_for_alignment (loop_vec_info loop_vinfo)
  {
    struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
    tree niters_of_prolog_loop, ni_name;
*************** vect_do_peeling_for_alignment (loop_vec_
*** 4319,4325 ****
    
    /* Peel the prolog loop and iterate it niters_of_prolog_loop.  */
    new_loop = 
! 	slpeel_tree_peel_loop_to_edge (loop, loops, loop_preheader_edge (loop), 
  				       niters_of_prolog_loop, ni_name, true); 
    gcc_assert (new_loop);
  #ifdef ENABLE_CHECKING
--- 4315,4321 ----
    
    /* Peel the prolog loop and iterate it niters_of_prolog_loop.  */
    new_loop = 
! 	slpeel_tree_peel_loop_to_edge (loop, loop_preheader_edge (loop), 
  				       niters_of_prolog_loop, ni_name, true); 
    gcc_assert (new_loop);
  #ifdef ENABLE_CHECKING
*************** vect_create_cond_for_align_checks (loop_
*** 4470,4477 ****
     stmts in the loop, and update the loop exit condition.  */
  
  void
! vect_transform_loop (loop_vec_info loop_vinfo, 
! 		     struct loops *loops ATTRIBUTE_UNUSED)
  {
    struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
    basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
--- 4466,4472 ----
     stmts in the loop, and update the loop exit condition.  */
  
  void
! vect_transform_loop (loop_vec_info loop_vinfo)
  {
    struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
    basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
*************** vect_transform_loop (loop_vec_info loop_
*** 4508,4514 ****
        cond_expr = vect_create_cond_for_align_checks (loop_vinfo,
                                                       &cond_expr_stmt_list);
        initialize_original_copy_tables ();
!       nloop = loop_version (loops, loop, cond_expr, &condition_bb, true);
        free_original_copy_tables();
  
        /** Loop versioning violates an assumption we try to maintain during 
--- 4503,4509 ----
        cond_expr = vect_create_cond_for_align_checks (loop_vinfo,
                                                       &cond_expr_stmt_list);
        initialize_original_copy_tables ();
!       nloop = loop_version (loop, cond_expr, &condition_bb, true);
        free_original_copy_tables();
  
        /** Loop versioning violates an assumption we try to maintain during 
*************** vect_transform_loop (loop_vec_info loop_
*** 4550,4556 ****
       Only one data ref with unknown store is allowed.  */
  
    if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
!     vect_do_peeling_for_alignment (loop_vinfo, loops);
    
    /* If the loop has a symbolic number of iterations 'n' (i.e. it's not a
       compile time constant), or it is a constant that doesn't divide by the
--- 4545,4551 ----
       Only one data ref with unknown store is allowed.  */
  
    if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
!     vect_do_peeling_for_alignment (loop_vinfo);
    
    /* If the loop has a symbolic number of iterations 'n' (i.e. it's not a
       compile time constant), or it is a constant that doesn't divide by the
*************** vect_transform_loop (loop_vec_info loop_
*** 4563,4569 ****
    if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
        || (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
            && LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0))
!     vect_do_peeling_for_loop_bound (loop_vinfo, &ratio, loops);
    else
      ratio = build_int_cst (TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo)),
  		LOOP_VINFO_INT_NITERS (loop_vinfo) / vectorization_factor);
--- 4558,4564 ----
    if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
        || (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
            && LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0))
!     vect_do_peeling_for_loop_bound (loop_vinfo, &ratio);
    else
      ratio = build_int_cst (TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo)),
  		LOOP_VINFO_INT_NITERS (loop_vinfo) / vectorization_factor);
Index: cfgloop.c
===================================================================
*** cfgloop.c	(revision 119131)
--- cfgloop.c	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 40,46 ****
  #define HEADER_BLOCK(B) (* (int *) (B)->aux)
  #define LATCH_EDGE(E) (*(int *) (E)->aux)
  
! static void flow_loops_cfg_dump (const struct loops *, FILE *);
  static void establish_preds (struct loop *);
  static void canonicalize_loop_headers (void);
  static bool glb_enum_p (basic_block, void *);
--- 40,46 ----
  #define HEADER_BLOCK(B) (* (int *) (B)->aux)
  #define LATCH_EDGE(E) (*(int *) (E)->aux)
  
! static void flow_loops_cfg_dump (FILE *);
  static void establish_preds (struct loop *);
  static void canonicalize_loop_headers (void);
  static bool glb_enum_p (basic_block, void *);
*************** static bool glb_enum_p (basic_block, voi
*** 48,58 ****
  /* Dump loop related CFG information.  */
  
  static void
! flow_loops_cfg_dump (const struct loops *loops, FILE *file)
  {
    basic_block bb;
  
!   if (! loops->num || ! file)
      return;
  
    FOR_EACH_BB (bb)
--- 48,58 ----
  /* Dump loop related CFG information.  */
  
  static void
! flow_loops_cfg_dump (FILE *file)
  {
    basic_block bb;
  
!   if (!file)
      return;
  
    FOR_EACH_BB (bb)
*************** flow_loop_dump (const struct loop *loop,
*** 122,145 ****
      loop_dump_aux (loop, file, verbose);
  }
  
! /* Dump the loop information specified by LOOPS to the stream FILE,
     using auxiliary dump callback function LOOP_DUMP_AUX if non null.  */
  
  void
! flow_loops_dump (const struct loops *loops, FILE *file, void (*loop_dump_aux) (const struct loop *, FILE *, int), int verbose)
  {
!   int i;
!   int num_loops;
  
!   num_loops = loops->num;
!   if (! num_loops || ! file)
      return;
  
!   fprintf (file, ";; %d loops found\n", num_loops);
  
!   for (i = 0; i < num_loops; i++)
      {
!       struct loop *loop = loops->parray[i];
  
        if (!loop)
  	continue;
--- 122,143 ----
      loop_dump_aux (loop, file, verbose);
  }
  
! /* Dump the loop information about loops to the stream FILE,
     using auxiliary dump callback function LOOP_DUMP_AUX if non null.  */
  
  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_loops_dump (const struct loops *loo
*** 148,154 ****
      }
  
    if (verbose)
!     flow_loops_cfg_dump (loops, file);
  }
  
  /* Free data allocated for LOOP.  */
--- 146,152 ----
      }
  
    if (verbose)
!     flow_loops_cfg_dump (file);
  }
  
  /* Free data allocated for LOOP.  */
*************** flow_loop_nodes_find (basic_block header
*** 236,255 ****
    return num_nodes;
  }
  
! /* For each loop in the lOOPS tree that has just a single exit
!    record the exit edge.  */
  
  void
! mark_single_exit_loops (struct loops *loops)
  {
    basic_block bb;
    edge e;
    struct loop *loop;
    unsigned i;
  
!   for (i = 1; i < loops->num; i++)
      {
!       loop = loops->parray[i];
        if (loop)
  	set_single_exit (loop, NULL);
      }
--- 234,252 ----
    return num_nodes;
  }
  
! /* For each loop that has just a single exit, record the exit edge.  */
  
  void
! mark_single_exit_loops (void)
  {
    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);
      }
*************** mark_single_exit_loops (struct loops *lo
*** 257,263 ****
    FOR_EACH_BB (bb)
      {
        edge_iterator ei;
!       if (bb->loop_father == loops->tree_root)
  	continue;
        FOR_EACH_EDGE (e, ei, bb->succs)
  	{
--- 254,260 ----
    FOR_EACH_BB (bb)
      {
        edge_iterator ei;
!       if (bb->loop_father == current_loops->tree_root)
  	continue;
        FOR_EACH_EDGE (e, ei, bb->succs)
  	{
*************** mark_single_exit_loops (struct loops *lo
*** 281,289 ****
  	}
      }
  
!   for (i = 1; i < loops->num; i++)
      {
!       loop = loops->parray[i];
        if (!loop)
  	continue;
  
--- 278,286 ----
  	}
      }
  
!   for (i = 1; i < current_loops->num; i++)
      {
!       loop = current_loops->parray[i];
        if (!loop)
  	continue;
  
*************** mark_single_exit_loops (struct loops *lo
*** 291,297 ****
  	set_single_exit (loop, NULL);
      }
  
!   loops->state |= LOOPS_HAVE_MARKED_SINGLE_EXITS;
  }
  
  static void
--- 288,294 ----
  	set_single_exit (loop, NULL);
      }
  
!   current_loops->state |= LOOPS_HAVE_MARKED_SINGLE_EXITS;
  }
  
  static void
*************** find_common_loop (struct loop *loop_s, s
*** 930,936 ****
  /* Cancels the LOOP; it must be innermost one.  */
  
  static void
! cancel_loop (struct loops *loops, struct loop *loop)
  {
    basic_block *bbs;
    unsigned i;
--- 927,933 ----
  /* Cancels the LOOP; it must be innermost one.  */
  
  static void
! cancel_loop (struct loop *loop)
  {
    basic_block *bbs;
    unsigned i;
*************** cancel_loop (struct loops *loops, struct
*** 946,952 ****
    flow_loop_tree_node_remove (loop);
  
    /* Remove loop from loops array.  */
!   loops->parray[loop->num] = NULL;
  
    /* Free loop data.  */
    flow_loop_free (loop);
--- 943,949 ----
    flow_loop_tree_node_remove (loop);
  
    /* Remove loop from loops array.  */
!   current_loops->parray[loop->num] = NULL;
  
    /* Free loop data.  */
    flow_loop_free (loop);
*************** cancel_loop (struct loops *loops, struct
*** 954,967 ****
  
  /* Cancels LOOP and all its subloops.  */
  void
! cancel_loop_tree (struct loops *loops, struct loop *loop)
  {
    while (loop->inner)
!     cancel_loop_tree (loops, loop->inner);
!   cancel_loop (loops, loop);
  }
  
! /* Checks that LOOPS are all right:
       -- sizes of loops are all right
       -- results of get_loop_body really belong to the loop
       -- loop header have just single entry edge and single latch edge
--- 951,964 ----
  
  /* Cancels LOOP and all its subloops.  */
  void
! cancel_loop_tree (struct loop *loop)
  {
    while (loop->inner)
!     cancel_loop_tree (loop->inner);
!   cancel_loop (loop);
  }
  
! /* Checks that information about loops is correct
       -- sizes of loops are all right
       -- results of get_loop_body really belong to the loop
       -- loop header have just single entry edge and single latch edge
*************** cancel_loop_tree (struct loops *loops, s
*** 969,975 ****
       -- irreducible loops are correctly marked
    */
  void
! verify_loop_structure (struct loops *loops)
  {
    unsigned *sizes, i, j;
    sbitmap irreds;
--- 966,972 ----
       -- irreducible loops are correctly marked
    */
  void
! verify_loop_structure (void)
  {
    unsigned *sizes, i, j;
    sbitmap irreds;
*************** verify_loop_structure (struct loops *loo
*** 979,1008 ****
    edge e;
  
    /* Check sizes.  */
!   sizes = XCNEWVEC (unsigned, 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 < loops->num; i++)
      {
!       if (!loops->parray[i])
  	continue;
  
!       if (loops->parray[i]->num_nodes != sizes[i])
  	{
  	  error ("size of loop %d should be %d, not %d",
! 		   i, sizes[i], loops->parray[i]->num_nodes);
  	  err = 1;
  	}
      }
  
    /* Check get_loop_body.  */
!   for (i = 1; i < loops->num; i++)
      {
!       loop = loops->parray[i];
        if (!loop)
  	continue;
        bbs = get_loop_body (loop);
--- 976,1005 ----
    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);
*************** verify_loop_structure (struct loops *loo
*** 1018,1036 ****
      }
  
    /* Check headers and latches.  */
!   for (i = 1; i < loops->num; i++)
      {
!       loop = loops->parray[i];
        if (!loop)
  	continue;
  
!       if ((loops->state & LOOPS_HAVE_PREHEADERS)
  	  && EDGE_COUNT (loop->header->preds) != 2)
  	{
  	  error ("loop %d's header does not have exactly 2 entries", i);
  	  err = 1;
  	}
!       if (loops->state & LOOPS_HAVE_SIMPLE_LATCHES)
  	{
  	  if (!single_succ_p (loop->latch))
  	    {
--- 1015,1033 ----
      }
  
    /* 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)
  	{
  	  error ("loop %d's header does not have exactly 2 entries", i);
  	  err = 1;
  	}
!       if (current_loops->state & LOOPS_HAVE_SIMPLE_LATCHES)
  	{
  	  if (!single_succ_p (loop->latch))
  	    {
*************** verify_loop_structure (struct loops *loo
*** 1053,1059 ****
  	  error ("loop %d's header does not belong directly to it", i);
  	  err = 1;
  	}
!       if ((loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
  	  && (loop_latch_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP))
  	{
  	  error ("loop %d's latch is marked as part of irreducible region", i);
--- 1050,1056 ----
  	  error ("loop %d's header does not belong directly to it", i);
  	  err = 1;
  	}
!       if ((current_loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
  	  && (loop_latch_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP))
  	{
  	  error ("loop %d's latch is marked as part of irreducible region", i);
*************** verify_loop_structure (struct loops *loo
*** 1062,1068 ****
      }
  
    /* Check irreducible loops.  */
!   if (loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
      {
        /* Record old info.  */
        irreds = sbitmap_alloc (last_basic_block);
--- 1059,1065 ----
      }
  
    /* Check irreducible loops.  */
!   if (current_loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
      {
        /* Record old info.  */
        irreds = sbitmap_alloc (last_basic_block);
*************** verify_loop_structure (struct loops *loo
*** 1079,1085 ****
  	}
  
        /* Recount it.  */
!       mark_irreducible_loops (loops);
  
        /* Compare.  */
        FOR_EACH_BB (bb)
--- 1076,1082 ----
  	}
  
        /* Recount it.  */
!       mark_irreducible_loops ();
  
        /* Compare.  */
        FOR_EACH_BB (bb)
*************** verify_loop_structure (struct loops *loo
*** 1121,1133 ****
      }
  
    /* Check the single_exit.  */
!   if (loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
      {
!       memset (sizes, 0, sizeof (unsigned) * loops->num);
        FOR_EACH_BB (bb)
  	{
  	  edge_iterator ei;
! 	  if (bb->loop_father == loops->tree_root)
  	    continue;
  	  FOR_EACH_EDGE (e, ei, bb->succs)
  	    {
--- 1118,1130 ----
      }
  
    /* 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;
! 	  if (bb->loop_father == current_loops->tree_root)
  	    continue;
  	  FOR_EACH_EDGE (e, ei, bb->succs)
  	    {
*************** verify_loop_structure (struct loops *loo
*** 1157,1165 ****
  	    }
  	}
  
!       for (i = 1; i < loops->num; i++)
  	{
! 	  loop = loops->parray[i];
  	  if (!loop)
  	    continue;
  
--- 1154,1162 ----
  	    }
  	}
  
!       for (i = 1; i < current_loops->num; i++)
  	{
! 	  loop = current_loops->parray[i];
  	  if (!loop)
  	    continue;
  
Index: cfgloop.h
===================================================================
*** cfgloop.h	(revision 119131)
--- cfgloop.h	(working copy)
*************** struct loops
*** 191,205 ****
  /* Loop recognition.  */
  extern int flow_loops_find (struct loops *);
  extern void flow_loops_free (struct loops *);
! extern void flow_loops_dump (const struct loops *, FILE *,
  			     void (*)(const struct loop *, FILE *, int), int);
  extern void flow_loop_dump (const struct loop *, FILE *,
  			    void (*)(const struct loop *, FILE *, int), int);
  extern void flow_loop_free (struct loop *);
  int flow_loop_nodes_find (basic_block, struct loop *);
! void fix_loop_structure (struct loops *, bitmap changed_bbs);
! void mark_irreducible_loops (struct loops *);
! void mark_single_exit_loops (struct loops *);
  
  /* Loop data structure manipulation/querying.  */
  extern void flow_loop_tree_node_add (struct loop *, struct loop *);
--- 191,205 ----
  /* Loop recognition.  */
  extern int flow_loops_find (struct loops *);
  extern void flow_loops_free (struct loops *);
! extern void flow_loops_dump (FILE *,
  			     void (*)(const struct loop *, FILE *, int), int);
  extern void flow_loop_dump (const struct loop *, FILE *,
  			    void (*)(const struct loop *, FILE *, int), int);
  extern void flow_loop_free (struct loop *);
  int flow_loop_nodes_find (basic_block, struct loop *);
! void fix_loop_structure (bitmap changed_bbs);
! void mark_irreducible_loops (void);
! void mark_single_exit_loops (void);
  
  /* Loop data structure manipulation/querying.  */
  extern void flow_loop_tree_node_add (struct loop *, struct loop *);
*************** extern int num_loop_insns (struct loop *
*** 213,219 ****
  extern int average_num_loop_insns (struct loop *);
  extern unsigned get_loop_level (const struct loop *);
  extern bool loop_exit_edge_p (const struct loop *, edge);
! extern void mark_loop_exit_edges (struct loops *);
  
  /* Loops & cfg manipulation.  */
  extern basic_block *get_loop_body (const struct loop *);
--- 213,219 ----
  extern int average_num_loop_insns (struct loop *);
  extern unsigned get_loop_level (const struct loop *);
  extern bool loop_exit_edge_p (const struct loop *, edge);
! extern void mark_loop_exit_edges (void);
  
  /* Loops & cfg manipulation.  */
  extern basic_block *get_loop_body (const struct loop *);
*************** extern edge loop_latch_edge (const struc
*** 230,236 ****
  extern void add_bb_to_loop (basic_block, struct loop *);
  extern void remove_bb_from_loops (basic_block);
  
! extern void cancel_loop_tree (struct loops *, struct loop *);
  
  extern int fix_loop_placement (struct loop *);
  
--- 230,236 ----
  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 int fix_loop_placement (struct loop *);
  
*************** enum
*** 239,248 ****
    CP_SIMPLE_PREHEADERS = 1
  };
  
! extern void create_preheaders (struct loops *, int);
! extern void force_single_succ_latches (struct loops *);
  
! extern void verify_loop_structure (struct loops *);
  
  /* Loop analysis.  */
  extern bool just_once_each_iteration_p (const struct loop *, basic_block);
--- 239,248 ----
    CP_SIMPLE_PREHEADERS = 1
  };
  
! extern void create_preheaders (int);
! extern void force_single_succ_latches (void);
  
! extern void verify_loop_structure (void);
  
  /* Loop analysis.  */
  extern bool just_once_each_iteration_p (const struct loop *, basic_block);
*************** extern bool can_duplicate_loop_p (struct
*** 259,274 ****
  #define DLTHE_FLAG_COMPLETTE_PEEL 4	/* Update frequencies expecting
  					   a complete peeling.  */
  
! extern struct loop * duplicate_loop (struct loops *, struct loop *,
! 				     struct loop *);
! extern bool duplicate_loop_to_header_edge (struct loop *, edge, struct loops *,
  					   unsigned, sbitmap, edge, edge *,
  					   unsigned *, int);
! extern struct loop *loopify (struct loops *, edge, edge,
  			     basic_block, edge, edge, bool);
! struct loop * loop_version (struct loops *, struct loop *, void *,
  			    basic_block *, bool);
! extern bool remove_path (struct loops *, edge);
  
  /* Induction variable analysis.  */
  
--- 259,273 ----
  #define DLTHE_FLAG_COMPLETTE_PEEL 4	/* Update frequencies expecting
  					   a complete peeling.  */
  
! extern struct loop * duplicate_loop (struct loop *, struct loop *);
! extern bool duplicate_loop_to_header_edge (struct loop *, edge, 
  					   unsigned, sbitmap, edge, edge *,
  					   unsigned *, int);
! extern struct loop *loopify (edge, edge,
  			     basic_block, edge, edge, bool);
! struct loop * loop_version (struct loop *, void *,
  			    basic_block *, bool);
! extern bool remove_path (edge);
  
  /* Induction variable analysis.  */
  
*************** extern void loop_optimizer_init (unsigne
*** 397,403 ****
  extern void loop_optimizer_finalize (void);
  
  /* Optimization passes.  */
! extern void unswitch_loops (struct loops *);
  
  enum
  {
--- 396,402 ----
  extern void loop_optimizer_finalize (void);
  
  /* Optimization passes.  */
! extern void unswitch_loops (void);
  
  enum
  {
*************** enum
*** 406,413 ****
    UAP_UNROLL_ALL = 4	/* Enables unrolling of all loops.  */
  };
  
! extern void unroll_and_peel_loops (struct loops *, int);
! extern void doloop_optimize_loops (struct loops *);
! extern void move_loop_invariants (struct loops *);
  
  #endif /* GCC_CFGLOOP_H */
--- 405,412 ----
    UAP_UNROLL_ALL = 4	/* Enables unrolling of all loops.  */
  };
  
! extern void unroll_and_peel_loops (int);
! extern void doloop_optimize_loops (void);
! extern void move_loop_invariants (void);
  
  #endif /* GCC_CFGLOOP_H */
Index: tree-flow.h
===================================================================
*** tree-flow.h	(revision 119131)
--- tree-flow.h	(working copy)
*************** struct tree_niter_desc
*** 802,808 ****
  };
  
  /* In tree-vectorizer.c */
! unsigned vectorize_loops (struct loops *);
  extern bool vect_can_force_dr_alignment_p (tree, unsigned int);
  extern tree get_vectype_for_scalar_type (tree);
  
--- 802,808 ----
  };
  
  /* In tree-vectorizer.c */
! unsigned vectorize_loops (void);
  extern bool vect_can_force_dr_alignment_p (tree, unsigned int);
  extern tree get_vectype_for_scalar_type (tree);
  
*************** bool empty_block_p (basic_block);
*** 811,830 ****
  
  /* In tree-ssa-loop*.c  */
  
! void tree_ssa_lim (struct loops *);
! unsigned int tree_ssa_unswitch_loops (struct loops *);
! unsigned int canonicalize_induction_variables (struct loops *);
! unsigned int tree_unroll_loops_completely (struct loops *, bool);
! unsigned int tree_ssa_prefetch_arrays (struct loops *);
! unsigned int remove_empty_loops (struct loops *);
! void tree_ssa_iv_optimize (struct loops *);
  
  bool number_of_iterations_exit (struct loop *, edge,
  				struct tree_niter_desc *niter, bool);
  tree find_loop_niter (struct loop *, edge *);
  tree loop_niter_by_eval (struct loop *, edge);
  tree find_loop_niter_by_eval (struct loop *, edge *);
! void estimate_numbers_of_iterations (struct loops *);
  bool scev_probably_wraps_p (tree, tree, tree, struct loop *, bool);
  bool convert_affine_scev (struct loop *, tree, tree *, tree *, tree, bool);
  
--- 811,830 ----
  
  /* In tree-ssa-loop*.c  */
  
! void tree_ssa_lim (void);
! unsigned int tree_ssa_unswitch_loops (void);
! unsigned int canonicalize_induction_variables (void);
! unsigned int tree_unroll_loops_completely (bool);
! unsigned int tree_ssa_prefetch_arrays (void);
! unsigned int remove_empty_loops (void);
! void tree_ssa_iv_optimize (void);
  
  bool number_of_iterations_exit (struct loop *, edge,
  				struct tree_niter_desc *niter, bool);
  tree find_loop_niter (struct loop *, edge *);
  tree loop_niter_by_eval (struct loop *, edge);
  tree find_loop_niter_by_eval (struct loop *, edge *);
! void estimate_numbers_of_iterations (void);
  bool scev_probably_wraps_p (tree, tree, tree, struct loop *, bool);
  bool convert_affine_scev (struct loop *, tree, tree *, tree *, tree, bool);
  
*************** bool nowrap_type_p (tree);
*** 832,838 ****
  enum ev_direction {EV_DIR_GROWS, EV_DIR_DECREASES, EV_DIR_UNKNOWN};
  enum ev_direction scev_direction (tree);
  
! void free_numbers_of_iterations_estimates (struct loops *);
  void free_numbers_of_iterations_estimates_loop (struct loop *);
  void rewrite_into_loop_closed_ssa (bitmap, unsigned);
  void verify_loop_closed_ssa (void);
--- 832,838 ----
  enum ev_direction {EV_DIR_GROWS, EV_DIR_DECREASES, EV_DIR_UNKNOWN};
  enum ev_direction scev_direction (tree);
  
! void free_numbers_of_iterations_estimates (void);
  void free_numbers_of_iterations_estimates_loop (struct loop *);
  void rewrite_into_loop_closed_ssa (bitmap, unsigned);
  void verify_loop_closed_ssa (void);
*************** void standard_iv_increment_position (str
*** 845,862 ****
  				     bool *);
  basic_block ip_end_pos (struct loop *);
  basic_block ip_normal_pos (struct loop *);
! bool tree_duplicate_loop_to_header_edge (struct loop *, edge, struct loops *,
  					 unsigned int, sbitmap,
  					 edge, edge *,
  					 unsigned int *, int);
! struct loop *tree_ssa_loop_version (struct loops *, struct loop *, tree,
  				    basic_block *);
  tree expand_simple_operations (tree);
  void substitute_in_loop_info (struct loop *, tree, tree);
  edge single_dom_exit (struct loop *);
  bool can_unroll_loop_p (struct loop *loop, unsigned factor,
  			struct tree_niter_desc *niter);
! void tree_unroll_loop (struct loops *, struct loop *, unsigned,
  		       edge, struct tree_niter_desc *);
  bool contains_abnormal_ssa_name_p (tree);
  
--- 845,862 ----
  				     bool *);
  basic_block ip_end_pos (struct loop *);
  basic_block ip_normal_pos (struct loop *);
! bool tree_duplicate_loop_to_header_edge (struct loop *, edge,
  					 unsigned int, sbitmap,
  					 edge, edge *,
  					 unsigned int *, int);
! struct loop *tree_ssa_loop_version (struct loop *, tree,
  				    basic_block *);
  tree expand_simple_operations (tree);
  void substitute_in_loop_info (struct loop *, tree, tree);
  edge single_dom_exit (struct loop *);
  bool can_unroll_loop_p (struct loop *loop, unsigned factor,
  			struct tree_niter_desc *niter);
! void tree_unroll_loop (struct loop *, unsigned,
  		       edge, struct tree_niter_desc *);
  bool contains_abnormal_ssa_name_p (tree);
  
*************** void sra_init_cache (void);
*** 943,949 ****
  bool sra_type_can_be_decomposed_p (tree);
  
  /* In tree-loop-linear.c  */
! extern void linear_transform_loops (struct loops *);
  
  /* In tree-ssa-loop-ivopts.c  */
  bool expr_invariant_in_loop_p (struct loop *, tree);
--- 943,949 ----
  bool sra_type_can_be_decomposed_p (tree);
  
  /* In tree-loop-linear.c  */
! extern void linear_transform_loops (void);
  
  /* In tree-ssa-loop-ivopts.c  */
  bool expr_invariant_in_loop_p (struct loop *, tree);
Index: basic-block.h
===================================================================
*** basic-block.h	(revision 119131)
--- basic-block.h	(working copy)
*************** extern const struct gcov_ctr_summary *pr
*** 180,186 ****
  
  /* Declared in cfgloop.h.  */
  struct loop;
- struct loops;
  
  /* Declared in tree-flow.h.  */
  struct edge_prediction;
--- 180,185 ----



More information about the Gcc-patches mailing list