
	* tree-flow.h: Move some protoypes.  Include new tree-ssa-loop.h.
	(struct affine_iv, struct tree_niter_desc): Move to tree-ssa-loop.h.
	(enum move_pos): Move to tree-ssa-loop-im.h
	* cfgloop.h: Move some prototypes.
	* tree-flow-inline.h (loop_containing_stmt): Move to tree-ssa-loop.h.
	* tree-ssa-loop.h: New File.  Include other tree-ssa-loop-*.h files.
	(struct affine_iv, struct tree_niter_desc): Relocate from tree-flow.h.
	(loop_containing_stmt): Relocate from tree-flow-inline.h.
	* tree-ssa-loop-ch.c: (do_while_loop_p): Make static.
	* tree-ssa-loop-im.c (for_each_index): Move to tree-ssa-loop.c.
	(enum move_pos): Relocate here.
	(lsm_tmp_name_add, gen_lsm_tmp_name, get_lsm_tmp_name): Move to
	tree-ssa-loop.c.
	(execute_sm_if_changed_flag_set): Change get_lsm_tmp_name call.
	(tree_ssa_loop_im, gate_tree_ssa_loop_im, pass_data_lim, make_pass_lim):
	Relocate here from tree-ssa-loop.c.
	* tree-ssa-loop-ivcanon.c (tree_num_loop_insns): Move to 
	tree-ssa-loop.c.
	(loop_edge_to_cancel, unloop_loops): Make static.
	(tree_ssa_loop_ivcanon, gate_tree_ssa_loop_ivcanon, pass_data_iv_canon,
	make_pass_iv_canon): Relocate from tree-ssa-loop.c.
	(tree_complete_unroll, gate_tree_complete_unroll,
	pass_data_complete_unroll, make_pass_complete_unroll): Relocate here.
	(tree_complete_unroll_inner, gate_tree_complete_unroll_inner,
	pass_data_complete_unrolli, make_pass_complete_unrolli): Relocate here.
	* tree-ssa-loop-ivopts.c: Remove local prototypes.
	(stmt_invariant_in_loop_p): Remove unused function.
	* tree-ssa-loop-ivopts.h: New file.  Add prototypes.
	* tree-ssa-loop-manip.h: New file.  Add prototypes.
	* tree-ssa-loop-niter.c (double_int_cmp, bound_index,
	estimate_numbers_of_iterations_loop): Make static.
	* tree-ssa-loop-niter.h: New file.  Add prototypes.
	* tree-ssa-loop-prefetch.c (tree_ssa_loop_prefetch,
	gate_tree_ssa_loop_prefetch, pass_data_loop_prefetch,
	make_pass_loop_prefetch): Relocate from tree-ssa-loop.c.
	* tree-ssa-loop-unswitch.c (tree_ssa_loop_unswitch,
	gate_tree_ssa_loop_unswitch, pass_data_tree_unswitch,
	make_pass_tree_unswitch): Relocate from tree-ssa-loop.c.
	* tree-ssa-loop.c (tree_ssa_loop_im, gate_tree_ssa_loop_im,
	pass_data_lim, make_pass_lim): Move to tree-ssa-loop-im.c.
	(tree_ssa_loop_unswitch, gate_tree_ssa_loop_unswitch,
	pass_data_tree_unswitch, make_pass_tree_unswitch): Move.
	(tree_ssa_loop_ivcanon, gate_tree_ssa_loop_ivcanon, pass_data_iv_canon,
	make_pass_iv_canon, tree_complete_unroll, gate_tree_complete_unroll,
	pass_data_complete_unroll, make_pass_complete_unroll,
	tree_complete_unroll_inner, gate_tree_complete_unroll_inner,
	pass_data_complete_unrolli, make_pass_complete_unrolli): Move to
	tree-ssa-loop-ivcanon.c.
	(tree_ssa_loop_prefetch, gate_tree_ssa_loop_prefetch,
	pass_data_loop_prefetch, make_pass_loop_prefetch): Move to
	tree-ssa-loop-prefetch.c.
	(for_each_index, lsm_tmp_name_add, gen_lsm_tmp_name): Relocate from
	tree-ssa-loop-im.c.
	(get_lsm_tmp_name): Relocate and add suffix parameter.
	(tree_num_loop_insns): Relocate from tree-ssa-ivcanon.c.
	* tree-scalar-evolution.h (simple_iv): Don't use affive_iv typedef.
	* loop-iv.c: Include tree-ssa-loop-niter.h.
	* loop-unroll.c: Include tree-ssa-loop-niter.h.
	* loop-unswitch.c: Include tree-ssa-loop-niter.h.

Index: tree-flow.h
===================================================================
*** tree-flow.h	(revision 203243)
--- tree-flow.h	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 35,40 ****
--- 35,41 ----
  #include "tree-pretty-print.h"
  #include "gimple-low.h"
  #include "tree-into-ssa.h"
+ #include "tree-ssa-loop.h"
  
  /* This structure is used to map a gimple statement to a label,
     or list of labels to represent transaction restart.  */
*************** extern basic_block move_sese_region_to_f
*** 244,352 ****
  void remove_edge_and_dominated_blocks (edge);
  bool tree_node_can_be_shared (tree);
  
- /* In tree-ssa-loop-ch.c  */
- bool do_while_loop_p (struct loop *);
- 
- /* Affine iv.  */
- 
- typedef struct
- {
-   /* Iv = BASE + STEP * i.  */
-   tree base, step;
- 
-   /* True if this iv does not overflow.  */
-   bool no_overflow;
- } affine_iv;
- 
- /* Description of number of iterations of a loop.  All the expressions inside
-    the structure can be evaluated at the end of the loop's preheader
-    (and due to ssa form, also anywhere inside the body of the loop).  */
- 
- struct tree_niter_desc
- {
-   tree assumptions;	/* The boolean expression.  If this expression evaluates
- 			   to false, then the other fields in this structure
- 			   should not be used; there is no guarantee that they
- 			   will be correct.  */
-   tree may_be_zero;	/* The boolean expression.  If it evaluates to true,
- 			   the loop will exit in the first iteration (i.e.
- 			   its latch will not be executed), even if the niter
- 			   field says otherwise.  */
-   tree niter;		/* The expression giving the number of iterations of
- 			   a loop (provided that assumptions == true and
- 			   may_be_zero == false), more precisely the number
- 			   of executions of the latch of the loop.  */
-   double_int max;	/* The upper bound on the number of iterations of
- 			   the loop.  */
- 
-   /* The simplified shape of the exit condition.  The loop exits if
-      CONTROL CMP BOUND is false, where CMP is one of NE_EXPR,
-      LT_EXPR, or GT_EXPR, and step of CONTROL is positive if CMP is
-      LE_EXPR and negative if CMP is GE_EXPR.  This information is used
-      by loop unrolling.  */
-   affine_iv control;
-   tree bound;
-   enum tree_code cmp;
- };
  
  
  /* In tree-ssa-loop*.c  */
  
- unsigned int tree_ssa_lim (void);
- unsigned int tree_ssa_unswitch_loops (void);
- unsigned int canonicalize_induction_variables (void);
- unsigned int tree_unroll_loops_completely (bool, bool);
- unsigned int tree_ssa_prefetch_arrays (void);
- void tree_ssa_iv_optimize (void);
  unsigned tree_predictive_commoning (void);
- tree canonicalize_loop_ivs (struct loop *, tree *, bool);
  bool parallelize_loops (void);
  
- bool loop_only_exit_p (const struct loop *, const_edge);
- bool number_of_iterations_exit (struct loop *, edge,
- 				struct tree_niter_desc *niter, bool,
- 				bool every_iteration = true);
- 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, gimple, struct loop *, bool);
  bool convert_affine_scev (struct loop *, tree, tree *, tree *, gimple, bool);
  
- bool nowrap_type_p (tree);
  enum ev_direction {EV_DIR_GROWS, EV_DIR_DECREASES, EV_DIR_UNKNOWN};
  enum ev_direction scev_direction (const_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 (bool);
- bool for_each_index (tree *, bool (*) (tree, tree *, void *), void *);
- void create_iv (tree, tree, tree, struct loop *, gimple_stmt_iterator *, bool,
- 		tree *, tree *);
- basic_block split_loop_exit_edge (edge);
- void standard_iv_increment_position (struct loop *, gimple_stmt_iterator *,
- 				     bool *);
- basic_block ip_end_pos (struct loop *);
- basic_block ip_normal_pos (struct loop *);
- bool gimple_duplicate_loop_to_header_edge (struct loop *, edge,
- 					 unsigned int, sbitmap,
- 					 edge, vec<edge> *,
- 					 int);
  struct loop *slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *, edge);
