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


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

Re: [patch] Add tree-ssa-loop.h and friends.


On 10/07/2013 04:44 AM, Richard Biener wrote:
On Thu, Oct 3, 2013 at 4:11 AM, Andrew MacLeod <amacleod@redhat.com> wrote:
this patch consolidates tree-ssa-loop*.c files with new .h files as required
(8 in total)

A number of the prototypes were in tree-flow.h, but there were also a few in
cfgloop.h.  tree-ssa-loop.h was created to contain a couple of common
structs and act as the gathering file for any generally applicable
tree-ssa-loop includes. tree-flow.h includes this file for now.

There is a bit of a criss-cross mess between the cfg-* and tree-ssa-loop*
routines, but I'm not touching that for now.  Some of that might have to get
resolved when I try to remove tree-flow.h as a standard include file from
the .c files.. we'll see.

In particular, tree-ssa-loop-niter.h exports a lot of more generally used
routines. loop-iv.c, loop-unroll.c and loop-unswitch.c needed to include it.

A few routines werent referenced outside their file so I made those static,
and there was one routine stmt_invariant_in_loop_p wich was actually unused.

bootstraps on x86_64-unknown-linux-gnu and passes with no new regressions.
OK?
+   enum tree_code cmp;
+ };
+
+ #include "tree-ssa-loop-im.h"
+ #include "tree-ssa-loop-ivcanon.h"

what's the particular reason to not do includes first?  That looks really
odd (and maybe rather than doing that these includes should be done
elsewhere, like in .c files or in a header that includes tree-ssa-loop.h).

I had sent a followup patch because I didn't like it either :-). required just a little shuffling since a couple of them used the typedefs declared before them.

You seem to export things like movement_possibility that are not
used outside of tree-ssa-loop-im.c (in my tree at least).

Hmm, seems I missed that one somehow... I've been checking every function and enum, but seemed to have managed to miss that one somehow. easy to fix.

Yes, both those should go into the tree-ssa-loop-im.c


Other than that the single reason we have to have all these exports
is that loop passes have their pass structures and gate / entries
defined in tree-ssa-loop.c instead of in the files the passes reside.
Consider changing that as a preparatory patch - it should cut down
the number of needed new .h files.

Yeah, good observation. And by shuffling a few other exported routines which are more generally used into tree-ssa-loop.c: for_each_index, lsm_tmp_name_add, gen_lsm_tmp_name, get_lsm_tmp_name, tree_num_loop_insns and enhancing get_lsm_tmp_name() to accept a suffix parameter, those loop-im and loop-ivcanon no longer need a .h file either.

I moved the passes out of tree-ssa-loop.c that would cause new .h files unnecessarily, but left the others since that is orthogonal and could be followed up later.

I just bundled it all together since it changes the original 2 patches a bit.

Bootstraps on x86_64-unknown-linux-gnu, testsuite regressions running. Assuming they pass fine, OK?

Andrew
	* 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:

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