- 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 *);
- typedef void (*transform_callback)(struct loop *, void *);
- void tree_transform_and_unroll_loop (struct loop *, unsigned,
- 				     edge, struct tree_niter_desc *,
- 				     transform_callback, void *);
- bool contains_abnormal_ssa_name_p (tree);
- bool stmt_dominates_stmt_p (gimple, gimple);
  
  /* In tree-ssa-threadedge.c */
  extern void threadedge_initialize_values (void);
--- 245,263 ----
*************** extern void thread_across_edge (gimple, 
*** 362,380 ****
  				vec<tree> *, tree (*) (gimple, gimple));
  extern void propagate_threaded_block_debug_into (basic_block, basic_block);
  
- /* In tree-ssa-loop-im.c  */
- /* The possibilities of statement movement.  */
- 
- enum move_pos
-   {
-     MOVE_IMPOSSIBLE,		/* No movement -- side effect expression.  */
-     MOVE_PRESERVE_EXECUTION,	/* Must not cause the non-executed statement
- 				   become executed -- memory accesses, ... */
-     MOVE_POSSIBLE		/* Unlimited movement.  */
-   };
- extern enum move_pos movement_possibility (gimple);
- char *get_lsm_tmp_name (tree, unsigned);
- 
  /* In tree-flow-inline.h  */
  static inline bool unmodifiable_var_p (const_tree);
  static inline bool ref_contains_array_ref (const_tree);
--- 273,278 ----
*************** extern void graphite_transform_loops (vo
*** 417,430 ****
  /* In tree-data-ref.c  */
  extern void tree_check_data_deps (void);
  
- /* In tree-ssa-loop-ivopts.c  */
- bool expr_invariant_in_loop_p (struct loop *, tree);
- bool stmt_invariant_in_loop_p (struct loop *, gimple);
- struct loop *outermost_invariant_loop_for_expr (struct loop *, tree);
- bool multiplier_allowed_in_address_p (HOST_WIDE_INT, enum machine_mode,
- 				      addr_space_t);
- bool may_be_nonaddressable_p (tree expr);
- 
  /* In gimplify.c  */
  tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree);
  tree force_gimple_operand (tree, gimple_seq *, bool, tree);
--- 315,320 ----
Index: cfgloop.h
===================================================================
*** cfgloop.h	(revision 203243)
--- cfgloop.h	(working copy)
*************** extern bool flow_bb_inside_loop_p (const
*** 255,261 ****
  extern struct loop * find_common_loop (struct loop *, struct loop *);
  struct loop *superloop_at_depth (struct loop *, unsigned);
  struct eni_weights_d;
- extern unsigned tree_num_loop_insns (struct loop *, struct eni_weights_d *);
  extern int num_loop_insns (const struct loop *);
  extern int average_num_loop_insns (const struct loop *);
  extern unsigned get_loop_level (const struct loop *);
--- 255,260 ----
*************** gcov_type expected_loop_iterations_unbou
*** 306,321 ****
  extern unsigned expected_loop_iterations (const struct loop *);
  extern rtx doloop_condition_get (rtx);
  
- void estimate_numbers_of_iterations_loop (struct loop *);
- void record_niter_bound (struct loop *, double_int, bool, bool);
- bool estimated_loop_iterations (struct loop *, double_int *);
- bool max_loop_iterations (struct loop *, double_int *);
- HOST_WIDE_INT estimated_loop_iterations_int (struct loop *);
- HOST_WIDE_INT max_loop_iterations_int (struct loop *);
- bool max_stmt_executions (struct loop *, double_int *);
- bool estimated_stmt_executions (struct loop *, double_int *);
- HOST_WIDE_INT max_stmt_executions_int (struct loop *);
- HOST_WIDE_INT estimated_stmt_executions_int (struct loop *);
  
  /* Loop manipulation.  */
  extern bool can_duplicate_loop_p (const struct loop *loop);
--- 305,310 ----
*************** enum
*** 735,741 ****
  extern void unroll_and_peel_loops (int);
  extern void doloop_optimize_loops (void);
  extern void move_loop_invariants (void);
- extern bool finite_loop_p (struct loop *);
  extern void scale_loop_profile (struct loop *loop, int scale, gcov_type iteration_bound);
  extern vec<basic_block> get_loop_hot_path (const struct loop *loop);
  
--- 724,729 ----
Index: tree-flow-inline.h
===================================================================
*** tree-flow-inline.h	(revision 203243)
--- tree-flow-inline.h	(working copy)
*************** may_be_aliased (const_tree var)
*** 107,127 ****
  	      || TREE_ADDRESSABLE (var)));
  }
  
- 
- /* Returns the loop of the statement STMT.  */
- 
- static inline struct loop *
- loop_containing_stmt (gimple stmt)
- {
-   basic_block bb = gimple_bb (stmt);
-   if (!bb)
-     return NULL;
- 
-   return bb->loop_father;
- }
- 
- 
- 
  /* Return true if VAR cannot be modified by the program.  */
  
  static inline bool
--- 107,112 ----
Index: tree-ssa-loop.h
===================================================================
*** tree-ssa-loop.h	(revision 0)
--- tree-ssa-loop.h	(revision 0)
***************
*** 0 ****
--- 1,85 ----
+ /* Header file for SSA loop optimizations.
+    Copyright (C) 2013 Free Software Foundation, Inc.
+ 
+ This file is part of GCC.
+ 
+ GCC is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 3, or (at your option) any later
+ version.
+ 
+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+  for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3.  If not see
+ <http://www.gnu.org/licenses/>.  */
+ 
+ #ifndef GCC_TREE_SSA_LOOP_H
+ #define GCC_TREE_SSA_LOOP_H
+ 
+ #include "tree-ssa-loop-ivopts.h"
+ #include "tree-ssa-loop-manip.h"
+ #include "tree-ssa-loop-niter.h"
+ 
+ /* Affine iv.  */
+ 
+ typedef struct affine_iv_d
+ {
+   /* Iv = BASE + STEP * i.  */
+   tree base, step;
+ 
+   /* True if this iv does not overflow.  */
+   bool no_overflow;
+ } affine_iv;
+ 
+ /* Description of number of iterations of a loop.  All the expressions inside
+    the structure can be evaluated at the end of the loop's preheader
+    (and due to ssa form, also anywhere inside the body of the loop).  */
+ 
+ struct tree_niter_desc
+ {
+   tree assumptions;	/* The boolean expression.  If this expression evaluates
+ 			   to false, then the other fields in this structure
+ 			   should not be used; there is no guarantee that they
+ 			   will be correct.  */
+   tree may_be_zero;	/* The boolean expression.  If it evaluates to true,
+ 			   the loop will exit in the first iteration (i.e.
+ 			   its latch will not be executed), even if the niter
+ 			   field says otherwise.  */
+   tree niter;		/* The expression giving the number of iterations of
+ 			   a loop (provided that assumptions == true and
+ 			   may_be_zero == false), more precisely the number
+ 			   of executions of the latch of the loop.  */
+   double_int max;	/* The upper bound on the number of iterations of
+ 			   the loop.  */
+ 
+   /* The simplified shape of the exit condition.  The loop exits if
+      CONTROL CMP BOUND is false, where CMP is one of NE_EXPR,
+      LT_EXPR, or GT_EXPR, and step of CONTROL is positive if CMP is
+      LE_EXPR and negative if CMP is GE_EXPR.  This information is used
+      by loop unrolling.  */
+   affine_iv control;
+   tree bound;
+   enum tree_code cmp;
+ };
+ 
+ extern bool for_each_index (tree *, bool (*) (tree, tree *, void *), void *);
+ extern char *get_lsm_tmp_name (tree ref, unsigned n, const char *suffix = NULL);
+ extern unsigned tree_num_loop_insns (struct loop *, struct eni_weights_d *);
+ 
+ /* Returns the loop of the statement STMT.  */
+ 
+ static inline struct loop *
+ loop_containing_stmt (gimple stmt)
+ {
+   basic_block bb = gimple_bb (stmt);
+   if (!bb)
+     return NULL;
+ 
+   return bb->loop_father;
+ }
+ 
+ #endif /* GCC_TREE_SSA_LOOP_H */
Index: tree-ssa-loop-ch.c
===================================================================
*** tree-ssa-loop-ch.c	(revision 203243)
--- tree-ssa-loop-ch.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 29,35 ****
  #include "cfgloop.h"
  #include "tree-inline.h"
  #include "flags.h"
- #include "tree-inline.h"
  
  /* Duplicates headers of loops if they are small enough, so that the statements
     in the loop body are always executed when the loop is entered.  This
--- 29,34 ----
*************** should_duplicate_loop_header_p (basic_bl
*** 100,106 ****
  
  /* Checks whether LOOP is a do-while style loop.  */
  
! bool
  do_while_loop_p (struct loop *loop)
  {
    gimple stmt = last_stmt (loop->latch);
--- 99,105 ----
  
  /* Checks whether LOOP is a do-while style loop.  */
  
! static bool
  do_while_loop_p (struct loop *loop)
  {
    gimple stmt = last_stmt (loop->latch);
Index: tree-ssa-loop-im.c
===================================================================
*** tree-ssa-loop-im.c	(revision 203243)
--- tree-ssa-loop-im.c	(working copy)
*************** clear_lim_data (gimple stmt)
*** 242,339 ****
    *p = NULL;
  }
  
- /* Calls CBCK for each index in memory reference ADDR_P.  There are two
-    kinds situations handled; in each of these cases, the memory reference
-    and DATA are passed to the callback:
- 
-    Access to an array: ARRAY_{RANGE_}REF (base, index).  In this case we also
-    pass the pointer to the index to the callback.
- 
-    Pointer dereference: INDIRECT_REF (addr).  In this case we also pass the
-    pointer to addr to the callback.
- 
-    If the callback returns false, the whole search stops and false is returned.
-    Otherwise the function returns true after traversing through the whole
-    reference *ADDR_P.  */
  
! bool
! for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
! {
!   tree *nxt, *idx;
! 
!   for (; ; addr_p = nxt)
!     {
!       switch (TREE_CODE (*addr_p))
! 	{
! 	case SSA_NAME:
! 	  return cbck (*addr_p, addr_p, data);
! 
! 	case MEM_REF:
! 	  nxt = &TREE_OPERAND (*addr_p, 0);
! 	  return cbck (*addr_p, nxt, data);
! 
! 	case BIT_FIELD_REF:
! 	case VIEW_CONVERT_EXPR:
! 	case REALPART_EXPR:
! 	case IMAGPART_EXPR:
! 	  nxt = &TREE_OPERAND (*addr_p, 0);
! 	  break;
! 
! 	case COMPONENT_REF:
! 	  /* If the component has varying offset, it behaves like index
! 	     as well.  */
! 	  idx = &TREE_OPERAND (*addr_p, 2);
! 	  if (*idx
! 	      && !cbck (*addr_p, idx, data))
! 	    return false;
! 
! 	  nxt = &TREE_OPERAND (*addr_p, 0);
! 	  break;
! 
! 	case ARRAY_REF:
! 	case ARRAY_RANGE_REF:
! 	  nxt = &TREE_OPERAND (*addr_p, 0);
! 	  if (!cbck (*addr_p, &TREE_OPERAND (*addr_p, 1), data))
! 	    return false;
! 	  break;
! 
! 	case VAR_DECL:
! 	case PARM_DECL:
! 	case CONST_DECL:
! 	case STRING_CST:
! 	case RESULT_DECL:
! 	case VECTOR_CST:
! 	case COMPLEX_CST:
! 	case INTEGER_CST:
! 	case REAL_CST:
! 	case FIXED_CST:
! 	case CONSTRUCTOR:
! 	  return true;
! 
! 	case ADDR_EXPR:
! 	  gcc_assert (is_gimple_min_invariant (*addr_p));
! 	  return true;
! 
! 	case TARGET_MEM_REF:
! 	  idx = &TMR_BASE (*addr_p);
! 	  if (*idx
! 	      && !cbck (*addr_p, idx, data))
! 	    return false;
! 	  idx = &TMR_INDEX (*addr_p);
! 	  if (*idx
! 	      && !cbck (*addr_p, idx, data))
! 	    return false;
! 	  idx = &TMR_INDEX2 (*addr_p);
! 	  if (*idx
! 	      && !cbck (*addr_p, idx, data))
! 	    return false;
! 	  return true;
  
- 	default:
-     	  gcc_unreachable ();
- 	}
-     }
- }
  
  /* If it is possible to hoist the statement STMT unconditionally,
     returns MOVE_POSSIBLE.
--- 242,257 ----
    *p = NULL;
  }
  
  
! /* The possibilities of statement movement.  */
! enum move_pos
!   {
!     MOVE_IMPOSSIBLE,		/* No movement -- side effect expression.  */
!     MOVE_PRESERVE_EXECUTION,	/* Must not cause the non-executed statement
! 				   become executed -- memory accesses, ... */
!     MOVE_POSSIBLE		/* Unlimited movement.  */
!   };
  
  
  /* If it is possible to hoist the statement STMT unconditionally,
     returns MOVE_POSSIBLE.
*************** first_mem_ref_loc (struct loop *loop, me
*** 1741,1862 ****
    return locp;
  }
  
- /* The name and the length of the currently generated variable
-    for lsm.  */
- #define MAX_LSM_NAME_LENGTH 40
- static char lsm_tmp_name[MAX_LSM_NAME_LENGTH + 1];
- static int lsm_tmp_name_length;
- 
- /* Adds S to lsm_tmp_name.  */
- 
- static void
- lsm_tmp_name_add (const char *s)
- {
-   int l = strlen (s) + lsm_tmp_name_length;
-   if (l > MAX_LSM_NAME_LENGTH)
-     return;
- 
-   strcpy (lsm_tmp_name + lsm_tmp_name_length, s);
-   lsm_tmp_name_length = l;
- }
- 
- /* Stores the name for temporary variable that replaces REF to
-    lsm_tmp_name.  */
- 
- static void
- gen_lsm_tmp_name (tree ref)
- {
-   const char *name;
- 
-   switch (TREE_CODE (ref))
-     {
-     case MEM_REF:
-     case TARGET_MEM_REF:
-       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
-       lsm_tmp_name_add ("_");
-       break;
- 
-     case ADDR_EXPR:
-       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
-       break;
- 
-     case BIT_FIELD_REF:
-     case VIEW_CONVERT_EXPR:
-     case ARRAY_RANGE_REF:
-       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
-       break;
- 
-     case REALPART_EXPR:
-       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
-       lsm_tmp_name_add ("_RE");
-       break;
- 
-     case IMAGPART_EXPR:
-       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
-       lsm_tmp_name_add ("_IM");
-       break;
- 
-     case COMPONENT_REF:
-       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
-       lsm_tmp_name_add ("_");
-       name = get_name (TREE_OPERAND (ref, 1));
-       if (!name)
- 	name = "F";
-       lsm_tmp_name_add (name);
-       break;
- 
-     case ARRAY_REF:
-       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
-       lsm_tmp_name_add ("_I");
-       break;
- 
-     case SSA_NAME:
-     case VAR_DECL:
-     case PARM_DECL:
-       name = get_name (ref);
-       if (!name)
- 	name = "D";
-       lsm_tmp_name_add (name);
-       break;
- 
-     case STRING_CST:
-       lsm_tmp_name_add ("S");
-       break;
- 
-     case RESULT_DECL:
-       lsm_tmp_name_add ("R");
-       break;
- 
-     case INTEGER_CST:
-       /* Nothing.  */
-       break;
- 
-     default:
-       gcc_unreachable ();
-     }
- }
- 
- /* Determines name for temporary variable that replaces REF.
-    The name is accumulated into the lsm_tmp_name variable.
-    N is added to the name of the temporary.  */
- 
- char *
- get_lsm_tmp_name (tree ref, unsigned n)
- {
-   char ns[2];
- 
-   lsm_tmp_name_length = 0;
-   gen_lsm_tmp_name (ref);
-   lsm_tmp_name_add ("_lsm");
-   if (n < 10)
-     {
-       ns[0] = '0' + n;
-       ns[1] = 0;
-       lsm_tmp_name_add (ns);
-     }
-   return lsm_tmp_name;
- }
- 
  struct prev_flag_edges {
    /* Edge to insert new flag comparison code.  */
    edge append_cond_position;
--- 1659,1664 ----
*************** static tree
*** 2026,2033 ****
  execute_sm_if_changed_flag_set (struct loop *loop, mem_ref_p ref)
  {
    tree flag;
!   char *str = get_lsm_tmp_name (ref->mem.ref, ~0);
!   lsm_tmp_name_add ("_flag");
    flag = create_tmp_reg (boolean_type_node, str);
    for_all_locs_in_loop (loop, ref, sm_set_flag_if_changed (flag));
    return flag;
--- 1828,1834 ----
  execute_sm_if_changed_flag_set (struct loop *loop, mem_ref_p ref)
  {
    tree flag;
!   char *str = get_lsm_tmp_name (ref->mem.ref, ~0, "_flag");
    flag = create_tmp_reg (boolean_type_node, str);
    for_all_locs_in_loop (loop, ref, sm_set_flag_if_changed (flag));
    return flag;
*************** tree_ssa_lim (void)
*** 2639,2641 ****
--- 2440,2500 ----
  
    return todo;
  }
+ 
+ /* Loop invariant motion pass.  */
+ 
+ static unsigned int
+ tree_ssa_loop_im (void)
+ {
+   if (number_of_loops (cfun) <= 1)
+     return 0;
+ 
+   return tree_ssa_lim ();
+ }
+ 
+ static bool
+ gate_tree_ssa_loop_im (void)
+ {
+   return flag_tree_loop_im != 0;
+ }
+ 
+ namespace {
+ 
+ const pass_data pass_data_lim =
+ {
+   GIMPLE_PASS, /* type */
+   "lim", /* name */
+   OPTGROUP_LOOP, /* optinfo_flags */
+   true, /* has_gate */
+   true, /* has_execute */
+   TV_LIM, /* tv_id */
+   PROP_cfg, /* properties_required */
+   0, /* properties_provided */
+   0, /* properties_destroyed */
+   0, /* todo_flags_start */
+   0, /* todo_flags_finish */
+ };
+ 
+ class pass_lim : public gimple_opt_pass
+ {
+ public:
+   pass_lim (gcc::context *ctxt)
+     : gimple_opt_pass (pass_data_lim, ctxt)
+   {}
+ 
+   /* opt_pass methods: */
+   opt_pass * clone () { return new pass_lim (m_ctxt); }
+   bool gate () { return gate_tree_ssa_loop_im (); }
+   unsigned int execute () { return tree_ssa_loop_im (); }
+ 
+ }; // class pass_lim
+ 
+ } // anon namespace
+ 
+ gimple_opt_pass *
+ make_pass_lim (gcc::context *ctxt)
+ {
+   return new pass_lim (ctxt);
+ }
+ 
+ 
Index: tree-ssa-loop-ivcanon.c
===================================================================
*** tree-ssa-loop-ivcanon.c	(revision 203243)
--- tree-ssa-loop-ivcanon.c	(working copy)
*************** create_canonical_iv (struct loop *loop, 
*** 107,129 ****
    update_stmt (cond);
  }
  
- /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS.  */
- 
- unsigned
- tree_num_loop_insns (struct loop *loop, eni_weights *weights)
- {
-   basic_block *body = get_loop_body (loop);
-   gimple_stmt_iterator gsi;
-   unsigned size = 0, i;
- 
-   for (i = 0; i < loop->num_nodes; i++)
-     for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
-       size += estimate_num_insns (gsi_stmt (gsi), weights);
-   free (body);
- 
-   return size;
- }
- 
  /* Describe size of loop as detected by tree_estimate_loop_size.  */
  struct loop_size
  {
--- 107,112 ----
*************** estimated_unrolled_size (struct loop_siz
*** 422,428 ****
     loop-niter identified as having undefined effect in the last iteration.
     The other cases are hopefully rare and will be cleaned up later.  */
  
! edge
  loop_edge_to_cancel (struct loop *loop)
  {
    vec<edge> exits;
--- 405,411 ----
     loop-niter identified as having undefined effect in the last iteration.
     The other cases are hopefully rare and will be cleaned up later.  */
  
! static edge
  loop_edge_to_cancel (struct loop *loop)
  {
    vec<edge> exits;
*************** static vec<int> loops_to_unloop_nunroll;
*** 598,604 ****
     LOOP_CLOSED_SSA_INVALIDATED is used to bookkepp the case
     when we need to go into loop closed SSA form.  */
  
! void
  unloop_loops (bitmap loop_closed_ssa_invalidated,
  	      bool *irred_invalidated)
  {
--- 581,587 ----
     LOOP_CLOSED_SSA_INVALIDATED is used to bookkepp the case
     when we need to go into loop closed SSA form.  */
  
! static void
  unloop_loops (bitmap loop_closed_ssa_invalidated,
  	      bool *irred_invalidated)
  {
*************** tree_unroll_loops_completely (bool may_i
*** 1253,1255 ****
--- 1236,1417 ----
  
    return 0;
  }
+ 
+ /* Canonical induction variable creation pass.  */
+ 
+ static unsigned int
+ tree_ssa_loop_ivcanon (void)
+ {
+   if (number_of_loops (cfun) <= 1)
+     return 0;
+ 
+   return canonicalize_induction_variables ();
+ }
+ 
+ static bool
+ gate_tree_ssa_loop_ivcanon (void)
+ {
+   return flag_tree_loop_ivcanon != 0;
+ }
+ 
+ namespace {
+ 
+ const pass_data pass_data_iv_canon =
+ {
+   GIMPLE_PASS, /* type */
+   "ivcanon", /* name */
+   OPTGROUP_LOOP, /* optinfo_flags */
+   true, /* has_gate */
+   true, /* has_execute */
+   TV_TREE_LOOP_IVCANON, /* tv_id */
+   ( PROP_cfg | PROP_ssa ), /* properties_required */
+   0, /* properties_provided */
+   0, /* properties_destroyed */
+   0, /* todo_flags_start */
+   0, /* todo_flags_finish */
+ };
+ 
+ class pass_iv_canon : public gimple_opt_pass
+ {
+ public:
+   pass_iv_canon (gcc::context *ctxt)
+     : gimple_opt_pass (pass_data_iv_canon, ctxt)
+   {}
+ 
+   /* opt_pass methods: */
+   bool gate () { return gate_tree_ssa_loop_ivcanon (); }
+   unsigned int execute () { return tree_ssa_loop_ivcanon (); }
+ 
+ }; // class pass_iv_canon
+ 
+ } // anon namespace
+ 
+ gimple_opt_pass *
+ make_pass_iv_canon (gcc::context *ctxt)
+ {
+   return new pass_iv_canon (ctxt);
+ }
+ 
+ /* Complete unrolling of loops.  */
+ 
+ static unsigned int
+ tree_complete_unroll (void)
+ {
+   if (number_of_loops (cfun) <= 1)
+     return 0;
+ 
+   return tree_unroll_loops_completely (flag_unroll_loops
+ 				       || flag_peel_loops
+ 				       || optimize >= 3, true);
+ }
+ 
+ static bool
+ gate_tree_complete_unroll (void)
+ {
+   return true;
+ }
+ 
+ namespace {
+ 
+ const pass_data pass_data_complete_unroll =
+ {
+   GIMPLE_PASS, /* type */
+   "cunroll", /* name */
+   OPTGROUP_LOOP, /* optinfo_flags */
+   true, /* has_gate */
+   true, /* has_execute */
+   TV_COMPLETE_UNROLL, /* tv_id */
+   ( PROP_cfg | PROP_ssa ), /* properties_required */
+   0, /* properties_provided */
+   0, /* properties_destroyed */
+   0, /* todo_flags_start */
+   0, /* todo_flags_finish */
+ };
+ 
+ class pass_complete_unroll : public gimple_opt_pass
+ {
+ public:
+   pass_complete_unroll (gcc::context *ctxt)
+     : gimple_opt_pass (pass_data_complete_unroll, ctxt)
+   {}
+ 
+   /* opt_pass methods: */
+   bool gate () { return gate_tree_complete_unroll (); }
+   unsigned int execute () { return tree_complete_unroll (); }
+ 
+ }; // class pass_complete_unroll
+ 
+ } // anon namespace
+ 
+ gimple_opt_pass *
+ make_pass_complete_unroll (gcc::context *ctxt)
+ {
+   return new pass_complete_unroll (ctxt);
+ }
+ 
+ /* Complete unrolling of inner loops.  */
+ 
+ static unsigned int
+ tree_complete_unroll_inner (void)
+ {
+   unsigned ret = 0;
+ 
+   loop_optimizer_init (LOOPS_NORMAL
+ 		       | LOOPS_HAVE_RECORDED_EXITS);
+   if (number_of_loops (cfun) > 1)
+     {
+       scev_initialize ();
+       ret = tree_unroll_loops_completely (optimize >= 3, false);
+       free_numbers_of_iterations_estimates ();
+       scev_finalize ();
+     }
+   loop_optimizer_finalize ();
+ 
+   return ret;
+ }
+ 
+ static bool
+ gate_tree_complete_unroll_inner (void)
+ {
+   return optimize >= 2;
+ }
+ 
+ namespace {
+ 
+ const pass_data pass_data_complete_unrolli =
+ {
+   GIMPLE_PASS, /* type */
+   "cunrolli", /* name */
+   OPTGROUP_LOOP, /* optinfo_flags */
+   true, /* has_gate */
+   true, /* has_execute */
+   TV_COMPLETE_UNROLL, /* tv_id */
+   ( PROP_cfg | PROP_ssa ), /* properties_required */
+   0, /* properties_provided */
+   0, /* properties_destroyed */
+   0, /* todo_flags_start */
+   TODO_verify_flow, /* todo_flags_finish */
+ };
+ 
+ class pass_complete_unrolli : public gimple_opt_pass
+ {
+ public:
+   pass_complete_unrolli (gcc::context *ctxt)
+     : gimple_opt_pass (pass_data_complete_unrolli, ctxt)
+   {}
+ 
+   /* opt_pass methods: */
+   bool gate () { return gate_tree_complete_unroll_inner (); }
+   unsigned int execute () { return tree_complete_unroll_inner (); }
+ 
+ }; // class pass_complete_unrolli
+ 
+ } // anon namespace
+ 
+ gimple_opt_pass *
+ make_pass_complete_unrolli (gcc::context *ctxt)
+ {
+   return new pass_complete_unrolli (ctxt);
+ }
+ 
+ 
Index: tree-ssa-loop-ivopts.c
===================================================================
*** tree-ssa-loop-ivopts.c	(revision 203243)
--- tree-ssa-loop-ivopts.c	(working copy)
*************** single_dom_exit (struct loop *loop)
*** 452,458 ****
  
  /* Dumps information about the induction variable IV to FILE.  */
  
- extern void dump_iv (FILE *, struct iv *);
  void
  dump_iv (FILE *file, struct iv *iv)
  {
--- 452,457 ----
*************** dump_iv (FILE *file, struct iv *iv)
*** 497,503 ****
  
  /* Dumps information about the USE to FILE.  */
  
- extern void dump_use (FILE *, struct iv_use *);
  void
  dump_use (FILE *file, struct iv_use *use)
  {
--- 496,501 ----
*************** dump_use (FILE *file, struct iv_use *use
*** 541,547 ****
  
  /* Dumps information about the uses to FILE.  */
  
- extern void dump_uses (FILE *, struct ivopts_data *);
  void
  dump_uses (FILE *file, struct ivopts_data *data)
  {
--- 539,544 ----
*************** dump_uses (FILE *file, struct ivopts_dat
*** 559,565 ****
  
  /* Dumps information about induction variable candidate CAND to FILE.  */
  
- extern void dump_cand (FILE *, struct iv_cand *);
  void
  dump_cand (FILE *file, struct iv_cand *cand)
  {
--- 556,561 ----
*************** expr_invariant_in_loop_p (struct loop *l
*** 1454,1482 ****
    return true;
  }
  
- /* Returns true if statement STMT is obviously invariant in LOOP,
-    i.e. if all its operands on the RHS are defined outside of the LOOP.
-    LOOP should not be the function body.  */
- 
- bool
- stmt_invariant_in_loop_p (struct loop *loop, gimple stmt)
- {
-   unsigned i;
-   tree lhs;
- 
-   gcc_assert (loop_depth (loop) > 0);
- 
-   lhs = gimple_get_lhs (stmt);
-   for (i = 0; i < gimple_num_ops (stmt); i++)
-     {
-       tree op = gimple_op (stmt, i);
-       if (op != lhs && !expr_invariant_in_loop_p (loop, op))
- 	return false;
-     }
- 
-   return true;
- }
- 
  /* Cumulates the steps of indices into DATA and replaces their values with the
     initial ones.  Returns false when the value of the index cannot be determined.
     Callback for for_each_index.  */
--- 1450,1455 ----
Index: tree-ssa-loop-ivopts.h
===================================================================
*** tree-ssa-loop-ivopts.h	(revision 0)
--- tree-ssa-loop-ivopts.h	(revision 0)
***************
*** 0 ****
--- 1,36 ----
+ /* Header file for Induction variable optimizations.
+    Copyright (C) 2013 Free Software Foundation, Inc.
+ 
+ This file is part of GCC.
+ 
+ GCC is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 3, or (at your option) any later
+ version.
+ 
+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+  for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3.  If not see
+ <http://www.gnu.org/licenses/>.  */
+ 
+ #ifndef GCC_TREE_SSA_LOOP_IVOPTS_H
+ #define GCC_TREE_SSA_LOOP_IVOPTS_H
+ 
+ extern edge single_dom_exit (struct loop *);
+ extern void dump_iv (FILE *, struct iv *);
+ extern void dump_use (FILE *, struct iv_use *);
+ extern void dump_uses (FILE *, struct ivopts_data *);
+ extern void dump_cand (FILE *, struct iv_cand *);
+ extern bool contains_abnormal_ssa_name_p (tree);
+ extern struct loop *outermost_invariant_loop_for_expr (struct loop *, tree);
+ extern bool expr_invariant_in_loop_p (struct loop *, tree);
+ bool may_be_nonaddressable_p (tree expr);
+ bool multiplier_allowed_in_address_p (HOST_WIDE_INT, enum machine_mode,
+ 				      addr_space_t);
+ void tree_ssa_iv_optimize (void);
+ 
+ #endif /* GCC_TREE_SSA_LOOP_IVOPTS_H */
Index: tree-ssa-loop-manip.h
===================================================================
*** tree-ssa-loop-manip.h	(revision 0)
--- tree-ssa-loop-manip.h	(revision 0)
***************
*** 0 ****
--- 1,49 ----
+ /* Header file for High-level loop manipulation functions.
+    Copyright (C) 2013 Free Software Foundation, Inc.
+ 
+ This file is part of GCC.
+ 
+ GCC is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 3, or (at your option) any later
+ version.
+ 
+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+  for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3.  If not see
+ <http://www.gnu.org/licenses/>.  */
+ 
+ #ifndef GCC_TREE_SSA_LOOP_MANIP_H
+ #define GCC_TREE_SSA_LOOP_MANIP_H
+ 
+ typedef void (*transform_callback)(struct loop *, void *);
+ 
+ extern void create_iv (tree, tree, tree, struct loop *, gimple_stmt_iterator *,
+ 		       bool, tree *, tree *);
+ extern void rewrite_into_loop_closed_ssa (bitmap, unsigned);
+ extern void verify_loop_closed_ssa (bool);
+ extern basic_block split_loop_exit_edge (edge);
+ extern basic_block ip_end_pos (struct loop *);
+ extern basic_block ip_normal_pos (struct loop *);
+ extern void standard_iv_increment_position (struct loop *,
+ 					    gimple_stmt_iterator *, bool *);
+ extern bool gimple_duplicate_loop_to_header_edge (struct loop *, edge,
+ 						  unsigned int, sbitmap,
+ 						  edge, vec<edge> *,
+ 						  int);
+ extern bool can_unroll_loop_p (struct loop *loop, unsigned factor,
+ 			       struct tree_niter_desc *niter);
+ extern void tree_transform_and_unroll_loop (struct loop *, unsigned,
+ 					    edge, struct tree_niter_desc *,
+ 					    transform_callback, void *);
+ extern void tree_unroll_loop (struct loop *, unsigned,
+ 			      edge, struct tree_niter_desc *);
+ extern tree canonicalize_loop_ivs (struct loop *, tree *, bool);
+ 
+ 
+ 
+ #endif /* GCC_TREE_SSA_LOOP_MANIP_H */
Index: tree-ssa-loop-niter.c
===================================================================
*** tree-ssa-loop-niter.c	(revision 203243)
--- tree-ssa-loop-niter.c	(working copy)
*************** gcov_type_to_double_int (gcov_type val)
*** 3027,3033 ****
  
  /* Compare double ints, callback for qsort.  */
  
! int
  double_int_cmp (const void *p1, const void *p2)
  {
    const double_int *d1 = (const double_int *)p1;
--- 3027,3033 ----
  
  /* Compare double ints, callback for qsort.  */
  
! static int
  double_int_cmp (const void *p1, const void *p2)
  {
    const double_int *d1 = (const double_int *)p1;
*************** double_int_cmp (const void *p1, const vo
*** 3042,3048 ****
  /* Return index of BOUND in BOUNDS array sorted in increasing order.
     Lookup by binary search.  */
  
! int
  bound_index (vec<double_int> bounds, double_int bound)
  {
    unsigned int end = bounds.length ();
--- 3042,3048 ----
  /* Return index of BOUND in BOUNDS array sorted in increasing order.
     Lookup by binary search.  */
  
! static int
  bound_index (vec<double_int> bounds, double_int bound)
  {
    unsigned int end = bounds.length ();
*************** maybe_lower_iteration_bound (struct loop
*** 3349,3355 ****
  /* Records estimates on numbers of iterations of LOOP.  If USE_UNDEFINED_P
     is true also use estimates derived from undefined behavior.  */
  
! void
  estimate_numbers_of_iterations_loop (struct loop *loop)
  {
    vec<edge> exits;
--- 3349,3355 ----
  /* Records estimates on numbers of iterations of LOOP.  If USE_UNDEFINED_P
     is true also use estimates derived from undefined behavior.  */
  
! static void
  estimate_numbers_of_iterations_loop (struct loop *loop)
  {
    vec<edge> exits;
Index: tree-ssa-loop-niter.h
===================================================================
*** tree-ssa-loop-niter.h	(revision 0)
--- tree-ssa-loop-niter.h	(revision 0)
***************
*** 0 ****
--- 1,49 ----
+ /* Header file for loop interation estimates.
+    Copyright (C) 2013 Free Software Foundation, Inc.
+ 
+ This file is part of GCC.
+ 
+ GCC is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 3, or (at your option) any later
+ version.
+ 
+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+  for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3.  If not see
+ <http://www.gnu.org/licenses/>.  */
+ 
+ #ifndef GCC_TREE_SSA_LOOP_NITER_H
+ #define GCC_TREE_SSA_LOOP_NITER_H
+ 
+ extern tree expand_simple_operations (tree);
+ extern bool loop_only_exit_p (const struct loop *, const_edge);
+ extern bool number_of_iterations_exit (struct loop *, edge,
+ 				       struct tree_niter_desc *niter, bool,
+ 				       bool every_iteration = true);
+ extern tree find_loop_niter (struct loop *, edge *);
+ extern bool finite_loop_p (struct loop *);
+ extern tree loop_niter_by_eval (struct loop *, edge);
+ extern tree find_loop_niter_by_eval (struct loop *, edge *);
+ extern void record_niter_bound (struct loop *, double_int, bool, bool);
+ extern bool estimated_loop_iterations (struct loop *, double_int *);
+ extern bool max_loop_iterations (struct loop *, double_int *);
+ extern HOST_WIDE_INT estimated_loop_iterations_int (struct loop *);
+ extern HOST_WIDE_INT max_loop_iterations_int (struct loop *);
+ extern HOST_WIDE_INT max_stmt_executions_int (struct loop *);
+ extern HOST_WIDE_INT estimated_stmt_executions_int (struct loop *);
+ extern bool max_stmt_executions (struct loop *, double_int *);
+ extern bool estimated_stmt_executions (struct loop *, double_int *);
+ extern void estimate_numbers_of_iterations (void);
+ extern bool stmt_dominates_stmt_p (gimple, gimple);
+ extern bool nowrap_type_p (tree);
+ extern bool scev_probably_wraps_p (tree, tree, gimple, struct loop *, bool);
+ extern void free_numbers_of_iterations_estimates_loop (struct loop *);
+ extern void free_numbers_of_iterations_estimates (void);
+ extern void substitute_in_loop_info (struct loop *, tree, tree);
+ 
+ #endif /* GCC_TREE_SSA_LOOP_NITER_H */
Index: tree-ssa-loop-prefetch.c
===================================================================
*** tree-ssa-loop-prefetch.c	(revision 203243)
--- tree-ssa-loop-prefetch.c	(working copy)
*************** tree_ssa_prefetch_arrays (void)
*** 1988,1990 ****
--- 1988,2047 ----
    free_original_copy_tables ();
    return todo_flags;
  }
+ 
+ /* Prefetching.  */
+ 
+ static unsigned int
+ tree_ssa_loop_prefetch (void)
+ {
+   if (number_of_loops (cfun) <= 1)
+     return 0;
+ 
+   return tree_ssa_prefetch_arrays ();
+ }
+ 
+ static bool
+ gate_tree_ssa_loop_prefetch (void)
+ {
+   return flag_prefetch_loop_arrays > 0;
+ }
+ 
+ namespace {
+ 
+ const pass_data pass_data_loop_prefetch =
+ {
+   GIMPLE_PASS, /* type */
+   "aprefetch", /* name */
+   OPTGROUP_LOOP, /* optinfo_flags */
+   true, /* has_gate */
+   true, /* has_execute */
+   TV_TREE_PREFETCH, /* tv_id */
+   ( PROP_cfg | PROP_ssa ), /* properties_required */
+   0, /* properties_provided */
+   0, /* properties_destroyed */
+   0, /* todo_flags_start */
+   0, /* todo_flags_finish */
+ };
+ 
+ class pass_loop_prefetch : public gimple_opt_pass
+ {
+ public:
+   pass_loop_prefetch (gcc::context *ctxt)
+     : gimple_opt_pass (pass_data_loop_prefetch, ctxt)
+   {}
+ 
+   /* opt_pass methods: */
+   bool gate () { return gate_tree_ssa_loop_prefetch (); }
+   unsigned int execute () { return tree_ssa_loop_prefetch (); }
+ 
+ }; // class pass_loop_prefetch
+ 
+ } // anon namespace
+ 
+ gimple_opt_pass *
+ make_pass_loop_prefetch (gcc::context *ctxt)
+ {
+   return new pass_loop_prefetch (ctxt);
+ }
+ 
+ 
Index: tree-ssa-loop-unswitch.c
===================================================================
*** tree-ssa-loop-unswitch.c	(revision 203243)
--- tree-ssa-loop-unswitch.c	(working copy)
*************** tree_unswitch_loop (struct loop *loop,
*** 388,390 ****
--- 388,447 ----
  		       NULL, prob_true, prob_true,
  		       REG_BR_PROB_BASE - prob_true, false);
  }
+ 
+ /* Loop unswitching pass.  */
+ 
+ static unsigned int
+ tree_ssa_loop_unswitch (void)
+ {
+   if (number_of_loops (cfun) <= 1)
+     return 0;
+ 
+   return tree_ssa_unswitch_loops ();
+ }
+ 
+ static bool
+ gate_tree_ssa_loop_unswitch (void)
+ {
+   return flag_unswitch_loops != 0;
+ }
+ 
+ namespace {
+ 
+ const pass_data pass_data_tree_unswitch =
+ {
+   GIMPLE_PASS, /* type */
+   "unswitch", /* name */
+   OPTGROUP_LOOP, /* optinfo_flags */
+   true, /* has_gate */
+   true, /* has_execute */
+   TV_TREE_LOOP_UNSWITCH, /* tv_id */
+   PROP_cfg, /* properties_required */
+   0, /* properties_provided */
+   0, /* properties_destroyed */
+   0, /* todo_flags_start */
+   0, /* todo_flags_finish */
+ };
+ 
+ class pass_tree_unswitch : public gimple_opt_pass
+ {
+ public:
+   pass_tree_unswitch (gcc::context *ctxt)
+     : gimple_opt_pass (pass_data_tree_unswitch, ctxt)
+   {}
+ 
+   /* opt_pass methods: */
+   bool gate () { return gate_tree_ssa_loop_unswitch (); }
+   unsigned int execute () { return tree_ssa_loop_unswitch (); }
+ 
+ }; // class pass_tree_unswitch
+ 
+ } // anon namespace
+ 
+ gimple_opt_pass *
+ make_pass_tree_unswitch (gcc::context *ctxt)
+ {
+   return new pass_tree_unswitch (ctxt);
+ }
+ 
+ 
Index: tree-ssa-loop.c
===================================================================
*** tree-ssa-loop.c	(revision 203243)
--- tree-ssa-loop.c	(working copy)
*************** make_pass_tree_loop_init (gcc::context *
*** 134,250 ****
    return new pass_tree_loop_init (ctxt);
  }
  
- /* Loop invariant motion pass.  */
- 
- static unsigned int
- tree_ssa_loop_im (void)
- {
-   if (number_of_loops (cfun) <= 1)
-     return 0;
- 
-   return tree_ssa_lim ();
- }
- 
- static bool
- gate_tree_ssa_loop_im (void)
- {
-   return flag_tree_loop_im != 0;
- }
- 
- namespace {
- 
- const pass_data pass_data_lim =
- {
-   GIMPLE_PASS, /* type */
-   "lim", /* name */
-   OPTGROUP_LOOP, /* optinfo_flags */
-   true, /* has_gate */
-   true, /* has_execute */
-   TV_LIM, /* tv_id */
-   PROP_cfg, /* properties_required */
-   0, /* properties_provided */
-   0, /* properties_destroyed */
-   0, /* todo_flags_start */
-   0, /* todo_flags_finish */
- };
- 
- class pass_lim : public gimple_opt_pass
- {
- public:
-   pass_lim (gcc::context *ctxt)
-     : gimple_opt_pass (pass_data_lim, ctxt)
-   {}
- 
-   /* opt_pass methods: */
-   opt_pass * clone () { return new pass_lim (m_ctxt); }
-   bool gate () { return gate_tree_ssa_loop_im (); }
-   unsigned int execute () { return tree_ssa_loop_im (); }
- 
- }; // class pass_lim
- 
- } // anon namespace
- 
- gimple_opt_pass *
- make_pass_lim (gcc::context *ctxt)
- {
-   return new pass_lim (ctxt);
- }
- 
- /* Loop unswitching pass.  */
- 
- static unsigned int
- tree_ssa_loop_unswitch (void)
- {
-   if (number_of_loops (cfun) <= 1)
-     return 0;
- 
-   return tree_ssa_unswitch_loops ();
- }
- 
- static bool
- gate_tree_ssa_loop_unswitch (void)
- {
-   return flag_unswitch_loops != 0;
- }
- 
- namespace {
- 
- const pass_data pass_data_tree_unswitch =
- {
-   GIMPLE_PASS, /* type */
-   "unswitch", /* name */
-   OPTGROUP_LOOP, /* optinfo_flags */
-   true, /* has_gate */
-   true, /* has_execute */
-   TV_TREE_LOOP_UNSWITCH, /* tv_id */
-   PROP_cfg, /* properties_required */
-   0, /* properties_provided */
-   0, /* properties_destroyed */
-   0, /* todo_flags_start */
-   0, /* todo_flags_finish */
- };
- 
- class pass_tree_unswitch : public gimple_opt_pass
- {
- public:
-   pass_tree_unswitch (gcc::context *ctxt)
-     : gimple_opt_pass (pass_data_tree_unswitch, ctxt)
-   {}
- 
-   /* opt_pass methods: */
-   bool gate () { return gate_tree_ssa_loop_unswitch (); }
-   unsigned int execute () { return tree_ssa_loop_unswitch (); }
- 
- }; // class pass_tree_unswitch
- 
- } // anon namespace
- 
- gimple_opt_pass *
- make_pass_tree_unswitch (gcc::context *ctxt)
- {
-   return new pass_tree_unswitch (ctxt);
- }
- 
  /* Predictive commoning.  */
  
  static unsigned
--- 134,139 ----
*************** make_pass_check_data_deps (gcc::context 
*** 515,575 ****
    return new pass_check_data_deps (ctxt);
  }
  
- /* Canonical induction variable creation pass.  */
- 
- static unsigned int
- tree_ssa_loop_ivcanon (void)
- {
-   if (number_of_loops (cfun) <= 1)
-     return 0;
- 
-   return canonicalize_induction_variables ();
- }
- 
- static bool
- gate_tree_ssa_loop_ivcanon (void)
- {
-   return flag_tree_loop_ivcanon != 0;
- }
- 
- namespace {
- 
- const pass_data pass_data_iv_canon =
- {
-   GIMPLE_PASS, /* type */
-   "ivcanon", /* name */
-   OPTGROUP_LOOP, /* optinfo_flags */
-   true, /* has_gate */
-   true, /* has_execute */
-   TV_TREE_LOOP_IVCANON, /* tv_id */
-   ( PROP_cfg | PROP_ssa ), /* properties_required */
-   0, /* properties_provided */
-   0, /* properties_destroyed */
-   0, /* todo_flags_start */
-   0, /* todo_flags_finish */
- };
- 
- class pass_iv_canon : public gimple_opt_pass
- {
- public:
-   pass_iv_canon (gcc::context *ctxt)
-     : gimple_opt_pass (pass_data_iv_canon, ctxt)
-   {}
- 
-   /* opt_pass methods: */
-   bool gate () { return gate_tree_ssa_loop_ivcanon (); }
-   unsigned int execute () { return tree_ssa_loop_ivcanon (); }
- 
- }; // class pass_iv_canon
- 
- } // anon namespace
- 
- gimple_opt_pass *
- make_pass_iv_canon (gcc::context *ctxt)
- {
-   return new pass_iv_canon (ctxt);
- }
- 
  /* Propagation of constants using scev.  */
  
  static bool
--- 404,409 ----
*************** make_pass_record_bounds (gcc::context *c
*** 667,794 ****
    return new pass_record_bounds (ctxt);
  }
  
- /* Complete unrolling of loops.  */
- 
- static unsigned int
- tree_complete_unroll (void)
- {
-   if (number_of_loops (cfun) <= 1)
-     return 0;
- 
-   return tree_unroll_loops_completely (flag_unroll_loops
- 				       || flag_peel_loops
- 				       || optimize >= 3, true);
- }
- 
- static bool
- gate_tree_complete_unroll (void)
- {
-   return true;
- }
- 
- namespace {
- 
- const pass_data pass_data_complete_unroll =
- {
-   GIMPLE_PASS, /* type */
-   "cunroll", /* name */
-   OPTGROUP_LOOP, /* optinfo_flags */
-   true, /* has_gate */
-   true, /* has_execute */
-   TV_COMPLETE_UNROLL, /* tv_id */
-   ( PROP_cfg | PROP_ssa ), /* properties_required */
-   0, /* properties_provided */
-   0, /* properties_destroyed */
-   0, /* todo_flags_start */
-   0, /* todo_flags_finish */
- };
- 
- class pass_complete_unroll : public gimple_opt_pass
- {
- public:
-   pass_complete_unroll (gcc::context *ctxt)
-     : gimple_opt_pass (pass_data_complete_unroll, ctxt)
-   {}
- 
-   /* opt_pass methods: */
-   bool gate () { return gate_tree_complete_unroll (); }
-   unsigned int execute () { return tree_complete_unroll (); }
- 
- }; // class pass_complete_unroll
- 
- } // anon namespace
- 
- gimple_opt_pass *
- make_pass_complete_unroll (gcc::context *ctxt)
- {
-   return new pass_complete_unroll (ctxt);
- }
- 
- /* Complete unrolling of inner loops.  */
- 
- static unsigned int
- tree_complete_unroll_inner (void)
- {
-   unsigned ret = 0;
- 
-   loop_optimizer_init (LOOPS_NORMAL
- 		       | LOOPS_HAVE_RECORDED_EXITS);
-   if (number_of_loops (cfun) > 1)
-     {
-       scev_initialize ();
-       ret = tree_unroll_loops_completely (optimize >= 3, false);
-       free_numbers_of_iterations_estimates ();
-       scev_finalize ();
-     }
-   loop_optimizer_finalize ();
- 
-   return ret;
- }
- 
- static bool
- gate_tree_complete_unroll_inner (void)
- {
-   return optimize >= 2;
- }
- 
- namespace {
- 
- const pass_data pass_data_complete_unrolli =
- {
-   GIMPLE_PASS, /* type */
-   "cunrolli", /* name */
-   OPTGROUP_LOOP, /* optinfo_flags */
-   true, /* has_gate */
-   true, /* has_execute */
-   TV_COMPLETE_UNROLL, /* tv_id */
-   ( PROP_cfg | PROP_ssa ), /* properties_required */
-   0, /* properties_provided */
-   0, /* properties_destroyed */
-   0, /* todo_flags_start */
-   TODO_verify_flow, /* todo_flags_finish */
- };
- 
- class pass_complete_unrolli : public gimple_opt_pass
- {
- public:
-   pass_complete_unrolli (gcc::context *ctxt)
-     : gimple_opt_pass (pass_data_complete_unrolli, ctxt)
-   {}
- 
-   /* opt_pass methods: */
-   bool gate () { return gate_tree_complete_unroll_inner (); }
-   unsigned int execute () { return tree_complete_unroll_inner (); }
- 
- }; // class pass_complete_unrolli
- 
- } // anon namespace
- 
- gimple_opt_pass *
- make_pass_complete_unrolli (gcc::context *ctxt)
- {
-   return new pass_complete_unrolli (ctxt);
- }
- 
  /* Parallelization.  */
  
  static bool
--- 501,506 ----
*************** make_pass_parallelize_loops (gcc::contex
*** 846,906 ****
    return new pass_parallelize_loops (ctxt);
  }
  
- /* Prefetching.  */
- 
- static unsigned int
- tree_ssa_loop_prefetch (void)
- {
-   if (number_of_loops (cfun) <= 1)
-     return 0;
- 
-   return tree_ssa_prefetch_arrays ();
- }
- 
- static bool
- gate_tree_ssa_loop_prefetch (void)
- {
-   return flag_prefetch_loop_arrays > 0;
- }
- 
- namespace {
- 
- const pass_data pass_data_loop_prefetch =
- {
-   GIMPLE_PASS, /* type */
-   "aprefetch", /* name */
-   OPTGROUP_LOOP, /* optinfo_flags */
-   true, /* has_gate */
-   true, /* has_execute */
-   TV_TREE_PREFETCH, /* tv_id */
-   ( PROP_cfg | PROP_ssa ), /* properties_required */
-   0, /* properties_provided */
-   0, /* properties_destroyed */
-   0, /* todo_flags_start */
-   0, /* todo_flags_finish */
- };
- 
- class pass_loop_prefetch : public gimple_opt_pass
- {
- public:
-   pass_loop_prefetch (gcc::context *ctxt)
-     : gimple_opt_pass (pass_data_loop_prefetch, ctxt)
-   {}
- 
-   /* opt_pass methods: */
-   bool gate () { return gate_tree_ssa_loop_prefetch (); }
-   unsigned int execute () { return tree_ssa_loop_prefetch (); }
- 
- }; // class pass_loop_prefetch
- 
- } // anon namespace
- 
- gimple_opt_pass *
- make_pass_loop_prefetch (gcc::context *ctxt)
- {
-   return new pass_loop_prefetch (ctxt);
- }
- 
  /* Induction variable optimizations.  */
  
  static unsigned int
--- 558,563 ----
*************** make_pass_tree_loop_done (gcc::context *
*** 1004,1006 ****
--- 661,895 ----
  {
    return new pass_tree_loop_done (ctxt);
  }
+ 
+ /* Calls CBCK for each index in memory reference ADDR_P.  There are two
+    kinds situations handled; in each of these cases, the memory reference
+    and DATA are passed to the callback:
+ 
+    Access to an array: ARRAY_{RANGE_}REF (base, index).  In this case we also
+    pass the pointer to the index to the callback.
+ 
+    Pointer dereference: INDIRECT_REF (addr).  In this case we also pass the
+    pointer to addr to the callback.
+ 
+    If the callback returns false, the whole search stops and false is returned.
+    Otherwise the function returns true after traversing through the whole
+    reference *ADDR_P.  */
+ 
+ bool
+ for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
+ {
+   tree *nxt, *idx;
+ 
+   for (; ; addr_p = nxt)
+     {
+       switch (TREE_CODE (*addr_p))
+ 	{
+ 	case SSA_NAME:
+ 	  return cbck (*addr_p, addr_p, data);
+ 
+ 	case MEM_REF:
+ 	  nxt = &TREE_OPERAND (*addr_p, 0);
+ 	  return cbck (*addr_p, nxt, data);
+ 
+ 	case BIT_FIELD_REF:
+ 	case VIEW_CONVERT_EXPR:
+ 	case REALPART_EXPR:
+ 	case IMAGPART_EXPR:
+ 	  nxt = &TREE_OPERAND (*addr_p, 0);
+ 	  break;
+ 
+ 	case COMPONENT_REF:
+ 	  /* If the component has varying offset, it behaves like index
+ 	     as well.  */
+ 	  idx = &TREE_OPERAND (*addr_p, 2);
+ 	  if (*idx
+ 	      && !cbck (*addr_p, idx, data))
+ 	    return false;
+ 
+ 	  nxt = &TREE_OPERAND (*addr_p, 0);
+ 	  break;
+ 
+ 	case ARRAY_REF:
+ 	case ARRAY_RANGE_REF:
+ 	  nxt = &TREE_OPERAND (*addr_p, 0);
+ 	  if (!cbck (*addr_p, &TREE_OPERAND (*addr_p, 1), data))
+ 	    return false;
+ 	  break;
+ 
+ 	case VAR_DECL:
+ 	case PARM_DECL:
+ 	case CONST_DECL:
+ 	case STRING_CST:
+ 	case RESULT_DECL:
+ 	case VECTOR_CST:
+ 	case COMPLEX_CST:
+ 	case INTEGER_CST:
+ 	case REAL_CST:
+ 	case FIXED_CST:
+ 	case CONSTRUCTOR:
+ 	  return true;
+ 
+ 	case ADDR_EXPR:
+ 	  gcc_assert (is_gimple_min_invariant (*addr_p));
+ 	  return true;
+ 
+ 	case TARGET_MEM_REF:
+ 	  idx = &TMR_BASE (*addr_p);
+ 	  if (*idx
+ 	      && !cbck (*addr_p, idx, data))
+ 	    return false;
+ 	  idx = &TMR_INDEX (*addr_p);
+ 	  if (*idx
+ 	      && !cbck (*addr_p, idx, data))
+ 	    return false;
+ 	  idx = &TMR_INDEX2 (*addr_p);
+ 	  if (*idx
+ 	      && !cbck (*addr_p, idx, data))
+ 	    return false;
+ 	  return true;
+ 
+ 	default:
+     	  gcc_unreachable ();
+ 	}
+     }
+ }
+ 
+ 
+ /* The name and the length of the currently generated variable
+    for lsm.  */
+ #define MAX_LSM_NAME_LENGTH 40
+ static char lsm_tmp_name[MAX_LSM_NAME_LENGTH + 1];
+ static int lsm_tmp_name_length;
+ 
+ /* Adds S to lsm_tmp_name.  */
+ 
+ static void
+ lsm_tmp_name_add (const char *s)
+ {
+   int l = strlen (s) + lsm_tmp_name_length;
+   if (l > MAX_LSM_NAME_LENGTH)
+     return;
+ 
+   strcpy (lsm_tmp_name + lsm_tmp_name_length, s);
+   lsm_tmp_name_length = l;
+ }
+ 
+ /* Stores the name for temporary variable that replaces REF to
+    lsm_tmp_name.  */
+ 
+ static void
+ gen_lsm_tmp_name (tree ref)
+ {
+   const char *name;
+ 
+   switch (TREE_CODE (ref))
+     {
+     case MEM_REF:
+     case TARGET_MEM_REF:
+       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
+       lsm_tmp_name_add ("_");
+       break;
+ 
+     case ADDR_EXPR:
+       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
+       break;
+ 
+     case BIT_FIELD_REF:
+     case VIEW_CONVERT_EXPR:
+     case ARRAY_RANGE_REF:
+       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
+       break;
+ 
+     case REALPART_EXPR:
+       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
+       lsm_tmp_name_add ("_RE");
+       break;
+ 
+     case IMAGPART_EXPR:
+       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
+       lsm_tmp_name_add ("_IM");
+       break;
+ 
+     case COMPONENT_REF:
+       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
+       lsm_tmp_name_add ("_");
+       name = get_name (TREE_OPERAND (ref, 1));
+       if (!name)
+ 	name = "F";
+       lsm_tmp_name_add (name);
+       break;
+ 
+     case ARRAY_REF:
+       gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
+       lsm_tmp_name_add ("_I");
+       break;
+ 
+     case SSA_NAME:
+     case VAR_DECL:
+     case PARM_DECL:
+       name = get_name (ref);
+       if (!name)
+ 	name = "D";
+       lsm_tmp_name_add (name);
+       break;
+ 
+     case STRING_CST:
+       lsm_tmp_name_add ("S");
+       break;
+ 
+     case RESULT_DECL:
+       lsm_tmp_name_add ("R");
+       break;
+ 
+     case INTEGER_CST:
+       /* Nothing.  */
+       break;
+ 
+     default:
+       gcc_unreachable ();
+     }
+ }
+ 
+ /* Determines name for temporary variable that replaces REF.
+    The name is accumulated into the lsm_tmp_name variable.
+    N is added to the name of the temporary.  */
+ 
+ char *
+ get_lsm_tmp_name (tree ref, unsigned n, const char *suffix)
+ {
+   char ns[2];
+ 
+   lsm_tmp_name_length = 0;
+   gen_lsm_tmp_name (ref);
+   lsm_tmp_name_add ("_lsm");
+   if (n < 10)
+     {
+       ns[0] = '0' + n;
+       ns[1] = 0;
+       lsm_tmp_name_add (ns);
+     }
+   return lsm_tmp_name;
+   if (suffix != NULL)
+     lsm_tmp_name_add (suffix);
+ }
+ 
+ /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS.  */
+ 
+ unsigned
+ tree_num_loop_insns (struct loop *loop, eni_weights *weights)
+ {
+   basic_block *body = get_loop_body (loop);
+   gimple_stmt_iterator gsi;
+   unsigned size = 0, i;
+ 
+   for (i = 0; i < loop->num_nodes; i++)
+     for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
+       size += estimate_num_insns (gsi_stmt (gsi), weights);
+   free (body);
+ 
+   return size;
+ }
+ 
+ 
+ 
Index: tree-scalar-evolution.h
===================================================================
*** tree-scalar-evolution.h	(revision 203243)
--- tree-scalar-evolution.h	(working copy)
*************** extern tree resolve_mixers (struct loop 
*** 36,42 ****
  extern void gather_stats_on_scev_database (void);
  extern unsigned int scev_const_prop (void);
  extern bool expression_expensive_p (tree);
! extern bool simple_iv (struct loop *, struct loop *, tree, affine_iv *, bool);
  extern tree compute_overall_effect_of_inner_loop (struct loop *, tree);
  
  /* Returns the basic block preceding LOOP or ENTRY_BLOCK_PTR when the
--- 36,43 ----
  extern void gather_stats_on_scev_database (void);
  extern unsigned int scev_const_prop (void);
  extern bool expression_expensive_p (tree);
! extern bool simple_iv (struct loop *, struct loop *, tree, struct affine_iv_d *,
! 		       bool);
  extern tree compute_overall_effect_of_inner_loop (struct loop *, tree);
  
  /* Returns the basic block preceding LOOP or ENTRY_BLOCK_PTR when the
Index: loop-iv.c
===================================================================
*** loop-iv.c	(revision 203243)
--- loop-iv.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 62,67 ****
--- 62,68 ----
  #include "df.h"
  #include "hash-table.h"
  #include "dumpfile.h"
+ #include "tree-ssa-loop-niter.h"
  
  /* Possible return values of iv_get_reaching_def.  */
  
Index: loop-unroll.c
===================================================================
*** loop-unroll.c	(revision 203243)
--- loop-unroll.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 32,37 ****
--- 32,38 ----
  #include "recog.h"
  #include "target.h"
  #include "dumpfile.h"
+ #include "tree-ssa-loop-niter.h"
  
  /* This pass performs loop unrolling and peeling.  We only perform these
     optimizations on innermost loops (with single exception) because
Index: loop-unswitch.c
===================================================================
*** loop-unswitch.c	(revision 203243)
--- loop-unswitch.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 29,34 ****
--- 29,35 ----
  #include "params.h"
  #include "expr.h"
  #include "dumpfile.h"
+ #include "tree-ssa-loop-niter.h"
  
  /* This pass moves constant conditions out of loops, duplicating the loop
     in progress, i.e. this code:
