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]

[tuples, commited] Scalar evolution analysis


Hello,

this patch tuplifies scalar evolution analysis and # of iterations
analysis.  It also fixes problems with pass_ch (gimple_copy used to
share bitmaps between the original and copied statement, which caused
the bitmaps to be freed twice, which leads to quite cryptic ICEs)
and enables it, and tuplifies and enables pass_scev_cprop.

Zdenek

Index: ChangeLog.tuples
===================================================================
*** ChangeLog.tuples	(revision 132890)
--- ChangeLog.tuples	(working copy)
***************
*** 1,3 ****
--- 1,43 ----
+ 2008-03-04  Zdenek Dvorak  <ook@ucw.cz>
+ 
+ 	* tree-ssa-loop-niter.c, tree-scalar-evolution.c: Tuplified.
+ 	* tree-ssa-loop-manip.c (split_loop_exit_edge): Ditto.
+ 	* tree-chrec.c (chrec_fold_plus, chrec_apply, chrec_convert_1,
+ 	convert_affine_scev, chrec_convert_rhs, chrec_convert,
+ 	chrec_convert_aggressive): Pass statements as gimple.
+ 	* tree-scalar-evolution.h (get_loop_exit_condition, simple_iv):
+ 	Type changed.
+ 	* tree-chrec.h (chrec_convert, chrec_convert_rhs): Ditto.
+ 	* tree-ssa-loop-ivopts.c (abnormal_ssa_name_p,
+ 	idx_contains_abnormal_ssa_name_p, contains_abnormal_ssa_name_p,
+ 	expr_invariant_in_loop_p, tree_int_cst_sign_bit): Enabled.
+ 	* gimple-dummy.c (chrec_dont_know, chrec_known, chrec_not_analyzed_yet,
+ 	analyze_scalar_evolution, chrec_contains_symbols_defined_in_loop,
+ 	estimate_numbers_of_iterations, expr_invariant_in_loop_p,
+ 	free_numbers_of_iterations_estimates,
+ 	free_numbers_of_iterations_estimates_loop, get_loop_exit_condition,
+ 	instantiate_parameters, nowrap_type_p. scev_const_prop. scev_finalize,
+ 	scev_initialize, scev_probably_wraps_p, scev_reset,
+ 	tree_int_cst_sign_bit, number_of_iterations_exit, loop_niter_by_eval,
+ 	substitute_in_loop_info): Removed.
+ 	* tree-ssa-loop.c (tree_loop_optimizer_init): Merged into...
+ 	(tree_ssa_loop_init): ... here.  Enable scev_initialize call.
+ 	(tree_ssa_loop_done): Enable scev finalization.
+ 	* gimple-iterator.c (gsi_insert_seq_nodes_before): Allow inserting
+ 	at the end of basic block.
+ 	(gsi_for_stmt): Handle phi nodes.
+ 	* cfgloop.h (struct nb_iter_bound): Change type of stmt field to gimple.
+ 	* tree-flow.h (scev_probably_wraps_p, convert_affine_scev,
+ 	stmt_dominates_stmt_p): Types changed.
+ 	* Makefile.in (gt-tree-scalar-evolution.h): Enable.
+ 	* gimple.c (extract_ops_from_tree): Export.
+ 	(gimple_copy): Do not share bitmaps.
+ 	* gimple.h (extract_ops_from_tree): Declare.
+ 	(gimple_call_set_lhs): Allow lhs to be NULL.
+ 	* tree-cfg.c (add_phi_args_after_copy_edge,
+ 	add_phi_args_after_copy_bb): Tuplify.
+ 	* passes.c (init_optimization_passes): Enable pass_ch, pass_scev_cprop.
+ 
  2008-03-04  Oleg Ryjkov  <olegr@google.com>
  
  	* tree-ssa-dse.c (execute_simple_dse): Commented out.
Index: tree-ssa-loop-niter.c
===================================================================
*** tree-ssa-loop-niter.c	(revision 132890)
--- tree-ssa-loop-niter.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 43,50 ****
  #include "tree-inline.h"
  #include "gmp.h"
  
- /* FIXME tuples.  */
- #if 0
  #define SWAP(X, Y) do { affine_iv *tmp = (X); (X) = (Y); (Y) = tmp; } while (0)
  
  /* The maximum number of dominator BBs we search for conditions
--- 43,48 ----
*************** bound_difference (struct loop *loop, tre
*** 369,375 ****
    int cnt = 0;
    edge e;
    basic_block bb;
!   tree cond, c0, c1;
    enum tree_code cmp;
  
    /* Get rid of unnecessary casts, but preserve the value of
--- 367,374 ----
    int cnt = 0;
    edge e;
    basic_block bb;
!   tree c0, c1;
!   gimple cond;
    enum tree_code cmp;
  
    /* Get rid of unnecessary casts, but preserve the value of
*************** bound_difference (struct loop *loop, tre
*** 428,442 ****
        if (!(e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
  	continue;
  
!       /* FIXME tuples
!       cond = COND_EXPR_COND (last_stmt (e->src));
!       */
!       cond = NULL; /* FIXME tuples */
!       if (!COMPARISON_CLASS_P (cond))
! 	continue;
!       c0 = TREE_OPERAND (cond, 0);
!       cmp = TREE_CODE (cond);
!       c1 = TREE_OPERAND (cond, 1);
  
        if (e->flags & EDGE_FALSE_VALUE)
  	cmp = invert_tree_comparison (cmp, false);
--- 427,436 ----
        if (!(e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
  	continue;
  
!       cond = last_stmt (e->src);
!       c0 = gimple_cond_lhs (cond);
!       cmp = gimple_cond_code (cond);
!       c1 = gimple_cond_rhs (cond);
  
        if (e->flags & EDGE_FALSE_VALUE)
  	cmp = invert_tree_comparison (cmp, false);
*************** tree
*** 1380,1387 ****
  expand_simple_operations (tree expr)
  {
    unsigned i, n;
!   tree ret = NULL_TREE, e, ee, stmt;
    enum tree_code code;
  
    if (expr == NULL_TREE)
      return expr;
--- 1374,1382 ----
  expand_simple_operations (tree expr)
  {
    unsigned i, n;
!   tree ret = NULL_TREE, e, ee, e1;
    enum tree_code code;
+   gimple stmt;
  
    if (expr == NULL_TREE)
      return expr;
*************** expand_simple_operations (tree expr)
*** 1419,1429 ****
      return expr;
  
    stmt = SSA_NAME_DEF_STMT (expr);
!   if (TREE_CODE (stmt) == PHI_NODE)
      {
        basic_block src, dest;
  
!       if (PHI_NUM_ARGS (stmt) != 1)
  	return expr;
        e = PHI_ARG_DEF (stmt, 0);
  
--- 1414,1424 ----
      return expr;
  
    stmt = SSA_NAME_DEF_STMT (expr);
!   if (gimple_code (stmt) == GIMPLE_PHI)
      {
        basic_block src, dest;
  
!       if (gimple_phi_num_args (stmt) != 1)
  	return expr;
        e = PHI_ARG_DEF (stmt, 0);
  
*************** expand_simple_operations (tree expr)
*** 1437,1461 ****
  
        return expand_simple_operations (e);
      }
!   if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
      return expr;
  
!   e = GIMPLE_STMT_OPERAND (stmt, 1);
!   if (/* Casts are simple.  */
!       TREE_CODE (e) != NOP_EXPR
!       && TREE_CODE (e) != CONVERT_EXPR
!       /* Copies are simple.  */
!       && TREE_CODE (e) != SSA_NAME
!       /* Assignments of invariants are simple.  */
!       && !is_gimple_min_invariant (e)
!       /* And increments and decrements by a constant are simple.  */
!       && !((TREE_CODE (e) == PLUS_EXPR
! 	    || TREE_CODE (e) == MINUS_EXPR
! 	    || TREE_CODE (e) == POINTER_PLUS_EXPR)
! 	   && is_gimple_min_invariant (TREE_OPERAND (e, 1))))
!     return expr;
  
!   return expand_simple_operations (e);
  }
  
  /* Tries to simplify EXPR using the condition COND.  Returns the simplified
--- 1432,1480 ----
  
        return expand_simple_operations (e);
      }
!   if (gimple_code (stmt) != GIMPLE_ASSIGN)
      return expr;
  
!   e = gimple_assign_rhs1 (stmt);
!   code = gimple_assign_subcode (stmt);
!   if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
!     {
!       if (is_gimple_min_invariant (e))
! 	return e;
! 
!       if (code == SSA_NAME)
! 	return expand_simple_operations (e);
! 
!       return expr;
!     }
! 
!   switch (code)
!     {
!     case NOP_EXPR:
!     case CONVERT_EXPR:
!       /* Casts are simple.  */
!       ee = expand_simple_operations (e);
!       if (e == ee)
! 	return expr;
!       return fold_build1 (code, TREE_TYPE (expr), ee);
! 
!     case PLUS_EXPR:
!     case MINUS_EXPR:
!     case POINTER_PLUS_EXPR:
!       /* And increments and decrements of a constant are simple.  */
  
!       e1 = gimple_assign_rhs2 (stmt);
!       if (!is_gimple_min_invariant (e1))
! 	return expr;
! 
!       ee = expand_simple_operations (e);
!       if (e == ee)
! 	return expr;
!       return fold_build2 (code, TREE_TYPE (expr), ee, e1);
! 
!     default:
!       return expr;
!     }
  }
  
  /* Tries to simplify EXPR using the condition COND.  Returns the simplified
*************** simplify_using_initial_conditions (struc
*** 1590,1595 ****
--- 1609,1615 ----
  {
    edge e;
    basic_block bb;
+   gimple stmt;
    tree cond;
    int cnt = 0;
  
*************** simplify_using_initial_conditions (struc
*** 1610,1619 ****
        if (!(e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
  	continue;
  
!       /* FIXME tuples
!       cond = COND_EXPR_COND (last_stmt (e->src));
!       */
!       cond = NULL; /* FIXME tuples */
        if (e->flags & EDGE_FALSE_VALUE)
  	cond = invert_truthvalue (cond);
        expr = tree_simplify_using_condition (cond, expr);
--- 1630,1640 ----
        if (!(e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
  	continue;
  
!       stmt = last_stmt (e->src);
!       cond = fold_build2 (gimple_cond_code (stmt),
! 			  boolean_type_node,
! 			  gimple_cond_lhs (stmt),
! 			  gimple_cond_rhs (stmt));
        if (e->flags & EDGE_FALSE_VALUE)
  	cond = invert_truthvalue (cond);
        expr = tree_simplify_using_condition (cond, expr);
*************** static bool
*** 1684,1692 ****
  loop_only_exit_p (const struct loop *loop, const_edge exit)
  {
    basic_block *body;
!   block_stmt_iterator bsi;
    unsigned i;
!   tree call;
  
    if (exit != single_exit (loop))
      return false;
--- 1705,1713 ----
  loop_only_exit_p (const struct loop *loop, const_edge exit)
  {
    basic_block *body;
!   gimple_stmt_iterator bsi;
    unsigned i;
!   gimple call;
  
    if (exit != single_exit (loop))
      return false;
*************** loop_only_exit_p (const struct loop *loo
*** 1694,1703 ****
    body = get_loop_body (loop);
    for (i = 0; i < loop->num_nodes; i++)
      {
!       for (bsi = bsi_start (body[0]); !bsi_end_p (bsi); bsi_next (&bsi))
  	{
! 	  call = get_call_expr_in (bsi_stmt (bsi));
! 	  if (call && TREE_SIDE_EFFECTS (call))
  	    {
  	      free (body);
  	      return false;
--- 1715,1727 ----
    body = get_loop_body (loop);
    for (i = 0; i < loop->num_nodes; i++)
      {
!       for (bsi = gsi_start_bb (body[i]); !gsi_end_p (bsi); gsi_next (&bsi))
  	{
! 	  call = gsi_stmt (bsi);
! 	  if (gimple_code (call) != GIMPLE_CALL)
! 	    continue;
! 
! 	  if (gimple_has_side_effects (call))
  	    {
  	      free (body);
  	      return false;
*************** number_of_iterations_exit (struct loop *
*** 1722,1728 ****
  			   struct tree_niter_desc *niter,
  			   bool warn)
  {
!   tree stmt, cond, type;
    tree op0, op1;
    enum tree_code code;
    affine_iv iv0, iv1;
--- 1746,1753 ----
  			   struct tree_niter_desc *niter,
  			   bool warn)
  {
!   gimple stmt;
!   tree type;
    tree op0, op1;
    enum tree_code code;
    affine_iv iv0, iv1;
*************** number_of_iterations_exit (struct loop *
*** 1732,1746 ****
  
    niter->assumptions = boolean_false_node;
    stmt = last_stmt (exit->src);
!   if (!stmt || TREE_CODE (stmt) != COND_EXPR)
      return false;
  
    /* We want the condition for staying inside loop.  */
!   cond = COND_EXPR_COND (stmt);
    if (exit->flags & EDGE_TRUE_VALUE)
!     cond = invert_truthvalue (cond);
  
-   code = TREE_CODE (cond);
    switch (code)
      {
      case GT_EXPR:
--- 1757,1770 ----
  
    niter->assumptions = boolean_false_node;
    stmt = last_stmt (exit->src);
!   if (!stmt || gimple_code (stmt) != GIMPLE_COND)
      return false;
  
    /* We want the condition for staying inside loop.  */
!   code = gimple_cond_code (stmt);
    if (exit->flags & EDGE_TRUE_VALUE)
!     code = invert_tree_comparison (code, false);
  
    switch (code)
      {
      case GT_EXPR:
*************** number_of_iterations_exit (struct loop *
*** 1754,1761 ****
        return false;
      }
    
!   op0 = TREE_OPERAND (cond, 0);
!   op1 = TREE_OPERAND (cond, 1);
    type = TREE_TYPE (op0);
  
    if (TREE_CODE (type) != INTEGER_TYPE
--- 1778,1785 ----
        return false;
      }
    
!   op0 = gimple_cond_lhs (stmt);
!   op1 = gimple_cond_rhs (stmt);
    type = TREE_TYPE (op0);
  
    if (TREE_CODE (type) != INTEGER_TYPE
*************** number_of_iterations_exit (struct loop *
*** 1813,1819 ****
    if (warn)
      {
        const char *wording;
!       location_t loc = EXPR_LOCATION (stmt);
    
        /* We can provide a more specific warning if one of the operator is
  	 constant and the other advances by +1 or -1.  */
--- 1837,1843 ----
    if (warn)
      {
        const char *wording;
!       location_t loc = gimple_locus (stmt);
    
        /* We can provide a more specific warning if one of the operator is
  	 constant and the other advances by +1 or -1.  */
*************** find_loop_niter (struct loop *loop, edge
*** 1923,1958 ****
     result by a chain of operations such that all but exactly one of their
     operands are constants.  */
  
! static tree
  chain_of_csts_start (struct loop *loop, tree x)
  {
!   tree stmt = SSA_NAME_DEF_STMT (x);
    tree use;
    basic_block bb = gimple_bb (stmt);
  
    if (!bb
        || !flow_bb_inside_loop_p (loop, bb))
!     return NULL_TREE;
    
!   if (TREE_CODE (stmt) == PHI_NODE)
      {
        if (bb == loop->header)
  	return stmt;
  
!       return NULL_TREE;
      }
  
!   if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
!     return NULL_TREE;
  
    if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
!     return NULL_TREE;
    if (SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF) == NULL_DEF_OPERAND_P)
!     return NULL_TREE;
  
    use = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_USE);
    if (use == NULL_USE_OPERAND_P)
!     return NULL_TREE;
  
    return chain_of_csts_start (loop, use);
  }
--- 1947,1982 ----
     result by a chain of operations such that all but exactly one of their
     operands are constants.  */
  
! static gimple
  chain_of_csts_start (struct loop *loop, tree x)
  {
!   gimple stmt = SSA_NAME_DEF_STMT (x);
    tree use;
    basic_block bb = gimple_bb (stmt);
  
    if (!bb
        || !flow_bb_inside_loop_p (loop, bb))
!     return NULL;
    
!   if (gimple_code (stmt) == GIMPLE_PHI)
      {
        if (bb == loop->header)
  	return stmt;
  
!       return NULL;
      }
  
!   if (gimple_code (stmt) != GIMPLE_ASSIGN)
!     return NULL;
  
    if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
!     return NULL;
    if (SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF) == NULL_DEF_OPERAND_P)
!     return NULL;
  
    use = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_USE);
    if (use == NULL_USE_OPERAND_P)
!     return NULL;
  
    return chain_of_csts_start (loop, use);
  }
*************** chain_of_csts_start (struct loop *loop, 
*** 1965,1996 ****
     * the value of the phi node in the next iteration can be derived from the
       value in the current iteration by a chain of operations with constants.
     
!    If such phi node exists, it is returned.  If X is a constant, X is returned
!    unchanged.  Otherwise NULL_TREE is returned.  */
  
! static tree
  get_base_for (struct loop *loop, tree x)
  {
!   tree phi, init, next;
  
    if (is_gimple_min_invariant (x))
!     return x;
  
    phi = chain_of_csts_start (loop, x);
    if (!phi)
!     return NULL_TREE;
  
    init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
    next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
  
    if (TREE_CODE (next) != SSA_NAME)
!     return NULL_TREE;
  
    if (!is_gimple_min_invariant (init))
!     return NULL_TREE;
  
    if (chain_of_csts_start (loop, next) != phi)
!     return NULL_TREE;
  
    return phi;
  }
--- 1989,2020 ----
     * the value of the phi node in the next iteration can be derived from the
       value in the current iteration by a chain of operations with constants.
     
!    If such phi node exists, it is returned, otherwise NULL is returned.  */
  
! static gimple
  get_base_for (struct loop *loop, tree x)
  {
!   gimple phi;
!   tree init, next;
  
    if (is_gimple_min_invariant (x))
!     return NULL;
  
    phi = chain_of_csts_start (loop, x);
    if (!phi)
!     return NULL;
  
    init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
    next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
  
    if (TREE_CODE (next) != SSA_NAME)
!     return NULL;
  
    if (!is_gimple_min_invariant (init))
!     return NULL;
  
    if (chain_of_csts_start (loop, next) != phi)
!     return NULL;
  
    return phi;
  }
*************** get_base_for (struct loop *loop, tree x)
*** 2006,2012 ****
  static tree
  get_val_for (tree x, tree base)
  {
!   tree stmt, nx, val;
    use_operand_p op;
    ssa_op_iter iter;
  
--- 2030,2037 ----
  static tree
  get_val_for (tree x, tree base)
  {
!   gimple stmt;
!   tree nx, val;
    use_operand_p op;
    ssa_op_iter iter;
  
*************** get_val_for (tree x, tree base)
*** 2016,2030 ****
      return base;
  
    stmt = SSA_NAME_DEF_STMT (x);
!   if (TREE_CODE (stmt) == PHI_NODE)
      return base;
  
    FOR_EACH_SSA_USE_OPERAND (op, stmt, iter, SSA_OP_USE)
      {
        nx = USE_FROM_PTR (op);
        val = get_val_for (nx, base);
        SET_USE (op, val);
!       val = fold (GIMPLE_STMT_OPERAND (stmt, 1));
        SET_USE (op, nx);
        /* only iterate loop once.  */
        return val;
--- 2041,2057 ----
      return base;
  
    stmt = SSA_NAME_DEF_STMT (x);
!   if (gimple_code (stmt) == GIMPLE_PHI)
      return base;
  
    FOR_EACH_SSA_USE_OPERAND (op, stmt, iter, SSA_OP_USE)
      {
+       /* FIXME -- rewriting the statement this way in order to fold its rhs
+ 	 is an ugly hack.  */
        nx = USE_FROM_PTR (op);
        val = get_val_for (nx, base);
        SET_USE (op, val);
!       val = gimple_fold (stmt);
        SET_USE (op, nx);
        /* only iterate loop once.  */
        return val;
*************** get_val_for (tree x, tree base)
*** 2044,2063 ****
  tree
  loop_niter_by_eval (struct loop *loop, edge exit)
  {
!   tree cond, cnd, acnd;
!   tree op[2], val[2], next[2], aval[2], phi[2];
    unsigned i, j;
    enum tree_code cmp;
  
    cond = last_stmt (exit->src);
!   if (!cond || TREE_CODE (cond) != COND_EXPR)
      return chrec_dont_know;
  
!   cnd = COND_EXPR_COND (cond);
    if (exit->flags & EDGE_TRUE_VALUE)
!     cnd = invert_truthvalue (cnd);
  
-   cmp = TREE_CODE (cnd);
    switch (cmp)
      {
      case EQ_EXPR:
--- 2071,2090 ----
  tree
  loop_niter_by_eval (struct loop *loop, edge exit)
  {
!   tree acnd;
!   tree op[2], val[2], next[2], aval[2];
!   gimple phi, cond;
    unsigned i, j;
    enum tree_code cmp;
  
    cond = last_stmt (exit->src);
!   if (!cond || gimple_code (cond) != GIMPLE_COND)
      return chrec_dont_know;
  
!   cmp = gimple_cond_code (cond);
    if (exit->flags & EDGE_TRUE_VALUE)
!     cmp = invert_tree_comparison (cmp, false);
  
    switch (cmp)
      {
      case EQ_EXPR:
*************** loop_niter_by_eval (struct loop *loop, e
*** 2066,2073 ****
      case GE_EXPR:
      case LT_EXPR:
      case LE_EXPR:
!       for (j = 0; j < 2; j++)
! 	op[j] = TREE_OPERAND (cnd, j);
        break;
  
      default:
--- 2093,2100 ----
      case GE_EXPR:
      case LT_EXPR:
      case LE_EXPR:
!       op[0] = gimple_cond_lhs (cond);
!       op[1] = gimple_cond_rhs (cond);
        break;
  
      default:
*************** loop_niter_by_eval (struct loop *loop, e
*** 2076,2098 ****
  
    for (j = 0; j < 2; j++)
      {
!       phi[j] = get_base_for (loop, op[j]);
!       if (!phi[j])
! 	return chrec_dont_know;
!     }
! 
!   for (j = 0; j < 2; j++)
!     {
!       if (TREE_CODE (phi[j]) == PHI_NODE)
  	{
! 	  val[j] = PHI_ARG_DEF_FROM_EDGE (phi[j], loop_preheader_edge (loop));
! 	  next[j] = PHI_ARG_DEF_FROM_EDGE (phi[j], loop_latch_edge (loop));
  	}
        else
  	{
! 	  val[j] = phi[j];
! 	  next[j] = NULL_TREE;
! 	  op[j] = NULL_TREE;
  	}
      }
  
--- 2103,2121 ----
  
    for (j = 0; j < 2; j++)
      {
!       if (is_gimple_min_invariant (op[j]))
  	{
! 	  val[j] = op[j];
! 	  next[j] = NULL_TREE;
! 	  op[j] = NULL_TREE;
  	}
        else
  	{
! 	  phi = get_base_for (loop, op[j]);
! 	  if (!phi)
! 	    return chrec_dont_know;
! 	  val[j] = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
! 	  next[j] = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
  	}
      }
  
*************** find_loop_niter_by_eval (struct loop *lo
*** 2174,2190 ****
  
  */
  
  /* Returns a constant upper bound on the value of expression VAL.  VAL
     is considered to be unsigned.  If its type is signed, its value must
     be nonnegative.  */
   
  static double_int
! derive_constant_upper_bound (const_tree val)
  {
!   tree type = TREE_TYPE (val);
!   tree op0, op1, subtype, maxt;
    double_int bnd, max, mmax, cst;
!   tree stmt;
  
    if (INTEGRAL_TYPE_P (type))
      maxt = TYPE_MAX_VALUE (type);
--- 2197,2245 ----
  
  */
  
+ static double_int derive_constant_upper_bound_ops (tree, tree,
+ 						   enum tree_code, tree);
+ 
+ /* Returns a constant upper bound on the value of the right-hand side of
+    an assignment statement STMT.  */
+ 
+ static double_int
+ derive_constant_upper_bound_assign (gimple stmt)
+ {
+   enum tree_code code = gimple_assign_subcode (stmt);
+   tree op0 = gimple_assign_rhs1 (stmt);
+   tree op1 = (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS
+ 	      ? gimple_assign_rhs2 (stmt) : NULL_TREE);
+ 
+   return derive_constant_upper_bound_ops (TREE_TYPE (gimple_assign_lhs (stmt)),
+ 					  op0, code, op1);
+ }
+ 
  /* Returns a constant upper bound on the value of expression VAL.  VAL
     is considered to be unsigned.  If its type is signed, its value must
     be nonnegative.  */
   
  static double_int
! derive_constant_upper_bound (tree val)
  {
!   enum tree_code code;
!   tree op0, op1;
! 
!   extract_ops_from_tree (val, &code, &op0, &op1);
!   return derive_constant_upper_bound_ops (TREE_TYPE (val), op0, code, op1);
! }
! 
! /* Returns a constant upper bound on the value of expression OP0 CODE OP1,
!    whose type is TYPE.  The expression is considered to be unsigned.  If
!    its type is signed, its value must be nonnegative.  */
!  
! static double_int
! derive_constant_upper_bound_ops (tree type, tree op0,
! 				 enum tree_code code, tree op1)
! {
!   tree subtype, maxt;
    double_int bnd, max, mmax, cst;
!   gimple stmt;
  
    if (INTEGRAL_TYPE_P (type))
      maxt = TYPE_MAX_VALUE (type);
*************** derive_constant_upper_bound (const_tree 
*** 2193,2206 ****
  
    max = tree_to_double_int (maxt);
  
!   switch (TREE_CODE (val))
      {
      case INTEGER_CST:
!       return tree_to_double_int (val);
  
      case NOP_EXPR:
      case CONVERT_EXPR:
-       op0 = TREE_OPERAND (val, 0);
        subtype = TREE_TYPE (op0);
        if (!TYPE_UNSIGNED (subtype)
  	  /* If TYPE is also signed, the fact that VAL is nonnegative implies
--- 2248,2260 ----
  
    max = tree_to_double_int (maxt);
  
!   switch (code)
      {
      case INTEGER_CST:
!       return tree_to_double_int (op0);
  
      case NOP_EXPR:
      case CONVERT_EXPR:
        subtype = TREE_TYPE (op0);
        if (!TYPE_UNSIGNED (subtype)
  	  /* If TYPE is also signed, the fact that VAL is nonnegative implies
*************** derive_constant_upper_bound (const_tree 
*** 2228,2236 ****
      case PLUS_EXPR:
      case POINTER_PLUS_EXPR:
      case MINUS_EXPR:
-       op0 = TREE_OPERAND (val, 0);
-       op1 = TREE_OPERAND (val, 1);
- 
        if (TREE_CODE (op1) != INTEGER_CST
  	  || !tree_expr_nonnegative_p (op0))
  	return max;
--- 2282,2287 ----
*************** derive_constant_upper_bound (const_tree 
*** 2240,2246 ****
  	 of the signedness of the type.  */
        cst = tree_to_double_int (op1);
        cst = double_int_sext (cst, TYPE_PRECISION (type));
!       if (TREE_CODE (val) == PLUS_EXPR)
  	cst = double_int_neg (cst);
  
        bnd = derive_constant_upper_bound (op0);
--- 2291,2297 ----
  	 of the signedness of the type.  */
        cst = tree_to_double_int (op1);
        cst = double_int_sext (cst, TYPE_PRECISION (type));
!       if (code != MINUS_EXPR)
  	cst = double_int_neg (cst);
  
        bnd = derive_constant_upper_bound (op0);
*************** derive_constant_upper_bound (const_tree 
*** 2294,2301 ****
  
      case FLOOR_DIV_EXPR:
      case EXACT_DIV_EXPR:
-       op0 = TREE_OPERAND (val, 0);
-       op1 = TREE_OPERAND (val, 1);
        if (TREE_CODE (op1) != INTEGER_CST
  	  || tree_int_cst_sign_bit (op1))
  	return max;
--- 2345,2350 ----
*************** derive_constant_upper_bound (const_tree 
*** 2304,2321 ****
        return double_int_udiv (bnd, tree_to_double_int (op1), FLOOR_DIV_EXPR);
  
      case BIT_AND_EXPR:
-       op1 = TREE_OPERAND (val, 1);
        if (TREE_CODE (op1) != INTEGER_CST
  	  || tree_int_cst_sign_bit (op1))
  	return max;
        return tree_to_double_int (op1);
  
      case SSA_NAME:
!       stmt = SSA_NAME_DEF_STMT (val);
!       if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
! 	  || GIMPLE_STMT_OPERAND (stmt, 0) != val)
  	return max;
!       return derive_constant_upper_bound (GIMPLE_STMT_OPERAND (stmt, 1));
  
      default: 
        return max;
--- 2353,2369 ----
        return double_int_udiv (bnd, tree_to_double_int (op1), FLOOR_DIV_EXPR);
  
      case BIT_AND_EXPR:
        if (TREE_CODE (op1) != INTEGER_CST
  	  || tree_int_cst_sign_bit (op1))
  	return max;
        return tree_to_double_int (op1);
  
      case SSA_NAME:
!       stmt = SSA_NAME_DEF_STMT (op0);
!       if (gimple_code (stmt) != GIMPLE_ASSIGN
! 	  || gimple_assign_lhs (stmt) != op0)
  	return max;
!       return derive_constant_upper_bound_assign (stmt);
  
      default: 
        return max;
*************** record_niter_bound (struct loop *loop, d
*** 2358,2364 ****
  
  static void
  record_estimate (struct loop *loop, tree bound, double_int i_bound,
! 		 tree at_stmt, bool is_exit, bool realistic, bool upper)
  {
    double_int delta;
    edge exit;
--- 2406,2412 ----
  
  static void
  record_estimate (struct loop *loop, tree bound, double_int i_bound,
! 		 gimple at_stmt, bool is_exit, bool realistic, bool upper)
  {
    double_int delta;
    edge exit;
*************** record_estimate (struct loop *loop, tree
*** 2366,2372 ****
    if (dump_file && (dump_flags & TDF_DETAILS))
      {
        fprintf (dump_file, "Statement %s", is_exit ? "(exit)" : "");
!       print_generic_expr (dump_file, at_stmt, TDF_SLIM);
        fprintf (dump_file, " is %sexecuted at most ",
  	       upper ? "" : "probably ");
        print_generic_expr (dump_file, bound, TDF_SLIM);
--- 2414,2420 ----
    if (dump_file && (dump_flags & TDF_DETAILS))
      {
        fprintf (dump_file, "Statement %s", is_exit ? "(exit)" : "");
!       print_gimple_stmt (dump_file, at_stmt, 0, TDF_SLIM);
        fprintf (dump_file, " is %sexecuted at most ",
  	       upper ? "" : "probably ");
        print_generic_expr (dump_file, bound, TDF_SLIM);
*************** record_estimate (struct loop *loop, tree
*** 2424,2430 ****
     UPPER is true if we are sure the induction variable does not wrap.  */
  
  static void
! record_nonwrapping_iv (struct loop *loop, tree base, tree step, tree stmt,
  		       tree low, tree high, bool realistic, bool upper)
  {
    tree niter_bound, extreme, delta;
--- 2472,2478 ----
     UPPER is true if we are sure the induction variable does not wrap.  */
  
  static void
! record_nonwrapping_iv (struct loop *loop, tree base, tree step, gimple stmt,
  		       tree low, tree high, bool realistic, bool upper)
  {
    tree niter_bound, extreme, delta;
*************** record_nonwrapping_iv (struct loop *loop
*** 2443,2449 ****
        fprintf (dump_file, " + ");
        print_generic_expr (dump_file, step, TDF_SLIM);
        fprintf (dump_file, " * iteration does not wrap in statement ");
!       print_generic_expr (dump_file, stmt, TDF_SLIM);
        fprintf (dump_file, " in loop %d.\n", loop->num);
      }
  
--- 2491,2497 ----
        fprintf (dump_file, " + ");
        print_generic_expr (dump_file, step, TDF_SLIM);
        fprintf (dump_file, " * iteration does not wrap in statement ");
!       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
        fprintf (dump_file, " in loop %d.\n", loop->num);
      }
  
*************** array_at_struct_end_p (tree ref)
*** 2524,2530 ****
  struct ilb_data
  {
    struct loop *loop;
!   tree stmt;
    bool reliable;
  };
  
--- 2572,2578 ----
  struct ilb_data
  {
    struct loop *loop;
!   gimple stmt;
    bool reliable;
  };
  
*************** idx_infer_loop_bounds (tree base, tree *
*** 2611,2617 ****
     STMT is guaranteed to be executed in every iteration of LOOP.*/
  
  static void
! infer_loop_bounds_from_ref (struct loop *loop, tree stmt, tree ref,
  			    bool reliable)
  {
    struct ilb_data data;
--- 2659,2665 ----
     STMT is guaranteed to be executed in every iteration of LOOP.*/
  
  static void
! infer_loop_bounds_from_ref (struct loop *loop, gimple stmt, tree ref,
  			    bool reliable)
  {
    struct ilb_data data;
*************** infer_loop_bounds_from_ref (struct loop 
*** 2627,2640 ****
     executed in every iteration of LOOP.  */
  
  static void
! infer_loop_bounds_from_array (struct loop *loop, tree stmt, bool reliable)
  {
!   tree call;
! 
!   if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
      {
!       tree op0 = GIMPLE_STMT_OPERAND (stmt, 0);
!       tree op1 = GIMPLE_STMT_OPERAND (stmt, 1);
  
        /* For each memory access, analyze its access function
  	 and record a bound on the loop iteration domain.  */
--- 2675,2686 ----
     executed in every iteration of LOOP.  */
  
  static void
! infer_loop_bounds_from_array (struct loop *loop, gimple stmt, bool reliable)
  {
!   if (gimple_code (stmt) == GIMPLE_ASSIGN)
      {
!       tree op0 = gimple_assign_lhs (stmt);
!       tree op1 = gimple_assign_rhs1 (stmt);
  
        /* For each memory access, analyze its access function
  	 and record a bound on the loop iteration domain.  */
*************** infer_loop_bounds_from_array (struct loo
*** 2644,2660 ****
        if (REFERENCE_CLASS_P (op1))
  	infer_loop_bounds_from_ref (loop, stmt, op1, reliable);
      }
!   
!   
!   call = get_call_expr_in (stmt);
!   if (call)
      {
!       tree arg;
!       call_expr_arg_iterator iter;
  
!       FOR_EACH_CALL_EXPR_ARG (arg, iter, call)
! 	if (REFERENCE_CLASS_P (arg))
! 	  infer_loop_bounds_from_ref (loop, stmt, arg, reliable);
      }
  }
  
--- 2690,2710 ----
        if (REFERENCE_CLASS_P (op1))
  	infer_loop_bounds_from_ref (loop, stmt, op1, reliable);
      }
!   else if (gimple_code (stmt) == GIMPLE_CALL)
      {
!       tree arg, lhs;
!       unsigned i, n = gimple_call_num_args (stmt);
  
!       lhs = gimple_call_lhs (stmt);
!       if (lhs && REFERENCE_CLASS_P (lhs))
! 	infer_loop_bounds_from_ref (loop, stmt, lhs, reliable);
! 
!       for (i = 0; i < n; i++)
! 	{
! 	  arg = gimple_call_arg (stmt, i);
! 	  if (REFERENCE_CLASS_P (arg))
! 	    infer_loop_bounds_from_ref (loop, stmt, arg, reliable);
! 	}
      }
  }
  
*************** infer_loop_bounds_from_array (struct loo
*** 2662,2675 ****
     that signed arithmetics in STMT does not overflow.  */
  
  static void
! infer_loop_bounds_from_signedness (struct loop *loop, tree stmt)
  {
    tree def, base, step, scev, type, low, high;
  
!   if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
      return;
  
!   def = GIMPLE_STMT_OPERAND (stmt, 0);
  
    if (TREE_CODE (def) != SSA_NAME)
      return;
--- 2712,2725 ----
     that signed arithmetics in STMT does not overflow.  */
  
  static void
! infer_loop_bounds_from_signedness (struct loop *loop, gimple stmt)
  {
    tree def, base, step, scev, type, low, high;
  
!   if (gimple_code (stmt) != GIMPLE_ASSIGN)
      return;
  
!   def = gimple_assign_lhs (stmt);
  
    if (TREE_CODE (def) != SSA_NAME)
      return;
*************** infer_loop_bounds_from_undefined (struct
*** 2712,2718 ****
  {
    unsigned i;
    basic_block *bbs;
!   block_stmt_iterator bsi;
    basic_block bb;
    bool reliable;
    
--- 2762,2768 ----
  {
    unsigned i;
    basic_block *bbs;
!   gimple_stmt_iterator bsi;
    basic_block bb;
    bool reliable;
    
*************** infer_loop_bounds_from_undefined (struct
*** 2727,2735 ****
  	 # of iterations of the loop.  However, we can use it as a guess.  */
        reliable = dominated_by_p (CDI_DOMINATORS, loop->latch, bb);
  
!       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
  	{
! 	  tree stmt = bsi_stmt (bsi);
  
  	  infer_loop_bounds_from_array (loop, stmt, reliable);
  
--- 2777,2785 ----
  	 # of iterations of the loop.  However, we can use it as a guess.  */
        reliable = dominated_by_p (CDI_DOMINATORS, loop->latch, bb);
  
!       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
  	{
! 	  gimple stmt = gsi_stmt (bsi);
  
  	  infer_loop_bounds_from_array (loop, stmt, reliable);
  
*************** estimate_numbers_of_iterations (void)
*** 2839,2845 ****
  /* Returns true if statement S1 dominates statement S2.  */
  
  bool
! stmt_dominates_stmt_p (tree s1, tree s2)
  {
    basic_block bb1 = gimple_bb (s1), bb2 = gimple_bb (s2);
  
--- 2889,2895 ----
  /* Returns true if statement S1 dominates statement S2.  */
  
  bool
! stmt_dominates_stmt_p (gimple s1, gimple s2)
  {
    basic_block bb1 = gimple_bb (s1), bb2 = gimple_bb (s2);
  
*************** stmt_dominates_stmt_p (tree s1, tree s2)
*** 2849,2858 ****
  
    if (bb1 == bb2)
      {
!       block_stmt_iterator bsi;
  
!       for (bsi = bsi_start (bb1); bsi_stmt (bsi) != s2; bsi_next (&bsi))
! 	if (bsi_stmt (bsi) == s1)
  	  return true;
  
        return false;
--- 2899,2908 ----
  
    if (bb1 == bb2)
      {
!       gimple_stmt_iterator bsi;
  
!       for (bsi = gsi_start_bb (bb1); gsi_stmt (bsi) != s2; gsi_next (&bsi))
! 	if (gsi_stmt (bsi) == s1)
  	  return true;
  
        return false;
*************** stmt_dominates_stmt_p (tree s1, tree s2)
*** 2868,2874 ****
     statements in the loop.  */
  
  static bool
! n_of_executions_at_most (tree stmt,
  			 struct nb_iter_bound *niter_bound, 
  			 tree niter)
  {
--- 2918,2924 ----
     statements in the loop.  */
  
  static bool
! n_of_executions_at_most (gimple stmt,
  			 struct nb_iter_bound *niter_bound, 
  			 tree niter)
  {
*************** nowrap_type_p (tree type)
*** 2952,2958 ****
  
  bool
  scev_probably_wraps_p (tree base, tree step, 
! 		       tree at_stmt, struct loop *loop,
  		       bool use_overflow_semantics)
  {
    struct nb_iter_bound *bound;
--- 3002,3008 ----
  
  bool
  scev_probably_wraps_p (tree base, tree step, 
! 		       gimple at_stmt, struct loop *loop,
  		       bool use_overflow_semantics)
  {
    struct nb_iter_bound *bound;
*************** substitute_in_loop_info (struct loop *lo
*** 3077,3080 ****
  {
    loop->nb_iterations = simplify_replace_tree (loop->nb_iterations, name, val);
  }
- #endif
--- 3127,3129 ----
Index: tree-ssa-loop-manip.c
===================================================================
*** tree-ssa-loop-manip.c	(revision 132890)
--- tree-ssa-loop-manip.c	(working copy)
*************** verify_loop_closed_ssa (void)
*** 462,469 ****
      }
  }
  
- /* FIXME tuples.  */
- #if 0
  /* Split loop exit edge EXIT.  The things are a bit complicated by a need to
     preserve the loop closed ssa form.  The newly created block is returned.  */
  
--- 462,467 ----
*************** split_loop_exit_edge (edge exit)
*** 472,482 ****
  {
    basic_block dest = exit->dest;
    basic_block bb = split_edge (exit);
!   tree phi, new_phi, new_name, name;
    use_operand_p op_p;
  
!   for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
      {
        op_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (bb));
  
        name = USE_FROM_PTR (op_p);
--- 470,483 ----
  {
    basic_block dest = exit->dest;
    basic_block bb = split_edge (exit);
!   gimple phi, new_phi;
!   tree new_name, name;
    use_operand_p op_p;
+   gimple_stmt_iterator psi;
  
!   for (psi = gsi_start (phi_nodes (dest)); !gsi_end_p (psi); gsi_next (&psi))
      {
+       phi = gsi_stmt (psi);
        op_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (bb));
  
        name = USE_FROM_PTR (op_p);
*************** split_loop_exit_edge (edge exit)
*** 498,503 ****
--- 499,506 ----
    return bb;
  }
  
+ /* FIXME tuples.  */
+ #if 0
  /* Returns the basic block in that statements should be emitted for induction
     variables incremented at the end of the LOOP.  */
  
Index: tree-scalar-evolution.c
===================================================================
*** tree-scalar-evolution.c	(revision 132890)
--- tree-scalar-evolution.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 252,259 ****
  #include "flags.h"
  #include "params.h"
  
- /* FIXME tuples.  */
- #if 0
  static tree analyze_scalar_evolution_1 (struct loop *, tree, tree);
  
  /* The cached information about a ssa name VAR, claiming that inside LOOP,
--- 252,257 ----
*************** chrec_contains_symbols_defined_in_loop (
*** 375,381 ****
  
    if (TREE_CODE (chrec) == SSA_NAME)
      {
!       tree def = SSA_NAME_DEF_STMT (chrec);
        struct loop *def_loop = loop_containing_stmt (def);
        struct loop *loop = get_loop (loop_nb);
  
--- 373,379 ----
  
    if (TREE_CODE (chrec) == SSA_NAME)
      {
!       gimple def = SSA_NAME_DEF_STMT (chrec);
        struct loop *def_loop = loop_containing_stmt (def);
        struct loop *loop = get_loop (loop_nb);
  
*************** chrec_contains_symbols_defined_in_loop (
*** 399,405 ****
  /* Return true when PHI is a loop-phi-node.  */
  
  static bool
! loop_phi_node_p (tree phi)
  {
    /* The implementation of this function is based on the following
       property: "all the loop-phi-nodes of a loop are contained in the
--- 397,403 ----
  /* Return true when PHI is a loop-phi-node.  */
  
  static bool
! loop_phi_node_p (gimple phi)
  {
    /* The implementation of this function is based on the following
       property: "all the loop-phi-nodes of a loop are contained in the
*************** get_scalar_evolution (tree scalar)
*** 634,640 ****
  
  static tree
  add_to_evolution_1 (unsigned loop_nb, tree chrec_before, tree to_add,
! 		    tree at_stmt)
  {
    tree type, left, right;
    struct loop *loop = get_loop (loop_nb), *chloop;
--- 632,638 ----
  
  static tree
  add_to_evolution_1 (unsigned loop_nb, tree chrec_before, tree to_add,
! 		    gimple at_stmt)
  {
    tree type, left, right;
    struct loop *loop = get_loop (loop_nb), *chloop;
*************** add_to_evolution_1 (unsigned loop_nb, tr
*** 831,837 ****
  
  static tree 
  add_to_evolution (unsigned loop_nb, tree chrec_before, enum tree_code code,
! 		  tree to_add, tree at_stmt)
  {
    tree type = chrec_type (to_add);
    tree res = NULL_TREE;
--- 829,835 ----
  
  static tree 
  add_to_evolution (unsigned loop_nb, tree chrec_before, enum tree_code code,
! 		  tree to_add, gimple at_stmt)
  {
    tree type = chrec_type (to_add);
    tree res = NULL_TREE;
*************** set_nb_iterations_in_loop (struct loop *
*** 896,942 ****
     scalar evolution analysis.  For the moment, greedily select all the
     loop nests we could analyze.  */
  
- /* Return true when it is possible to analyze the condition expression
-    EXPR.  */
- 
- static bool
- analyzable_condition (const_tree expr)
- {
-   tree condition;
-   
-   if (TREE_CODE (expr) != COND_EXPR)
-     return false;
-   
-   condition = TREE_OPERAND (expr, 0);
-   
-   switch (TREE_CODE (condition))
-     {
-     case SSA_NAME:
-       return true;
-       
-     case LT_EXPR:
-     case LE_EXPR:
-     case GT_EXPR:
-     case GE_EXPR:
-     case EQ_EXPR:
-     case NE_EXPR:
-       return true;
-       
-     default:
-       return false;
-     }
-   
-   return false;
- }
- 
  /* For a loop with a single exit edge, return the COND_EXPR that
     guards the exit edge.  If the expression is too difficult to
     analyze, then give up.  */
  
! tree 
  get_loop_exit_condition (const struct loop *loop)
  {
!   tree res = NULL_TREE;
    edge exit_edge = single_exit (loop);
    
    if (dump_file && (dump_flags & TDF_DETAILS))
--- 894,907 ----
     scalar evolution analysis.  For the moment, greedily select all the
     loop nests we could analyze.  */
  
  /* For a loop with a single exit edge, return the COND_EXPR that
     guards the exit edge.  If the expression is too difficult to
     analyze, then give up.  */
  
! gimple 
  get_loop_exit_condition (const struct loop *loop)
  {
!   gimple res = NULL;
    edge exit_edge = single_exit (loop);
    
    if (dump_file && (dump_flags & TDF_DETAILS))
*************** get_loop_exit_condition (const struct lo
*** 944,959 ****
    
    if (exit_edge)
      {
!       tree expr;
        
!       expr = last_stmt (exit_edge->src);
!       if (analyzable_condition (expr))
! 	res = expr;
      }
    
    if (dump_file && (dump_flags & TDF_DETAILS))
      {
!       print_generic_expr (dump_file, res, 0);
        fprintf (dump_file, ")\n");
      }
    
--- 909,924 ----
    
    if (exit_edge)
      {
!       gimple stmt;
        
!       stmt = last_stmt (exit_edge->src);
!       if (gimple_code (stmt) == GIMPLE_COND)
! 	res = stmt;
      }
    
    if (dump_file && (dump_flags & TDF_DETAILS))
      {
!       print_gimple_stmt (dump_file, res, 0, 0);
        fprintf (dump_file, ")\n");
      }
    
*************** get_loop_exit_condition (const struct lo
*** 964,970 ****
  
  static void 
  get_exit_conditions_rec (struct loop *loop, 
! 			 VEC(tree,heap) **exit_conditions)
  {
    if (!loop)
      return;
--- 929,935 ----
  
  static void 
  get_exit_conditions_rec (struct loop *loop, 
! 			 VEC(gimple,heap) **exit_conditions)
  {
    if (!loop)
      return;
*************** get_exit_conditions_rec (struct loop *lo
*** 975,984 ****
    
    if (single_exit (loop))
      {
!       tree loop_condition = get_loop_exit_condition (loop);
        
        if (loop_condition)
! 	VEC_safe_push (tree, heap, *exit_conditions, loop_condition);
      }
  }
  
--- 940,949 ----
    
    if (single_exit (loop))
      {
!       gimple loop_condition = get_loop_exit_condition (loop);
        
        if (loop_condition)
! 	VEC_safe_push (gimple, heap, *exit_conditions, loop_condition);
      }
  }
  
*************** get_exit_conditions_rec (struct loop *lo
*** 986,992 ****
     initializes the EXIT_CONDITIONS array.  */
  
  static void
! select_loops_exit_conditions (VEC(tree,heap) **exit_conditions)
  {
    struct loop *function_body = current_loops->tree_root;
    
--- 951,957 ----
     initializes the EXIT_CONDITIONS array.  */
  
  static void
! select_loops_exit_conditions (VEC(gimple,heap) **exit_conditions)
  {
    struct loop *function_body = current_loops->tree_root;
    
*************** typedef enum t_bool {
*** 1003,1061 ****
  } t_bool;
  
  
! static t_bool follow_ssa_edge (struct loop *loop, tree, tree, tree *, int);
  
! /* Follow the ssa edge into the right hand side RHS of an assignment.
     Return true if the strongly connected component has been found.  */
  
  static t_bool
! follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs, 
! 			tree halting_phi, tree *evolution_of_loop, int limit)
  {
    t_bool res = t_false;
-   tree rhs0, rhs1;
-   tree type_rhs = TREE_TYPE (rhs);
    tree evol;
!   enum tree_code code;
!   
!   /* The RHS is one of the following cases:
!      - an SSA_NAME, 
!      - an INTEGER_CST,
!      - a PLUS_EXPR, 
!      - a POINTER_PLUS_EXPR, 
!      - a MINUS_EXPR,
!      - an ASSERT_EXPR,
!      - other cases are not yet handled.  */
!   code = TREE_CODE (rhs);
    switch (code)
      {
-     case NOP_EXPR:
-       /* This assignment is under the form "a_1 = (cast) rhs.  */
-       res = follow_ssa_edge_in_rhs (loop, at_stmt, TREE_OPERAND (rhs, 0),
- 				    halting_phi, evolution_of_loop, limit);
-       *evolution_of_loop = chrec_convert (TREE_TYPE (rhs),
- 					  *evolution_of_loop, at_stmt);
-       break;
- 
-     case INTEGER_CST:
-       /* This assignment is under the form "a_1 = 7".  */
-       res = t_false;
-       break;
-       
-     case SSA_NAME:
-       /* This assignment is under the form: "a_1 = b_2".  */
-       res = follow_ssa_edge 
- 	(loop, SSA_NAME_DEF_STMT (rhs), halting_phi, evolution_of_loop, limit);
-       break;
-       
      case POINTER_PLUS_EXPR:
      case PLUS_EXPR:
-       /* This case is under the form "rhs0 + rhs1".  */
-       rhs0 = TREE_OPERAND (rhs, 0);
-       rhs1 = TREE_OPERAND (rhs, 1);
-       STRIP_TYPE_NOPS (rhs0);
-       STRIP_TYPE_NOPS (rhs1);
- 
        if (TREE_CODE (rhs0) == SSA_NAME)
  	{
  	  if (TREE_CODE (rhs1) == SSA_NAME)
--- 968,990 ----
  } t_bool;
  
  
! static t_bool follow_ssa_edge (struct loop *loop, gimple, gimple, tree *, int);
  
! /* Follow the ssa edge into the binary expression RHS0 CODE RHS1.
     Return true if the strongly connected component has been found.  */
  
  static t_bool
! follow_ssa_edge_binary (struct loop *loop, gimple at_stmt,
! 			tree type, tree rhs0, enum tree_code code, tree rhs1,
! 			gimple halting_phi, tree *evolution_of_loop, int limit)
  {
    t_bool res = t_false;
    tree evol;
! 
    switch (code)
      {
      case POINTER_PLUS_EXPR:
      case PLUS_EXPR:
        if (TREE_CODE (rhs0) == SSA_NAME)
  	{
  	  if (TREE_CODE (rhs1) == SSA_NAME)
*************** follow_ssa_edge_in_rhs (struct loop *loo
*** 1070,1082 ****
  
  	      evol = *evolution_of_loop;
  	      res = follow_ssa_edge 
! 		(loop, SSA_NAME_DEF_STMT (rhs0), halting_phi, 
! 		 &evol, limit);
  	      
  	      if (res == t_true)
  		*evolution_of_loop = add_to_evolution 
  		  (loop->num, 
! 		   chrec_convert (type_rhs, evol, at_stmt), 
  		   code, rhs1, at_stmt);
  	      
  	      else if (res == t_false)
--- 999,1010 ----
  
  	      evol = *evolution_of_loop;
  	      res = follow_ssa_edge 
! 		(loop, SSA_NAME_DEF_STMT (rhs0), halting_phi, &evol, limit);
  	      
  	      if (res == t_true)
  		*evolution_of_loop = add_to_evolution 
  		  (loop->num, 
! 		   chrec_convert (type, evol, at_stmt), 
  		   code, rhs1, at_stmt);
  	      
  	      else if (res == t_false)
*************** follow_ssa_edge_in_rhs (struct loop *loo
*** 1088,1094 ****
  		  if (res == t_true)
  		    *evolution_of_loop = add_to_evolution 
  		      (loop->num, 
! 		       chrec_convert (type_rhs, *evolution_of_loop, at_stmt), 
  		       code, rhs0, at_stmt);
  
  		  else if (res == t_dont_know)
--- 1016,1022 ----
  		  if (res == t_true)
  		    *evolution_of_loop = add_to_evolution 
  		      (loop->num, 
! 		       chrec_convert (type, *evolution_of_loop, at_stmt), 
  		       code, rhs0, at_stmt);
  
  		  else if (res == t_dont_know)
*************** follow_ssa_edge_in_rhs (struct loop *loo
*** 1108,1114 ****
  		 evolution_of_loop, limit);
  	      if (res == t_true)
  		*evolution_of_loop = add_to_evolution 
! 		  (loop->num, chrec_convert (type_rhs, *evolution_of_loop,
  					     at_stmt),
  		   code, rhs1, at_stmt);
  
--- 1036,1042 ----
  		 evolution_of_loop, limit);
  	      if (res == t_true)
  		*evolution_of_loop = add_to_evolution 
! 		  (loop->num, chrec_convert (type, *evolution_of_loop,
  					     at_stmt),
  		   code, rhs1, at_stmt);
  
*************** follow_ssa_edge_in_rhs (struct loop *loo
*** 1126,1132 ****
  	     evolution_of_loop, limit);
  	  if (res == t_true)
  	    *evolution_of_loop = add_to_evolution 
! 	      (loop->num, chrec_convert (type_rhs, *evolution_of_loop,
  					 at_stmt),
  	       code, rhs0, at_stmt);
  
--- 1054,1060 ----
  	     evolution_of_loop, limit);
  	  if (res == t_true)
  	    *evolution_of_loop = add_to_evolution 
! 	      (loop->num, chrec_convert (type, *evolution_of_loop,
  					 at_stmt),
  	       code, rhs0, at_stmt);
  
*************** follow_ssa_edge_in_rhs (struct loop *loo
*** 1139,1154 ****
  	   "a = ... + ...".  */
  	/* And there is nothing to do.  */
  	res = t_false;
-       
        break;
        
      case MINUS_EXPR:
        /* This case is under the form "opnd0 = rhs0 - rhs1".  */
-       rhs0 = TREE_OPERAND (rhs, 0);
-       rhs1 = TREE_OPERAND (rhs, 1);
-       STRIP_TYPE_NOPS (rhs0);
-       STRIP_TYPE_NOPS (rhs1);
- 
        if (TREE_CODE (rhs0) == SSA_NAME)
  	{
  	  /* Match an assignment under the form: 
--- 1067,1076 ----
*************** follow_ssa_edge_in_rhs (struct loop *loo
*** 1164,1170 ****
  				 evolution_of_loop, limit);
  	  if (res == t_true)
  	    *evolution_of_loop = add_to_evolution 
! 	      (loop->num, chrec_convert (type_rhs, *evolution_of_loop, at_stmt),
  	       MINUS_EXPR, rhs1, at_stmt);
  
  	  else if (res == t_dont_know)
--- 1086,1092 ----
  				 evolution_of_loop, limit);
  	  if (res == t_true)
  	    *evolution_of_loop = add_to_evolution 
! 	      (loop->num, chrec_convert (type, *evolution_of_loop, at_stmt),
  	       MINUS_EXPR, rhs1, at_stmt);
  
  	  else if (res == t_dont_know)
*************** follow_ssa_edge_in_rhs (struct loop *loo
*** 1175,1188 ****
  	   "a = ... - ...".  */
  	/* And there is nothing to do.  */
  	res = t_false;
-       
        break;
      
      case ASSERT_EXPR:
        {
  	/* This assignment is of the form: "a_1 = ASSERT_EXPR <a_2, ...>"
  	   It must be handled as a copy assignment of the form a_1 = a_2.  */
! 	tree op0 = ASSERT_EXPR_VAR (rhs);
  	if (TREE_CODE (op0) == SSA_NAME)
  	  res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (op0),
  				 halting_phi, evolution_of_loop, limit);
--- 1097,1168 ----
  	   "a = ... - ...".  */
  	/* And there is nothing to do.  */
  	res = t_false;
        break;
+ 
+     default:
+       res = t_false;
+     }
+ 
+   return res;
+ }
      
+ /* Follow the ssa edge into the expression EXPR.
+    Return true if the strongly connected component has been found.  */
+ 
+ static t_bool
+ follow_ssa_edge_expr (struct loop *loop, gimple at_stmt, tree expr, 
+ 		      gimple halting_phi, tree *evolution_of_loop, int limit)
+ {
+   t_bool res = t_false;
+   tree rhs0, rhs1;
+   tree type = TREE_TYPE (expr);
+   enum tree_code code;
+   
+   /* The EXPR is one of the following cases:
+      - an SSA_NAME, 
+      - an INTEGER_CST,
+      - a PLUS_EXPR, 
+      - a POINTER_PLUS_EXPR, 
+      - a MINUS_EXPR,
+      - an ASSERT_EXPR,
+      - other cases are not yet handled.  */
+   code = TREE_CODE (expr);
+   switch (code)
+     {
+     case NOP_EXPR:
+       /* This assignment is under the form "a_1 = (cast) rhs.  */
+       res = follow_ssa_edge_expr (loop, at_stmt, TREE_OPERAND (expr, 0),
+ 				  halting_phi, evolution_of_loop, limit);
+       *evolution_of_loop = chrec_convert (type, *evolution_of_loop, at_stmt);
+       break;
+ 
+     case INTEGER_CST:
+       /* This assignment is under the form "a_1 = 7".  */
+       res = t_false;
+       break;
+       
+     case SSA_NAME:
+       /* This assignment is under the form: "a_1 = b_2".  */
+       res = follow_ssa_edge 
+ 	(loop, SSA_NAME_DEF_STMT (expr), halting_phi, evolution_of_loop, limit);
+       break;
+       
+     case POINTER_PLUS_EXPR:
+     case PLUS_EXPR:
+     case MINUS_EXPR:
+       /* This case is under the form "rhs0 +- rhs1".  */
+       rhs0 = TREE_OPERAND (expr, 0);
+       rhs1 = TREE_OPERAND (expr, 1);
+       STRIP_TYPE_NOPS (rhs0);
+       STRIP_TYPE_NOPS (rhs1);
+       return follow_ssa_edge_binary (loop, at_stmt, type, rhs0, code, rhs1,
+ 				     halting_phi, evolution_of_loop, limit);
+ 
      case ASSERT_EXPR:
        {
  	/* This assignment is of the form: "a_1 = ASSERT_EXPR <a_2, ...>"
  	   It must be handled as a copy assignment of the form a_1 = a_2.  */
! 	tree op0 = ASSERT_EXPR_VAR (expr);
  	if (TREE_CODE (op0) == SSA_NAME)
  	  res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (op0),
  				 halting_phi, evolution_of_loop, limit);
*************** follow_ssa_edge_in_rhs (struct loop *loo
*** 1200,1211 ****
    return res;
  }
  
  /* Checks whether the I-th argument of a PHI comes from a backedge.  */
  
  static bool
! backedge_phi_arg_p (const_tree phi, int i)
  {
!   const_edge e = PHI_ARG_EDGE (phi, i);
  
    /* We would in fact like to test EDGE_DFS_BACK here, but we do not care
       about updating it anywhere, and this should work as well most of the
--- 1180,1216 ----
    return res;
  }
  
+ /* Follow the ssa edge into the right hand side of an assignment STMT.
+    Return true if the strongly connected component has been found.  */
+ 
+ static t_bool
+ follow_ssa_edge_in_rhs (struct loop *loop, gimple stmt,
+ 			gimple halting_phi, tree *evolution_of_loop, int limit)
+ {
+   tree type = TREE_TYPE (gimple_assign_lhs (stmt));
+   enum tree_code code = gimple_assign_subcode (stmt);
+ 
+   switch (get_gimple_rhs_class (code))
+     {
+     case GIMPLE_BINARY_RHS:
+       return follow_ssa_edge_binary (loop, stmt, type,
+ 				     gimple_assign_rhs1 (stmt), code,
+ 				     gimple_assign_rhs2 (stmt),
+ 				     halting_phi, evolution_of_loop, limit);
+     case GIMPLE_SINGLE_RHS:
+       return follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
+ 				   halting_phi, evolution_of_loop, limit);
+     default:
+       return t_false;
+     }
+ }
+ 
  /* Checks whether the I-th argument of a PHI comes from a backedge.  */
  
  static bool
! backedge_phi_arg_p (gimple phi, int i)
  {
!   const_edge e = gimple_phi_arg_edge (phi, i);
  
    /* We would in fact like to test EDGE_DFS_BACK here, but we do not care
       about updating it anywhere, and this should work as well most of the
*************** backedge_phi_arg_p (const_tree phi, int 
*** 1223,1230 ****
  static inline t_bool
  follow_ssa_edge_in_condition_phi_branch (int i,
  					 struct loop *loop, 
! 					 tree condition_phi, 
! 					 tree halting_phi,
  					 tree *evolution_of_branch,
  					 tree init_cond, int limit)
  {
--- 1228,1235 ----
  static inline t_bool
  follow_ssa_edge_in_condition_phi_branch (int i,
  					 struct loop *loop, 
! 					 gimple condition_phi, 
! 					 gimple halting_phi,
  					 tree *evolution_of_branch,
  					 tree init_cond, int limit)
  {
*************** follow_ssa_edge_in_condition_phi_branch 
*** 1258,1268 ****
  
  static t_bool
  follow_ssa_edge_in_condition_phi (struct loop *loop,
! 				  tree condition_phi, 
! 				  tree halting_phi, 
  				  tree *evolution_of_loop, int limit)
  {
!   int i;
    tree init = *evolution_of_loop;
    tree evolution_of_branch;
    t_bool res = follow_ssa_edge_in_condition_phi_branch (0, loop, condition_phi,
--- 1263,1273 ----
  
  static t_bool
  follow_ssa_edge_in_condition_phi (struct loop *loop,
! 				  gimple condition_phi, 
! 				  gimple halting_phi, 
  				  tree *evolution_of_loop, int limit)
  {
!   int i, n;
    tree init = *evolution_of_loop;
    tree evolution_of_branch;
    t_bool res = follow_ssa_edge_in_condition_phi_branch (0, loop, condition_phi,
*************** follow_ssa_edge_in_condition_phi (struct
*** 1275,1284 ****
    *evolution_of_loop = evolution_of_branch;
  
    /* If the phi node is just a copy, do not increase the limit.  */
!   if (PHI_NUM_ARGS (condition_phi) > 1)
      limit++;
  
!   for (i = 1; i < PHI_NUM_ARGS (condition_phi); i++)
      {
        /* Quickly give up when the evolution of one of the branches is
  	 not known.  */
--- 1280,1290 ----
    *evolution_of_loop = evolution_of_branch;
  
    /* If the phi node is just a copy, do not increase the limit.  */
!   n = gimple_phi_num_args (condition_phi);
!   if (n > 1)
      limit++;
  
!   for (i = 1; i < n; i++)
      {
        /* Quickly give up when the evolution of one of the branches is
  	 not known.  */
*************** follow_ssa_edge_in_condition_phi (struct
*** 1306,1313 ****
  
  static t_bool
  follow_ssa_edge_inner_loop_phi (struct loop *outer_loop,
! 				tree loop_phi_node, 
! 				tree halting_phi,
  				tree *evolution_of_loop, int limit)
  {
    struct loop *loop = loop_containing_stmt (loop_phi_node);
--- 1312,1319 ----
  
  static t_bool
  follow_ssa_edge_inner_loop_phi (struct loop *outer_loop,
! 				gimple loop_phi_node, 
! 				gimple halting_phi,
  				tree *evolution_of_loop, int limit)
  {
    struct loop *loop = loop_containing_stmt (loop_phi_node);
*************** follow_ssa_edge_inner_loop_phi (struct l
*** 1318,1336 ****
    if (ev == PHI_RESULT (loop_phi_node))
      {
        t_bool res = t_false;
!       int i;
  
!       for (i = 0; i < PHI_NUM_ARGS (loop_phi_node); i++)
  	{
  	  tree arg = PHI_ARG_DEF (loop_phi_node, i);
  	  basic_block bb;
  
  	  /* Follow the edges that exit the inner loop.  */
! 	  bb = PHI_ARG_EDGE (loop_phi_node, i)->src;
  	  if (!flow_bb_inside_loop_p (loop, bb))
! 	    res = follow_ssa_edge_in_rhs (outer_loop, loop_phi_node,
! 					  arg, halting_phi,
! 					  evolution_of_loop, limit);
  	  if (res == t_true)
  	    break;
  	}
--- 1324,1342 ----
    if (ev == PHI_RESULT (loop_phi_node))
      {
        t_bool res = t_false;
!       int i, n = gimple_phi_num_args (loop_phi_node);
  
!       for (i = 0; i < n; i++)
  	{
  	  tree arg = PHI_ARG_DEF (loop_phi_node, i);
  	  basic_block bb;
  
  	  /* Follow the edges that exit the inner loop.  */
! 	  bb = gimple_phi_arg_edge (loop_phi_node, i)->src;
  	  if (!flow_bb_inside_loop_p (loop, bb))
! 	    res = follow_ssa_edge_expr (outer_loop, loop_phi_node,
! 					arg, halting_phi,
! 					evolution_of_loop, limit);
  	  if (res == t_true)
  	    break;
  	}
*************** follow_ssa_edge_inner_loop_phi (struct l
*** 1344,1363 ****
  
    /* Otherwise, compute the overall effect of the inner loop.  */
    ev = compute_overall_effect_of_inner_loop (loop, ev);
!   return follow_ssa_edge_in_rhs (outer_loop, loop_phi_node, ev, halting_phi,
! 				 evolution_of_loop, limit);
  }
  
  /* Follow an SSA edge from a loop-phi-node to itself, constructing a
     path that is analyzed on the return walk.  */
  
  static t_bool
! follow_ssa_edge (struct loop *loop, tree def, tree halting_phi,
  		 tree *evolution_of_loop, int limit)
  {
    struct loop *def_loop;
    
!   if (TREE_CODE (def) == NOP_EXPR)
      return t_false;
    
    /* Give up if the path is longer than the MAX that we allow.  */
--- 1350,1369 ----
  
    /* Otherwise, compute the overall effect of the inner loop.  */
    ev = compute_overall_effect_of_inner_loop (loop, ev);
!   return follow_ssa_edge_expr (outer_loop, loop_phi_node, ev, halting_phi,
! 			       evolution_of_loop, limit);
  }
  
  /* Follow an SSA edge from a loop-phi-node to itself, constructing a
     path that is analyzed on the return walk.  */
  
  static t_bool
! follow_ssa_edge (struct loop *loop, gimple def, gimple halting_phi,
  		 tree *evolution_of_loop, int limit)
  {
    struct loop *def_loop;
    
!   if (gimple_nop_p (def))
      return t_false;
    
    /* Give up if the path is longer than the MAX that we allow.  */
*************** follow_ssa_edge (struct loop *loop, tree
*** 1366,1374 ****
    
    def_loop = loop_containing_stmt (def);
    
!   switch (TREE_CODE (def))
      {
!     case PHI_NODE:
        if (!loop_phi_node_p (def))
  	/* DEF is a condition-phi-node.  Follow the branches, and
  	   record their evolutions.  Finally, merge the collected
--- 1372,1380 ----
    
    def_loop = loop_containing_stmt (def);
    
!   switch (gimple_code (def))
      {
!     case GIMPLE_PHI:
        if (!loop_phi_node_p (def))
  	/* DEF is a condition-phi-node.  Follow the branches, and
  	   record their evolutions.  Finally, merge the collected
*************** follow_ssa_edge (struct loop *loop, tree
*** 1397,1406 ****
        /* Outer loop.  */
        return t_false;
  
!     case GIMPLE_MODIFY_STMT:
!       return follow_ssa_edge_in_rhs (loop, def,
! 				     GIMPLE_STMT_OPERAND (def, 1), 
! 				     halting_phi, 
  				     evolution_of_loop, limit);
        
      default:
--- 1403,1410 ----
        /* Outer loop.  */
        return t_false;
  
!     case GIMPLE_ASSIGN:
!       return follow_ssa_edge_in_rhs (loop, def, halting_phi, 
  				     evolution_of_loop, limit);
        
      default:
*************** follow_ssa_edge (struct loop *loop, tree
*** 1417,1426 ****
     function from LOOP_PHI_NODE to LOOP_PHI_NODE in the loop.  */
  
  static tree
! analyze_evolution_in_loop (tree loop_phi_node, 
  			   tree init_cond)
  {
!   int i;
    tree evolution_function = chrec_not_analyzed_yet;
    struct loop *loop = loop_containing_stmt (loop_phi_node);
    basic_block bb;
--- 1421,1430 ----
     function from LOOP_PHI_NODE to LOOP_PHI_NODE in the loop.  */
  
  static tree
! analyze_evolution_in_loop (gimple loop_phi_node, 
  			   tree init_cond)
  {
!   int i, n = gimple_phi_num_args (loop_phi_node);
    tree evolution_function = chrec_not_analyzed_yet;
    struct loop *loop = loop_containing_stmt (loop_phi_node);
    basic_block bb;
*************** analyze_evolution_in_loop (tree loop_phi
*** 1429,1446 ****
      {
        fprintf (dump_file, "(analyze_evolution_in_loop \n");
        fprintf (dump_file, "  (loop_phi_node = ");
!       print_generic_expr (dump_file, loop_phi_node, 0);
        fprintf (dump_file, ")\n");
      }
    
!   for (i = 0; i < PHI_NUM_ARGS (loop_phi_node); i++)
      {
        tree arg = PHI_ARG_DEF (loop_phi_node, i);
!       tree ssa_chain, ev_fn;
        t_bool res;
  
        /* Select the edges that enter the loop body.  */
!       bb = PHI_ARG_EDGE (loop_phi_node, i)->src;
        if (!flow_bb_inside_loop_p (loop, bb))
  	continue;
        
--- 1433,1451 ----
      {
        fprintf (dump_file, "(analyze_evolution_in_loop \n");
        fprintf (dump_file, "  (loop_phi_node = ");
!       print_gimple_stmt (dump_file, loop_phi_node, 0, 0);
        fprintf (dump_file, ")\n");
      }
    
!   for (i = 0; i < n; i++)
      {
        tree arg = PHI_ARG_DEF (loop_phi_node, i);
!       gimple ssa_chain;
!       tree ev_fn;
        t_bool res;
  
        /* Select the edges that enter the loop body.  */
!       bb = gimple_phi_arg_edge (loop_phi_node, i)->src;
        if (!flow_bb_inside_loop_p (loop, bb))
  	continue;
        
*************** analyze_evolution_in_loop (tree loop_phi
*** 1487,1510 ****
     loop, and leaves this task to the on-demand tree reconstructor.  */
  
  static tree 
! analyze_initial_condition (tree loop_phi_node)
  {
!   int i;
    tree init_cond = chrec_not_analyzed_yet;
!   struct loop *loop = gimple_bb (loop_phi_node)->loop_father;
    
    if (dump_file && (dump_flags & TDF_DETAILS))
      {
        fprintf (dump_file, "(analyze_initial_condition \n");
        fprintf (dump_file, "  (loop_phi_node = \n");
!       print_generic_expr (dump_file, loop_phi_node, 0);
        fprintf (dump_file, ")\n");
      }
    
!   for (i = 0; i < PHI_NUM_ARGS (loop_phi_node); i++)
      {
        tree branch = PHI_ARG_DEF (loop_phi_node, i);
!       basic_block bb = PHI_ARG_EDGE (loop_phi_node, i)->src;
        
        /* When the branch is oriented to the loop's body, it does
       	 not contribute to the initial condition.  */
--- 1492,1516 ----
     loop, and leaves this task to the on-demand tree reconstructor.  */
  
  static tree 
! analyze_initial_condition (gimple loop_phi_node)
  {
!   int i, n;
    tree init_cond = chrec_not_analyzed_yet;
!   struct loop *loop = loop_containing_stmt (loop_phi_node);
    
    if (dump_file && (dump_flags & TDF_DETAILS))
      {
        fprintf (dump_file, "(analyze_initial_condition \n");
        fprintf (dump_file, "  (loop_phi_node = \n");
!       print_gimple_stmt (dump_file, loop_phi_node, 0, 0);
        fprintf (dump_file, ")\n");
      }
    
!   n = gimple_phi_num_args (loop_phi_node);
!   for (i = 0; i < n; i++)
      {
        tree branch = PHI_ARG_DEF (loop_phi_node, i);
!       basic_block bb = gimple_phi_arg_edge (loop_phi_node, i)->src;
        
        /* When the branch is oriented to the loop's body, it does
       	 not contribute to the initial condition.  */
*************** analyze_initial_condition (tree loop_phi
*** 1543,1549 ****
  /* Analyze the scalar evolution for LOOP_PHI_NODE.  */
  
  static tree 
! interpret_loop_phi (struct loop *loop, tree loop_phi_node)
  {
    tree res;
    struct loop *phi_loop = loop_containing_stmt (loop_phi_node);
--- 1549,1555 ----
  /* Analyze the scalar evolution for LOOP_PHI_NODE.  */
  
  static tree 
! interpret_loop_phi (struct loop *loop, gimple loop_phi_node)
  {
    tree res;
    struct loop *phi_loop = loop_containing_stmt (loop_phi_node);
*************** interpret_loop_phi (struct loop *loop, t
*** 1575,1586 ****
     analyzed.  */
  
  static tree
! interpret_condition_phi (struct loop *loop, tree condition_phi)
  {
!   int i;
    tree res = chrec_not_analyzed_yet;
    
!   for (i = 0; i < PHI_NUM_ARGS (condition_phi); i++)
      {
        tree branch_chrec;
        
--- 1581,1592 ----
     analyzed.  */
  
  static tree
! interpret_condition_phi (struct loop *loop, gimple condition_phi)
  {
!   int i, n = gimple_phi_num_args (condition_phi);
    tree res = chrec_not_analyzed_yet;
    
!   for (i = 0; i < n; i++)
      {
        tree branch_chrec;
        
*************** interpret_condition_phi (struct loop *lo
*** 1599,1605 ****
    return res;
  }
  
! /* Interpret the right hand side of a GIMPLE_MODIFY_STMT OPND1.  If we didn't
     analyze this node before, follow the definitions until ending
     either on an analyzed GIMPLE_MODIFY_STMT, or on a loop-phi-node.  On the
     return path, this function propagates evolutions (ala constant copy
--- 1605,1611 ----
    return res;
  }
  
! /* Interpret the operation RHS1 OP RHS2.  If we didn't
     analyze this node before, follow the definitions until ending
     either on an analyzed GIMPLE_MODIFY_STMT, or on a loop-phi-node.  On the
     return path, this function propagates evolutions (ala constant copy
*************** interpret_condition_phi (struct loop *lo
*** 1607,1687 ****
     analyze the effect of an inner loop: see interpret_loop_phi.  */
  
  static tree
! interpret_rhs_modify_stmt (struct loop *loop, tree at_stmt,
! 			   	  tree opnd1, tree type)
  {
!   tree res, opnd10, opnd11, chrec10, chrec11;
  
!   if (is_gimple_min_invariant (opnd1))
!     return chrec_convert (type, opnd1, at_stmt);
  
!   switch (TREE_CODE (opnd1))
      {
      case POINTER_PLUS_EXPR:
!       opnd10 = TREE_OPERAND (opnd1, 0);
!       opnd11 = TREE_OPERAND (opnd1, 1);
!       chrec10 = analyze_scalar_evolution (loop, opnd10);
!       chrec11 = analyze_scalar_evolution (loop, opnd11);
!       chrec10 = chrec_convert (type, chrec10, at_stmt);
!       chrec11 = chrec_convert (sizetype, chrec11, at_stmt);
!       res = chrec_fold_plus (type, chrec10, chrec11);
        break;
  
      case PLUS_EXPR:
!       opnd10 = TREE_OPERAND (opnd1, 0);
!       opnd11 = TREE_OPERAND (opnd1, 1);
!       chrec10 = analyze_scalar_evolution (loop, opnd10);
!       chrec11 = analyze_scalar_evolution (loop, opnd11);
!       chrec10 = chrec_convert (type, chrec10, at_stmt);
!       chrec11 = chrec_convert (type, chrec11, at_stmt);
!       res = chrec_fold_plus (type, chrec10, chrec11);
        break;
        
      case MINUS_EXPR:
!       opnd10 = TREE_OPERAND (opnd1, 0);
!       opnd11 = TREE_OPERAND (opnd1, 1);
!       chrec10 = analyze_scalar_evolution (loop, opnd10);
!       chrec11 = analyze_scalar_evolution (loop, opnd11);
!       chrec10 = chrec_convert (type, chrec10, at_stmt);
!       chrec11 = chrec_convert (type, chrec11, at_stmt);
!       res = chrec_fold_minus (type, chrec10, chrec11);
        break;
  
      case NEGATE_EXPR:
!       opnd10 = TREE_OPERAND (opnd1, 0);
!       chrec10 = analyze_scalar_evolution (loop, opnd10);
!       chrec10 = chrec_convert (type, chrec10, at_stmt);
        /* TYPE may be integer, real or complex, so use fold_convert.  */
!       res = chrec_fold_multiply (type, chrec10,
  				 fold_convert (type, integer_minus_one_node));
        break;
  
      case MULT_EXPR:
!       opnd10 = TREE_OPERAND (opnd1, 0);
!       opnd11 = TREE_OPERAND (opnd1, 1);
!       chrec10 = analyze_scalar_evolution (loop, opnd10);
!       chrec11 = analyze_scalar_evolution (loop, opnd11);
!       chrec10 = chrec_convert (type, chrec10, at_stmt);
!       chrec11 = chrec_convert (type, chrec11, at_stmt);
!       res = chrec_fold_multiply (type, chrec10, chrec11);
!       break;
!       
!     case SSA_NAME:
!       res = chrec_convert (type, analyze_scalar_evolution (loop, opnd1),
! 			   at_stmt);
!       break;
! 
!     case ASSERT_EXPR:
!       opnd10 = ASSERT_EXPR_VAR (opnd1);
!       res = chrec_convert (type, analyze_scalar_evolution (loop, opnd10),
! 			   at_stmt);
        break;
        
      case NOP_EXPR:
      case CONVERT_EXPR:
!       opnd10 = TREE_OPERAND (opnd1, 0);
!       chrec10 = analyze_scalar_evolution (loop, opnd10);
!       res = chrec_convert (type, chrec10, at_stmt);
        break;
        
      default:
--- 1613,1688 ----
     analyze the effect of an inner loop: see interpret_loop_phi.  */
  
  static tree
! interpret_rhs_expr (struct loop *loop, gimple at_stmt,
! 		    tree type, tree rhs1, enum tree_code code, tree rhs2)
  {
!   tree res, chrec1, chrec2;
! 
!   if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
!     {
!       if (is_gimple_min_invariant (rhs1))
! 	return chrec_convert (type, rhs1, at_stmt);
! 
!       if (code == SSA_NAME)
! 	return chrec_convert (type, analyze_scalar_evolution (loop, rhs1),
! 			      at_stmt);
  
!       if (code == ASSERT_EXPR)
! 	{
! 	  rhs1 = ASSERT_EXPR_VAR (rhs1);
! 	  return chrec_convert (type, analyze_scalar_evolution (loop, rhs1),
! 				at_stmt);
! 	}
  
!       return chrec_dont_know;
!     }
! 
!   switch (code)
      {
      case POINTER_PLUS_EXPR:
!       chrec1 = analyze_scalar_evolution (loop, rhs1);
!       chrec2 = analyze_scalar_evolution (loop, rhs2);
!       chrec1 = chrec_convert (type, chrec1, at_stmt);
!       chrec2 = chrec_convert (sizetype, chrec2, at_stmt);
!       res = chrec_fold_plus (type, chrec1, chrec2);
        break;
  
      case PLUS_EXPR:
!       chrec1 = analyze_scalar_evolution (loop, rhs1);
!       chrec2 = analyze_scalar_evolution (loop, rhs2);
!       chrec1 = chrec_convert (type, chrec1, at_stmt);
!       chrec2 = chrec_convert (type, chrec2, at_stmt);
!       res = chrec_fold_plus (type, chrec1, chrec2);
        break;
        
      case MINUS_EXPR:
!       chrec1 = analyze_scalar_evolution (loop, rhs1);
!       chrec2 = analyze_scalar_evolution (loop, rhs2);
!       chrec1 = chrec_convert (type, chrec1, at_stmt);
!       chrec2 = chrec_convert (type, chrec2, at_stmt);
!       res = chrec_fold_minus (type, chrec1, chrec2);
        break;
  
      case NEGATE_EXPR:
!       chrec1 = analyze_scalar_evolution (loop, rhs1);
!       chrec1 = chrec_convert (type, chrec1, at_stmt);
        /* TYPE may be integer, real or complex, so use fold_convert.  */
!       res = chrec_fold_multiply (type, chrec1,
  				 fold_convert (type, integer_minus_one_node));
        break;
  
      case MULT_EXPR:
!       chrec1 = analyze_scalar_evolution (loop, rhs1);
!       chrec2 = analyze_scalar_evolution (loop, rhs2);
!       chrec1 = chrec_convert (type, chrec1, at_stmt);
!       chrec2 = chrec_convert (type, chrec2, at_stmt);
!       res = chrec_fold_multiply (type, chrec1, chrec2);
        break;
        
      case NOP_EXPR:
      case CONVERT_EXPR:
!       chrec1 = analyze_scalar_evolution (loop, rhs1);
!       res = chrec_convert (type, chrec1, at_stmt);
        break;
        
      default:
*************** interpret_rhs_modify_stmt (struct loop *
*** 1692,1697 ****
--- 1693,1739 ----
    return res;
  }
  
+ /* Interpret the expression EXPR.  */
+ 
+ static tree
+ interpret_expr (struct loop *loop, gimple at_stmt, tree expr)
+ {
+   enum tree_code code;
+   tree type = TREE_TYPE (expr), op0, op1;
+ 
+   if (automatically_generated_chrec_p (expr))
+     return expr;
+ 
+   extract_ops_from_tree (expr, &code, &op0, &op1);
+ 
+   return interpret_rhs_expr (loop, at_stmt, type,
+ 			     op0, code, op1);
+ }
+ 
+ /* Interpret the rhs of the assignment STMT.  */
+ 
+ static tree
+ interpret_gimple_assign (struct loop *loop, gimple stmt)
+ {
+   tree type = TREE_TYPE (gimple_assign_lhs (stmt));
+   enum tree_code code = gimple_assign_subcode (stmt);
+ 
+   switch (get_gimple_rhs_class (code))
+     {
+     case GIMPLE_BINARY_RHS:
+       return interpret_rhs_expr (loop, stmt, type,
+ 				 gimple_assign_rhs1 (stmt), code,
+ 				 gimple_assign_rhs2 (stmt));
+     case GIMPLE_UNARY_RHS:
+     case GIMPLE_SINGLE_RHS:
+       return interpret_rhs_expr (loop, stmt, type,
+ 				 gimple_assign_rhs1 (stmt), code, NULL_TREE);
+ 
+     default:
+       return chrec_dont_know;
+     }
+ }
+ 
  
  
  /* This section contains all the entry points: 
*************** compute_scalar_evolution_in_loop (struct
*** 1723,1729 ****
  static tree
  analyze_scalar_evolution_1 (struct loop *loop, tree var, tree res)
  {
!   tree def, type = TREE_TYPE (var);
    basic_block bb;
    struct loop *def_loop;
  
--- 1765,1772 ----
  static tree
  analyze_scalar_evolution_1 (struct loop *loop, tree var, tree res)
  {
!   tree type = TREE_TYPE (var);
!   gimple def;
    basic_block bb;
    struct loop *def_loop;
  
*************** analyze_scalar_evolution_1 (struct loop 
*** 1731,1737 ****
      return chrec_dont_know;
  
    if (TREE_CODE (var) != SSA_NAME)
!     return interpret_rhs_modify_stmt (loop, NULL_TREE, var, type);
  
    def = SSA_NAME_DEF_STMT (var);
    bb = gimple_bb (def);
--- 1774,1780 ----
      return chrec_dont_know;
  
    if (TREE_CODE (var) != SSA_NAME)
!     return interpret_expr (loop, NULL, var);
  
    def = SSA_NAME_DEF_STMT (var);
    bb = gimple_bb (def);
*************** analyze_scalar_evolution_1 (struct loop 
*** 1762,1775 ****
        goto set_and_end;
      }
  
!   switch (TREE_CODE (def))
      {
!     case GIMPLE_MODIFY_STMT:
!       res = interpret_rhs_modify_stmt (loop, def,
! 	  			       GIMPLE_STMT_OPERAND (def, 1), type);
        break;
  
!     case PHI_NODE:
        if (loop_phi_node_p (def))
  	res = interpret_loop_phi (loop, def);
        else
--- 1805,1817 ----
        goto set_and_end;
      }
  
!   switch (gimple_code (def))
      {
!     case GIMPLE_ASSIGN:
!       res = interpret_gimple_assign (loop, def);
        break;
  
!     case GIMPLE_PHI:
        if (loop_phi_node_p (def))
  	res = interpret_loop_phi (loop, def);
        else
*************** analyze_scalar_evolution (struct loop *l
*** 1825,1833 ****
  
    res = analyze_scalar_evolution_1 (loop, var, get_scalar_evolution (var));
  
-   if (TREE_CODE (var) == SSA_NAME && res == chrec_dont_know)
-     res = var;
- 
    if (dump_file && (dump_flags & TDF_DETAILS))
      fprintf (dump_file, ")\n");
  
--- 1867,1872 ----
*************** loop_closed_phi_def (tree var)
*** 1914,1920 ****
  {
    struct loop *loop;
    edge exit;
!   tree phi;
  
    if (var == NULL_TREE
        || TREE_CODE (var) != SSA_NAME)
--- 1953,1960 ----
  {
    struct loop *loop;
    edge exit;
!   gimple phi;
!   gimple_stmt_iterator psi;
  
    if (var == NULL_TREE
        || TREE_CODE (var) != SSA_NAME)
*************** loop_closed_phi_def (tree var)
*** 1925,1933 ****
    if (!exit)
      return NULL_TREE;
  
!   for (phi = phi_nodes (exit->dest); phi; phi = PHI_CHAIN (phi))
!     if (PHI_ARG_DEF_FROM_EDGE (phi, exit) == var)
!       return PHI_RESULT (phi);
  
    return NULL_TREE;
  }
--- 1965,1978 ----
    if (!exit)
      return NULL_TREE;
  
!   for (psi = gsi_start (phi_nodes (exit->dest));
!        !gsi_end_p (psi);
!        gsi_next (&psi))
!     {
!       phi = gsi_stmt (psi);
!       if (PHI_ARG_DEF_FROM_EDGE (phi, exit) == var)
! 	return PHI_RESULT (phi);
!     }
  
    return NULL_TREE;
  }
*************** instantiate_parameters_1 (struct loop *l
*** 2050,2056 ****
        if (CHREC_LEFT (chrec) != op0
  	  || CHREC_RIGHT (chrec) != op1)
  	{
! 	  op1 = chrec_convert_rhs (chrec_type (op0), op1, NULL_TREE);
  	  chrec = build_polynomial_chrec (CHREC_VARIABLE (chrec), op0, op1);
  	}
        return chrec;
--- 2095,2101 ----
        if (CHREC_LEFT (chrec) != op0
  	  || CHREC_RIGHT (chrec) != op1)
  	{
! 	  op1 = chrec_convert_rhs (chrec_type (op0), op1, NULL);
  	  chrec = build_polynomial_chrec (CHREC_VARIABLE (chrec), op0, op1);
  	}
        return chrec;
*************** instantiate_parameters_1 (struct loop *l
*** 2070,2077 ****
        if (TREE_OPERAND (chrec, 0) != op0
  	  || TREE_OPERAND (chrec, 1) != op1)
  	{
! 	  op0 = chrec_convert (type, op0, NULL_TREE);
! 	  op1 = chrec_convert_rhs (type, op1, NULL_TREE);
  	  chrec = chrec_fold_plus (type, op0, op1);
  	}
        return chrec;
--- 2115,2122 ----
        if (TREE_OPERAND (chrec, 0) != op0
  	  || TREE_OPERAND (chrec, 1) != op1)
  	{
! 	  op0 = chrec_convert (type, op0, NULL);
! 	  op1 = chrec_convert_rhs (type, op1, NULL);
  	  chrec = chrec_fold_plus (type, op0, op1);
  	}
        return chrec;
*************** instantiate_parameters_1 (struct loop *l
*** 2090,2097 ****
        if (TREE_OPERAND (chrec, 0) != op0
  	  || TREE_OPERAND (chrec, 1) != op1)
  	{
! 	  op0 = chrec_convert (type, op0, NULL_TREE);
! 	  op1 = chrec_convert (type, op1, NULL_TREE);
  	  chrec = chrec_fold_minus (type, op0, op1);
  	}
        return chrec;
--- 2135,2142 ----
        if (TREE_OPERAND (chrec, 0) != op0
  	  || TREE_OPERAND (chrec, 1) != op1)
  	{
! 	  op0 = chrec_convert (type, op0, NULL);
! 	  op1 = chrec_convert (type, op1, NULL);
  	  chrec = chrec_fold_minus (type, op0, op1);
  	}
        return chrec;
*************** instantiate_parameters_1 (struct loop *l
*** 2110,2117 ****
        if (TREE_OPERAND (chrec, 0) != op0
  	  || TREE_OPERAND (chrec, 1) != op1)
  	{
! 	  op0 = chrec_convert (type, op0, NULL_TREE);
! 	  op1 = chrec_convert (type, op1, NULL_TREE);
  	  chrec = chrec_fold_multiply (type, op0, op1);
  	}
        return chrec;
--- 2155,2162 ----
        if (TREE_OPERAND (chrec, 0) != op0
  	  || TREE_OPERAND (chrec, 1) != op1)
  	{
! 	  op0 = chrec_convert (type, op0, NULL);
! 	  op1 = chrec_convert (type, op1, NULL);
  	  chrec = chrec_fold_multiply (type, op0, op1);
  	}
        return chrec;
*************** instantiate_parameters_1 (struct loop *l
*** 2140,2146 ****
        if (flags & FOLD_CONVERSIONS)
  	return fold_convert (TREE_TYPE (chrec), op0);
  
!       return chrec_convert (TREE_TYPE (chrec), op0, NULL_TREE);
  
      case SCEV_NOT_KNOWN:
        return chrec_dont_know;
--- 2185,2191 ----
        if (flags & FOLD_CONVERSIONS)
  	return fold_convert (TREE_TYPE (chrec), op0);
  
!       return chrec_convert (TREE_TYPE (chrec), op0, NULL);
  
      case SCEV_NOT_KNOWN:
        return chrec_dont_know;
*************** number_of_exit_cond_executions (struct l
*** 2352,2365 ****
     from the EXIT_CONDITIONS array.  */
  
  static void 
! number_of_iterations_for_all_loops (VEC(tree,heap) **exit_conditions)
  {
    unsigned int i;
    unsigned nb_chrec_dont_know_loops = 0;
    unsigned nb_static_loops = 0;
!   tree cond;
    
!   for (i = 0; VEC_iterate (tree, *exit_conditions, i, cond); i++)
      {
        tree res = number_of_latch_executions (loop_containing_stmt (cond));
        if (chrec_contains_undetermined (res))
--- 2397,2410 ----
     from the EXIT_CONDITIONS array.  */
  
  static void 
! number_of_iterations_for_all_loops (VEC(gimple,heap) **exit_conditions)
  {
    unsigned int i;
    unsigned nb_chrec_dont_know_loops = 0;
    unsigned nb_static_loops = 0;
!   gimple cond;
    
!   for (i = 0; VEC_iterate (gimple, *exit_conditions, i, cond); i++)
      {
        tree res = number_of_latch_executions (loop_containing_stmt (cond));
        if (chrec_contains_undetermined (res))
*************** gather_chrec_stats (tree chrec, struct c
*** 2504,2536 ****
     index.  This allows the parallelization of the loop.  */
  
  static void 
! analyze_scalar_evolution_for_all_loop_phi_nodes (VEC(tree,heap) **exit_conditions)
  {
    unsigned int i;
    struct chrec_stats stats;
!   tree cond;
    
    reset_chrecs_counters (&stats);
    
!   for (i = 0; VEC_iterate (tree, *exit_conditions, i, cond); i++)
      {
        struct loop *loop;
        basic_block bb;
!       tree phi, chrec;
        
        loop = loop_containing_stmt (cond);
        bb = loop->header;
        
!       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
! 	if (is_gimple_reg (PHI_RESULT (phi)))
! 	  {
! 	    chrec = instantiate_parameters 
! 	      (loop, 
! 	       analyze_scalar_evolution (loop, PHI_RESULT (phi)));
  	    
! 	    if (dump_file && (dump_flags & TDF_STATS))
! 	      gather_chrec_stats (chrec, &stats);
! 	  }
      }
    
    if (dump_file && (dump_flags & TDF_STATS))
--- 2549,2585 ----
     index.  This allows the parallelization of the loop.  */
  
  static void 
! analyze_scalar_evolution_for_all_loop_phi_nodes (VEC(gimple,heap) **exit_conditions)
  {
    unsigned int i;
    struct chrec_stats stats;
!   gimple cond, phi;
!   gimple_stmt_iterator psi;
    
    reset_chrecs_counters (&stats);
    
!   for (i = 0; VEC_iterate (gimple, *exit_conditions, i, cond); i++)
      {
        struct loop *loop;
        basic_block bb;
!       tree chrec;
        
        loop = loop_containing_stmt (cond);
        bb = loop->header;
        
!       for (psi = gsi_start (phi_nodes (bb)); !gsi_end_p (psi); gsi_next (&psi))
! 	{
! 	  phi = gsi_stmt (psi);
! 	  if (is_gimple_reg (PHI_RESULT (phi)))
! 	    {
! 	      chrec = instantiate_parameters 
! 		        (loop, 
! 			 analyze_scalar_evolution (loop, PHI_RESULT (phi)));
  	    
! 	      if (dump_file && (dump_flags & TDF_STATS))
! 		gather_chrec_stats (chrec, &stats);
! 	    }
! 	}
      }
    
    if (dump_file && (dump_flags & TDF_STATS))
*************** scev_reset (void)
*** 2646,2652 ****
     overflow (e.g.  because it is computed in signed arithmetics).  */
  
  bool
! simple_iv (struct loop *loop, tree stmt, tree op, affine_iv *iv,
  	   bool allow_nonconstant_step)
  {
    basic_block bb = gimple_bb (stmt);
--- 2695,2701 ----
     overflow (e.g.  because it is computed in signed arithmetics).  */
  
  bool
! simple_iv (struct loop *loop, gimple stmt, tree op, affine_iv *iv,
  	   bool allow_nonconstant_step)
  {
    basic_block bb = gimple_bb (stmt);
*************** simple_iv (struct loop *loop, tree stmt,
*** 2705,2720 ****
  void
  scev_analysis (void)
  {
!   VEC(tree,heap) *exit_conditions;
    
!   exit_conditions = VEC_alloc (tree, heap, 37);
    select_loops_exit_conditions (&exit_conditions);
  
    if (dump_file && (dump_flags & TDF_STATS))
      analyze_scalar_evolution_for_all_loop_phi_nodes (&exit_conditions);
    
    number_of_iterations_for_all_loops (&exit_conditions);
!   VEC_free (tree, heap, exit_conditions);
  }
  
  /* Finalize the scalar evolution analysis.  */
--- 2754,2769 ----
  void
  scev_analysis (void)
  {
!   VEC(gimple,heap) *exit_conditions;
    
!   exit_conditions = VEC_alloc (gimple, heap, 37);
    select_loops_exit_conditions (&exit_conditions);
  
    if (dump_file && (dump_flags & TDF_STATS))
      analyze_scalar_evolution_for_all_loop_phi_nodes (&exit_conditions);
    
    number_of_iterations_for_all_loops (&exit_conditions);
!   VEC_free (gimple, heap, exit_conditions);
  }
  
  /* Finalize the scalar evolution analysis.  */
*************** scev_finalize (void)
*** 2739,2752 ****
  unsigned int
  scev_const_prop (void)
  {
-   /* FIXME tuples.  */
- #if 0
    basic_block bb;
!   tree name, phi, next_phi, type, ev;
    struct loop *loop, *ex_loop;
    bitmap ssa_names_to_remove = NULL;
    unsigned i;
    loop_iterator li;
  
    if (number_of_loops () <= 1)
      return 0;
--- 2788,2801 ----
  unsigned int
  scev_const_prop (void)
  {
    basic_block bb;
!   tree name, type, ev;
!   gimple phi, ass;
    struct loop *loop, *ex_loop;
    bitmap ssa_names_to_remove = NULL;
    unsigned i;
    loop_iterator li;
+   gimple_stmt_iterator psi;
  
    if (number_of_loops () <= 1)
      return 0;
*************** scev_const_prop (void)
*** 2755,2762 ****
      {
        loop = bb->loop_father;
  
!       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
  	{
  	  name = PHI_RESULT (phi);
  
  	  if (!is_gimple_reg (name))
--- 2804,2812 ----
      {
        loop = bb->loop_father;
  
!       for (psi = gsi_start (phi_nodes (bb)); !gsi_end_p (psi); gsi_next (&psi))
  	{
+ 	  phi = gsi_stmt (psi);
  	  name = PHI_RESULT (phi);
  
  	  if (!is_gimple_reg (name))
*************** scev_const_prop (void)
*** 2792,2802 ****
  
        EXECUTE_IF_SET_IN_BITMAP (ssa_names_to_remove, 0, i, bi)
  	{
  	  name = ssa_name (i);
  	  phi = SSA_NAME_DEF_STMT (name);
  
! 	  gcc_assert (TREE_CODE (phi) == PHI_NODE);
! 	  remove_phi_node (phi, NULL, true);
  	}
  
        BITMAP_FREE (ssa_names_to_remove);
--- 2842,2854 ----
  
        EXECUTE_IF_SET_IN_BITMAP (ssa_names_to_remove, 0, i, bi)
  	{
+ 	  gimple_stmt_iterator psi;
  	  name = ssa_name (i);
  	  phi = SSA_NAME_DEF_STMT (name);
  
! 	  gcc_assert (gimple_code (phi) == GIMPLE_PHI);
! 	  psi = gsi_for_stmt (phi);
! 	  remove_phi_node (&psi, true);
  	}
  
        BITMAP_FREE (ssa_names_to_remove);
*************** scev_const_prop (void)
*** 2807,2814 ****
    FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
      {
        edge exit;
!       tree def, rslt, ass, niter;
!       block_stmt_iterator bsi;
  
        /* If we do not know exact number of iterations of the loop, we cannot
  	 replace the final value.  */
--- 2859,2866 ----
    FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
      {
        edge exit;
!       tree def, rslt, niter;
!       gimple_stmt_iterator bsi;
  
        /* If we do not know exact number of iterations of the loop, we cannot
  	 replace the final value.  */
*************** scev_const_prop (void)
*** 2829,2850 ****
        /* Ensure that it is possible to insert new statements somewhere.  */
        if (!single_pred_p (exit->dest))
  	split_loop_exit_edge (exit);
!       bsi = bsi_after_labels (exit->dest);
  
        ex_loop = superloop_at_depth (loop,
  				    loop_depth (exit->dest->loop_father) + 1);
  
!       for (phi = phi_nodes (exit->dest); phi; phi = next_phi)
  	{
! 	  next_phi = PHI_CHAIN (phi);
  	  rslt = PHI_RESULT (phi);
  	  def = PHI_ARG_DEF_FROM_EDGE (phi, exit);
  	  if (!is_gimple_reg (def))
! 	    continue;
  
  	  if (!POINTER_TYPE_P (TREE_TYPE (def))
  	      && !INTEGRAL_TYPE_P (TREE_TYPE (def)))
! 	    continue;
  
  	  def = analyze_scalar_evolution_in_loop (ex_loop, loop, def, NULL);
  	  def = compute_overall_effect_of_inner_loop (ex_loop, def);
--- 2881,2908 ----
        /* Ensure that it is possible to insert new statements somewhere.  */
        if (!single_pred_p (exit->dest))
  	split_loop_exit_edge (exit);
!       bsi = gsi_after_labels (exit->dest);
  
        ex_loop = superloop_at_depth (loop,
  				    loop_depth (exit->dest->loop_father) + 1);
  
!       for (psi = gsi_start (phi_nodes (exit->dest)); !gsi_end_p (psi); )
  	{
! 	  phi = gsi_stmt (psi);
  	  rslt = PHI_RESULT (phi);
  	  def = PHI_ARG_DEF_FROM_EDGE (phi, exit);
  	  if (!is_gimple_reg (def))
! 	    {
! 	      gsi_next (&psi);
! 	      continue;
! 	    }
  
  	  if (!POINTER_TYPE_P (TREE_TYPE (def))
  	      && !INTEGRAL_TYPE_P (TREE_TYPE (def)))
! 	    {
! 	      gsi_next (&psi);
! 	      continue;
! 	    }
  
  	  def = analyze_scalar_evolution_in_loop (ex_loop, loop, def, NULL);
  	  def = compute_overall_effect_of_inner_loop (ex_loop, def);
*************** scev_const_prop (void)
*** 2854,2884 ****
  		 of some ssa names, which may cause problems if they appear
  		 on abnormal edges.  */
  	      || contains_abnormal_ssa_name_p (def))
! 	    continue;
  
  	  /* Eliminate the PHI node and replace it by a computation outside
  	     the loop.  */
  	  def = unshare_expr (def);
! 	  remove_phi_node (phi, NULL_TREE, false);
  
! 	  ass = build_gimple_modify_stmt (rslt, NULL_TREE);
  	  SSA_NAME_DEF_STMT (rslt) = ass;
! 	  {
! 	    block_stmt_iterator dest = bsi;
! 	    bsi_insert_before (&dest, ass, BSI_NEW_STMT);
! 	    def = force_gimple_operand_bsi (&dest, def, false, NULL_TREE,
! 					    true, BSI_SAME_STMT);
! 	  }
! 	  GIMPLE_STMT_OPERAND (ass, 1) = def;
! 	  update_stmt (ass);
  	}
      }
    return 0;
- #else
-   gimple_unreachable ();
-   return 0;
- #endif
  }
  
  #include "gt-tree-scalar-evolution.h"
- #endif
--- 2912,2935 ----
  		 of some ssa names, which may cause problems if they appear
  		 on abnormal edges.  */
  	      || contains_abnormal_ssa_name_p (def))
! 	    {
! 	      gsi_next (&psi);
! 	      continue;
! 	    }
  
  	  /* Eliminate the PHI node and replace it by a computation outside
  	     the loop.  */
  	  def = unshare_expr (def);
! 	  remove_phi_node (&psi, false);
  
! 	  def = force_gimple_operand_gsi (&bsi, def, false, NULL_TREE,
!       					  true, GSI_SAME_STMT);
! 	  ass = gimple_build_assign (rslt, def);
  	  SSA_NAME_DEF_STMT (rslt) = ass;
! 	  gsi_insert_before (&bsi, ass, GSI_SAME_STMT);
  	}
      }
    return 0;
  }
  
  #include "gt-tree-scalar-evolution.h"
Index: tree-scalar-evolution.h
===================================================================
*** tree-scalar-evolution.h	(revision 132890)
--- tree-scalar-evolution.h	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 23,29 ****
  
  extern tree number_of_latch_executions (struct loop *);
  extern tree number_of_exit_cond_executions (struct loop *);
! extern tree get_loop_exit_condition (const struct loop *);
  
  extern void scev_initialize (void);
  extern void scev_reset (void);
--- 23,29 ----
  
  extern tree number_of_latch_executions (struct loop *);
  extern tree number_of_exit_cond_executions (struct loop *);
! extern gimple get_loop_exit_condition (const struct loop *);
  
  extern void scev_initialize (void);
  extern void scev_reset (void);
*************** extern void gather_stats_on_scev_databas
*** 36,42 ****
  extern void scev_analysis (void);
  unsigned int scev_const_prop (void);
  
! extern bool simple_iv (struct loop *, tree, tree, affine_iv *, bool);
  
  /* Returns the loop of the polynomial chrec CHREC.  */
  
--- 36,42 ----
  extern void scev_analysis (void);
  unsigned int scev_const_prop (void);
  
! extern bool simple_iv (struct loop *, gimple, tree, affine_iv *, bool);
  
  /* Returns the loop of the polynomial chrec CHREC.  */
  
Index: tree-chrec.c
===================================================================
*** tree-chrec.c	(revision 132890)
--- tree-chrec.c	(working copy)
*************** chrec_fold_plus (tree type, 
*** 343,351 ****
      return chrec_fold_automatically_generated_operands (op0, op1);
  
    if (integer_zerop (op0))
!     return chrec_convert (type, op1, NULL_TREE);
    if (integer_zerop (op1))
!     return chrec_convert (type, op0, NULL_TREE);
  
    if (POINTER_TYPE_P (type))
      code = POINTER_PLUS_EXPR;
--- 343,351 ----
      return chrec_fold_automatically_generated_operands (op0, op1);
  
    if (integer_zerop (op0))
!     return chrec_convert (type, op1, NULL);
    if (integer_zerop (op1))
!     return chrec_convert (type, op0, NULL);
  
    if (POINTER_TYPE_P (type))
      code = POINTER_PLUS_EXPR;
*************** chrec_apply (unsigned var,
*** 577,583 ****
    if (evolution_function_is_affine_p (chrec))
      {
        /* "{a, +, b} (x)"  ->  "a + b*x".  */
!       x = chrec_convert_rhs (type, x, NULL_TREE);
        res = chrec_fold_multiply (TREE_TYPE (x), CHREC_RIGHT (chrec), x);
        if (!integer_zerop (CHREC_LEFT (chrec)))
  	res = chrec_fold_plus (type, CHREC_LEFT (chrec), res);
--- 577,583 ----
    if (evolution_function_is_affine_p (chrec))
      {
        /* "{a, +, b} (x)"  ->  "a + b*x".  */
!       x = chrec_convert_rhs (type, x, NULL);
        res = chrec_fold_multiply (TREE_TYPE (x), CHREC_RIGHT (chrec), x);
        if (!integer_zerop (CHREC_LEFT (chrec)))
  	res = chrec_fold_plus (type, CHREC_LEFT (chrec), res);
*************** avoid_arithmetics_in_type_p (const_tree 
*** 1114,1120 ****
    return false;
  }
  
! static tree chrec_convert_1 (tree, tree, tree, bool);
  
  /* Converts BASE and STEP of affine scev to TYPE.  LOOP is the loop whose iv
     the scev corresponds to.  AT_STMT is the statement at that the scev is
--- 1114,1120 ----
    return false;
  }
  
! static tree chrec_convert_1 (tree, tree, gimple, bool);
  
  /* Converts BASE and STEP of affine scev to TYPE.  LOOP is the loop whose iv
     the scev corresponds to.  AT_STMT is the statement at that the scev is
*************** static tree chrec_convert_1 (tree, tree,
*** 1126,1132 ****
  
  bool
  convert_affine_scev (struct loop *loop, tree type,
! 		     tree *base, tree *step, tree at_stmt,
  		     bool use_overflow_semantics)
  {
    tree ct = TREE_TYPE (*step);
--- 1126,1132 ----
  
  bool
  convert_affine_scev (struct loop *loop, tree type,
! 		     tree *base, tree *step, gimple at_stmt,
  		     bool use_overflow_semantics)
  {
    tree ct = TREE_TYPE (*step);
*************** convert_affine_scev (struct loop *loop, 
*** 1227,1233 ****
  /* Convert CHREC for the right hand side of a CREC.
     The increment for a pointer type is always sizetype.  */
  tree 
! chrec_convert_rhs (tree type, tree chrec, tree at_stmt)
  {
    if (POINTER_TYPE_P (type))
     type = sizetype;
--- 1227,1233 ----
  /* Convert CHREC for the right hand side of a CREC.
     The increment for a pointer type is always sizetype.  */
  tree 
! chrec_convert_rhs (tree type, tree chrec, gimple at_stmt)
  {
    if (POINTER_TYPE_P (type))
     type = sizetype;
*************** chrec_convert_rhs (tree type, tree chrec
*** 1259,1265 ****
  */
  
  tree 
! chrec_convert (tree type, tree chrec, tree at_stmt)
  {
    return chrec_convert_1 (type, chrec, at_stmt, true);
  }
--- 1259,1265 ----
  */
  
  tree 
! chrec_convert (tree type, tree chrec, gimple at_stmt)
  {
    return chrec_convert_1 (type, chrec, at_stmt, true);
  }
*************** chrec_convert (tree type, tree chrec, tr
*** 1277,1283 ****
     tests, but also to enforce that the result follows them.  */
  
  static tree 
! chrec_convert_1 (tree type, tree chrec, tree at_stmt,
  		 bool use_overflow_semantics)
  {
    tree ct, res;
--- 1277,1283 ----
     tests, but also to enforce that the result follows them.  */
  
  static tree 
! chrec_convert_1 (tree type, tree chrec, gimple at_stmt,
  		 bool use_overflow_semantics)
  {
    tree ct, res;
*************** chrec_convert_aggressive (tree type, tre
*** 1351,1360 ****
    right = CHREC_RIGHT (chrec);
    lc = chrec_convert_aggressive (type, left);
    if (!lc)
!     lc = chrec_convert (type, left, NULL_TREE);
    rc = chrec_convert_aggressive (rtype, right);
    if (!rc)
!     rc = chrec_convert (rtype, right, NULL_TREE);
   
    return build_polynomial_chrec (CHREC_VARIABLE (chrec), lc, rc);
  }
--- 1351,1360 ----
    right = CHREC_RIGHT (chrec);
    lc = chrec_convert_aggressive (type, left);
    if (!lc)
!     lc = chrec_convert (type, left, NULL);
    rc = chrec_convert_aggressive (rtype, right);
    if (!rc)
!     rc = chrec_convert (rtype, right, NULL);
   
    return build_polynomial_chrec (CHREC_VARIABLE (chrec), lc, rc);
  }
Index: tree-chrec.h
===================================================================
*** tree-chrec.h	(revision 132890)
--- tree-chrec.h	(working copy)
*************** tree_is_chrec (const_tree expr)
*** 57,64 ****
  extern tree chrec_fold_plus (tree, tree, tree);
  extern tree chrec_fold_minus (tree, tree, tree);
  extern tree chrec_fold_multiply (tree, tree, tree);
! extern tree chrec_convert (tree, tree, tree);
! extern tree chrec_convert_rhs (tree, tree, tree);
  extern tree chrec_convert_aggressive (tree, tree);
  
  /* Operations.  */
--- 57,64 ----
  extern tree chrec_fold_plus (tree, tree, tree);
  extern tree chrec_fold_minus (tree, tree, tree);
  extern tree chrec_fold_multiply (tree, tree, tree);
! extern tree chrec_convert (tree, tree, gimple);
! extern tree chrec_convert_rhs (tree, tree, gimple);
  extern tree chrec_convert_aggressive (tree, tree);
  
  /* Operations.  */
Index: tree-ssa-loop-ivopts.c
===================================================================
*** tree-ssa-loop-ivopts.c	(revision 132890)
--- tree-ssa-loop-ivopts.c	(working copy)
*************** stmt_after_increment (struct loop *loop,
*** 608,613 ****
--- 608,614 ----
        gcc_unreachable ();
      }
  }
+ #endif
  
  /* Returns true if EXP is a ssa name that occurs in an abnormal phi node.  */
  
*************** contains_abnormal_ssa_name_p (tree expr)
*** 689,694 ****
--- 690,697 ----
    return false;
  }
  
+ /* FIXME tuples.  */
+ #if 0
  /*  Returns tree describing number of iterations determined from
      EXIT of DATA->current_loop, or NULL if something goes wrong.  */
  
*************** find_interesting_uses_cond (struct ivopt
*** 1255,1260 ****
--- 1258,1265 ----
    record_use (data, cond_p, civ, stmt, USE_COMPARE);
  }
  
+ #endif
+ 
  /* Returns true if expression EXPR is obviously invariant in LOOP,
     i.e. if all its operands are defined outside of the LOOP.  */
  
*************** expr_invariant_in_loop_p (struct loop *l
*** 1277,1283 ****
        return true;
      }
  
!   if (!EXPR_P (expr) && !GIMPLE_STMT_P (expr))
      return false;
  
    len = TREE_OPERAND_LENGTH (expr);
--- 1282,1288 ----
        return true;
      }
  
!   if (!EXPR_P (expr))
      return false;
  
    len = TREE_OPERAND_LENGTH (expr);
*************** expr_invariant_in_loop_p (struct loop *l
*** 1288,1293 ****
--- 1293,1301 ----
    return true;
  }
  
+ /* FIXME tuples.  */
+ #if 0
+ 
  /* 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.  */
*************** var_at_stmt (struct loop *loop, struct i
*** 2551,2556 ****
--- 2559,2566 ----
      return cand->var_before;
  }
  
+ #endif
+ 
  /* Return the most significant (sign) bit of T.  Similar to tree_int_cst_msb,
     but the bit is determined from TYPE_PRECISION, not MODE_BITSIZE.  */
  
*************** tree_int_cst_sign_bit (const_tree t)
*** 2571,2576 ****
--- 2581,2588 ----
    return (w >> bitno) & 1;
  }
  
+ /* FIXME tuples.  */
+ #if 0
  /* If we can prove that TOP = cst * BOT for some constant cst,
     store cst to MUL and return true.  Otherwise return false.
     The returned value is always sign-extended, regardless of the
Index: gimple-dummy.c
===================================================================
*** gimple-dummy.c	(revision 132890)
--- gimple-dummy.c	(working copy)
***************
*** 14,40 ****
    void X (void);				\
    void X (void) { gcc_unreachable (); }
  
- DUMMY_VAR (chrec_dont_know);
- DUMMY_VAR (chrec_known);
- DUMMY_VAR (chrec_not_analyzed_yet);
  DUMMY_VAR (memory_identifier_string);
  
  
- DUMMY_FN (analyze_scalar_evolution)
  DUMMY_FN (canonicalize_induction_variables)
- DUMMY_FN (chrec_contains_symbols_defined_in_loop)
  DUMMY_FN (compute_builtin_object_size)
  DUMMY_FN (compute_data_dependences_for_loop)
  DUMMY_FN (dump_ddrs)
- DUMMY_FN (estimate_numbers_of_iterations)
- DUMMY_FN (expr_invariant_in_loop_p)
  DUMMY_FN (free_data_refs)
  DUMMY_FN (free_dependence_relations)
- DUMMY_FN (free_numbers_of_iterations_estimates)
- DUMMY_FN (free_numbers_of_iterations_estimates_loop)
- DUMMY_FN (get_loop_exit_condition)
  DUMMY_FN (get_type)
- DUMMY_FN (instantiate_parameters)
  DUMMY_FN (ipa_add_method)
  DUMMY_FN (ipa_callsite_callee)
  DUMMY_FN (ipa_callsite_compute_count)
--- 14,29 ----
*************** DUMMY_FN (ipa_nodes_free)
*** 62,78 ****
  DUMMY_FN (ipa_remove_method)
  DUMMY_FN (multiplier_allowed_in_address_p)
  DUMMY_FN (multiply_by_cost)
- DUMMY_FN (nowrap_type_p)
  DUMMY_FN (optimize_inline_calls)
  DUMMY_FN (remove_empty_loops)
- DUMMY_FN (scev_const_prop)
- DUMMY_FN (scev_finalize)
- DUMMY_FN (scev_initialize)
- DUMMY_FN (scev_probably_wraps_p)
- DUMMY_FN (scev_reset)
  DUMMY_FN (gimple_duplicate_loop_to_header_edge)
  DUMMY_FN (tree_function_versioning)
- DUMMY_FN (tree_int_cst_sign_bit)
  DUMMY_FN (tree_ssa_iv_optimize)
  DUMMY_FN (tree_ssa_prefetch_arrays)
  DUMMY_FN (tree_ssa_unswitch_loops)
--- 51,60 ----
*************** DUMMY_FN (tree_versionable_function_p)
*** 81,90 ****
  DUMMY_FN (vec_set_verbosity_level)
  DUMMY_FN (vect_set_verbosity_level)
  DUMMY_FN (vectorize_loops)
- DUMMY_FN (number_of_iterations_exit)
- DUMMY_FN (loop_niter_by_eval)
  DUMMY_FN (estimated_loop_iterations_int)
- DUMMY_FN (substitute_in_loop_info)
  DUMMY_FN (remove_iv)
  DUMMY_FN (omp_reduction_init)
  DUMMY_FN (diagnose_omp_structured_block_errors)
--- 63,69 ----
Index: tree-ssa-loop.c
===================================================================
*** tree-ssa-loop.c	(revision 132890)
--- tree-ssa-loop.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 37,52 ****
  #include "tree-inline.h"
  #include "tree-scalar-evolution.h"
  
- /* Initializes the loop structures.  */
- 
- static void
- tree_loop_optimizer_init (void)
- {
-   loop_optimizer_init (LOOPS_NORMAL
- 		       | LOOPS_HAVE_RECORDED_EXITS);
-   rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
- }
- 
  /* The loop superpass.  */
  
  static bool
--- 37,42 ----
*************** struct tree_opt_pass pass_tree_loop = 
*** 77,90 ****
  static unsigned int
  tree_ssa_loop_init (void)
  {
!   tree_loop_optimizer_init ();
    if (number_of_loops () <= 1)
      return 0;
  
- /* FIXME tuples.  */
- #if 0
    scev_initialize ();
- #endif
    return 0;
  }
    
--- 67,80 ----
  static unsigned int
  tree_ssa_loop_init (void)
  {
!   loop_optimizer_init (LOOPS_NORMAL
! 		       | LOOPS_HAVE_RECORDED_EXITS);
!   rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
! 
    if (number_of_loops () <= 1)
      return 0;
  
    scev_initialize ();
    return 0;
  }
    
*************** struct tree_opt_pass pass_iv_optimize =
*** 583,593 ****
  static unsigned int
  tree_ssa_loop_done (void)
  {
- /* FIXME tuples.  */
- #if 0
    free_numbers_of_iterations_estimates ();
    scev_finalize ();
- #endif
    loop_optimizer_finalize ();
    return 0;
  }
--- 573,580 ----
Index: gimple-iterator.c
===================================================================
*** gimple-iterator.c	(revision 132890)
--- gimple-iterator.c	(working copy)
*************** gsi_insert_seq_nodes_before (gimple_stmt
*** 76,83 ****
      }
    else
      {
!       gcc_assert (!gimple_seq_first (i->seq));
!       gimple_seq_set_first (i->seq, first);
        gimple_seq_set_last (i->seq, last);
      }
  
--- 76,93 ----
      }
    else
      {
!       gimple_seq_node itlast = gimple_seq_last (i->seq);
! 
!       /* If CUR is NULL, we link at the end of the sequence (this case happens
! 	 when gsi_after_labels is called for a basic block that contains only
! 	 labels, so it returns an iterator after the end of the block, and
! 	 we need to insert before it; it might be cleaner to add a flag to the
! 	 iterator saying whether we are at the start or end of the list).  */
!       first->prev = itlast;
!       if (itlast)
! 	itlast->next = first;
!       else
! 	gimple_seq_set_first (i->seq, first);
        gimple_seq_set_last (i->seq, last);
      }
  
*************** gimple_stmt_iterator
*** 418,425 ****
  gsi_for_stmt (gimple stmt)
  {
    gimple_stmt_iterator i;
  
!   for (i = gsi_start_bb (gimple_bb (stmt)); !gsi_end_p (i); gsi_next (&i))
      if (gsi_stmt (i) == stmt)
        return i;
  
--- 428,441 ----
  gsi_for_stmt (gimple stmt)
  {
    gimple_stmt_iterator i;
+   basic_block bb = gimple_bb (stmt);
+ 
+   if (gimple_code (stmt) == GIMPLE_PHI)
+     i = gsi_start (phi_nodes (bb));
+   else
+     i = gsi_start_bb (bb);
  
!   for (; !gsi_end_p (i); gsi_next (&i))
      if (gsi_stmt (i) == stmt)
        return i;
  
Index: cfgloop.h
===================================================================
*** cfgloop.h	(revision 132890)
--- cfgloop.h	(working copy)
*************** struct lpt_decision GTY (())
*** 49,55 ****
  struct nb_iter_bound GTY ((chain_next ("%h.next")))
  {
    /* The statement STMT is executed at most ...  */
!   tree stmt;
  
    /* ... BOUND + 1 times (BOUND must be an unsigned constant).
       The + 1 is added for the following reasons:
--- 49,55 ----
  struct nb_iter_bound GTY ((chain_next ("%h.next")))
  {
    /* The statement STMT is executed at most ...  */
!   gimple stmt;
  
    /* ... BOUND + 1 times (BOUND must be an unsigned constant).
       The + 1 is added for the following reasons:
Index: tree-flow.h
===================================================================
*** tree-flow.h	(revision 132890)
--- tree-flow.h	(working copy)
*************** tree find_loop_niter (struct loop *, edg
*** 978,985 ****
  tree loop_niter_by_eval (struct loop *, edge);
  tree find_loop_niter_by_eval (struct loop *, edge *);
  void estimate_numbers_of_iterations (void);
! bool scev_probably_wraps_p (tree, tree, tree, struct loop *, bool);
! bool convert_affine_scev (struct loop *, tree, tree *, tree *, tree, bool);
  
  bool nowrap_type_p (tree);
  enum ev_direction {EV_DIR_GROWS, EV_DIR_DECREASES, EV_DIR_UNKNOWN};
--- 978,985 ----
  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};
*************** void tree_transform_and_unroll_loop (str
*** 1015,1021 ****
  				     edge, struct tree_niter_desc *,
  				     transform_callback, void *);
  bool contains_abnormal_ssa_name_p (tree);
! bool stmt_dominates_stmt_p (tree, tree);
  void mark_virtual_ops_for_renaming (tree);
  
  /* In tree-ssa-threadedge.c */
--- 1015,1021 ----
  				     edge, struct tree_niter_desc *,
  				     transform_callback, void *);
  bool contains_abnormal_ssa_name_p (tree);
! bool stmt_dominates_stmt_p (gimple, gimple);
  void mark_virtual_ops_for_renaming (tree);
  
  /* In tree-ssa-threadedge.c */
Index: Makefile.in
===================================================================
*** Makefile.in	(revision 132890)
--- Makefile.in	(working copy)
*************** omega.o : omega.c omega.h $(CONFIG_H) $(
*** 2264,2275 ****
  tree-chrec.o: tree-chrec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(GGC_H) $(TREE_H) $(REAL_H) $(SCEV_H) tree-pass.h $(PARAMS_H) \
     $(DIAGNOSTIC_H) $(CFGLOOP_H) $(TREE_FLOW_H)
- # FIXME tuples.  Do not merge.
- #   gt-tree-scalar-evolution.h
  tree-scalar-evolution.o: tree-scalar-evolution.c $(CONFIG_H) $(SYSTEM_H) \
     coretypes.h $(TM_H) $(GGC_H) $(TREE_H) $(REAL_H) $(RTL_H) \
     $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) \
!    $(TIMEVAR_H) $(CFGLOOP_H) $(SCEV_H) tree-pass.h $(FLAGS_H) tree-chrec.h
  tree-data-ref.o: tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \
     $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
--- 2264,2274 ----
  tree-chrec.o: tree-chrec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(GGC_H) $(TREE_H) $(REAL_H) $(SCEV_H) tree-pass.h $(PARAMS_H) \
     $(DIAGNOSTIC_H) $(CFGLOOP_H) $(TREE_FLOW_H)
  tree-scalar-evolution.o: tree-scalar-evolution.c $(CONFIG_H) $(SYSTEM_H) \
     coretypes.h $(TM_H) $(GGC_H) $(TREE_H) $(REAL_H) $(RTL_H) \
     $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) \
!    $(TIMEVAR_H) $(CFGLOOP_H) $(SCEV_H) tree-pass.h $(FLAGS_H) tree-chrec.h \
!    gt-tree-scalar-evolution.h
  tree-data-ref.o: tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \
     $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
*************** s-constrs-h: $(MD_DEPS) build/genpreds$(
*** 3112,3118 ****
  	$(STAMP) s-constrs-h
  
  # FIXME tuples.  Do not merge.
- # $(srcdir)/tree-scalar-evolution.c 
  # $(srcdir)/ipa-reference.h 
  # $(srcdir)/omp-low.c 
  # $(srcdir)/ipa-reference.c
--- 3111,3116 ----
*************** GTFILES = $(srcdir)/input.h $(srcdir)/co
*** 3145,3150 ****
--- 3143,3149 ----
    $(srcdir)/tree-dfa.c \
    $(srcdir)/tree-iterator.c $(srcdir)/gimplify.c \
    $(srcdir)/tree-chrec.h \
+   $(srcdir)/tree-scalar-evolution.c \
    $(srcdir)/tree-ssa-operands.h \
    $(srcdir)/tree-profile.c $(srcdir)/tree-nested.c \
    $(srcdir)/varpool.c \
Index: gimple.c
===================================================================
*** gimple.c	(revision 132890)
--- gimple.c	(working copy)
*************** gimple_build_call (tree fn, size_t nargs
*** 280,286 ****
  /* Extract the operands and code for expression EXPR into *SUBCODE_P,
     *OP1_P and *OP2_P respectively.  */
  
! static void
  extract_ops_from_tree (tree expr, enum tree_code *subcode_p, tree *op1_p,
  		       tree *op2_p)
  {
--- 280,286 ----
  /* Extract the operands and code for expression EXPR into *SUBCODE_P,
     *OP1_P and *OP2_P respectively.  */
  
! void
  extract_ops_from_tree (tree expr, enum tree_code *subcode_p, tree *op1_p,
  		       tree *op2_p)
  {
*************** gimple_copy (gimple stmt)
*** 1737,1747 ****
        gimple_alloc_ops (copy, num_ops);
        for (i = 0; i < num_ops; i++)
  	gimple_set_op (copy, i, unshare_expr (gimple_op (stmt, i)));
  
        gimple_set_def_ops (copy, NULL);
        gimple_set_use_ops (copy, NULL);
!       update_stmt (copy);
      }
  
    return copy;
  }
--- 1737,1759 ----
        gimple_alloc_ops (copy, num_ops);
        for (i = 0; i < num_ops; i++)
  	gimple_set_op (copy, i, unshare_expr (gimple_op (stmt, i)));
+     }
  
+   if (gimple_has_ops (stmt))
+     {
        gimple_set_def_ops (copy, NULL);
        gimple_set_use_ops (copy, NULL);
!       copy->with_ops.addresses_taken = NULL;
!     }
! 
!   if (gimple_has_mem_ops (stmt))
!     {
!       gimple_set_vdef_ops (copy, NULL);
!       gimple_set_vuse_ops (copy, NULL);
!       stmt->with_mem_ops.stores = NULL;
!       stmt->with_mem_ops.loads = NULL;
      }
+   update_stmt (copy);
  
    return copy;
  }
Index: gimple.h
===================================================================
*** gimple.h	(revision 132890)
--- gimple.h	(working copy)
*************** union gimple_statement_d GTY ((desc ("gi
*** 513,518 ****
--- 513,519 ----
  /* In gimple.c.  */
  gimple gimple_build_return (tree);
  gimple gimple_build_assign (tree, tree);
+ void extract_ops_from_tree (tree, enum tree_code *, tree *, tree *);
  gimple gimple_build_assign_with_ops (enum tree_code, tree, tree, tree);
  gimple gimple_build_call_vec (tree, VEC(tree, gc) *);
  gimple gimple_build_call (tree, size_t, ...);
*************** static inline void
*** 1181,1187 ****
  gimple_call_set_lhs (gimple gs, tree lhs)
  {
    GIMPLE_CHECK (gs, GIMPLE_CALL);
!   gcc_assert (is_gimple_operand (lhs));
    gimple_set_op (gs, 0, lhs);
  }
  
--- 1182,1188 ----
  gimple_call_set_lhs (gimple gs, tree lhs)
  {
    GIMPLE_CHECK (gs, GIMPLE_CALL);
!   gcc_assert (!lhs || is_gimple_operand (lhs));
    gimple_set_op (gs, 0, lhs);
  }
  
Index: tree-cfg.c
===================================================================
*** tree-cfg.c	(revision 132890)
--- tree-cfg.c	(working copy)
*************** gimple_duplicate_bb (basic_block bb)
*** 4727,4742 ****
  /* Adds phi node arguments for edge E_COPY after basic block duplication.  */
  
  static void
! add_phi_args_after_copy_edge (edge e_copy ATTRIBUTE_UNUSED)
  {
- /* FIXME tuples.  */
- #if 0
    basic_block bb, bb_copy = e_copy->src, dest;
    edge e;
    edge_iterator ei;
!   tree phi, phi_copy, phi_next, def;
  
!   if (!phi_nodes (e_copy->dest))
      return;
  
    bb = bb_copy->flags & BB_DUPLICATED ? get_bb_original (bb_copy) : bb_copy;
--- 4727,4742 ----
  /* Adds phi node arguments for edge E_COPY after basic block duplication.  */
  
  static void
! add_phi_args_after_copy_edge (edge e_copy)
  {
    basic_block bb, bb_copy = e_copy->src, dest;
    edge e;
    edge_iterator ei;
!   gimple phi, phi_copy;
!   tree def;
!   gimple_stmt_iterator psi, psi_copy;
  
!   if (gimple_seq_empty_p (phi_nodes (e_copy->dest)))
      return;
  
    bb = bb_copy->flags & BB_DUPLICATED ? get_bb_original (bb_copy) : bb_copy;
*************** add_phi_args_after_copy_edge (edge e_cop
*** 4762,4778 ****
        gcc_assert (e != NULL);
      }
  
!   for (phi = phi_nodes (e->dest), phi_copy = phi_nodes (e_copy->dest);
!        phi;
!        phi = phi_next, phi_copy = PHI_CHAIN (phi_copy))
      {
!       phi_next = PHI_CHAIN (phi);
        def = PHI_ARG_DEF_FROM_EDGE (phi, e);
        add_phi_arg (phi_copy, def, e_copy);
      }
- #else
-   gimple_unreachable ();
- #endif
  }
  
  
--- 4762,4777 ----
        gcc_assert (e != NULL);
      }
  
!   for (psi = gsi_start (phi_nodes (e->dest)),
!        psi_copy = gsi_start (phi_nodes (e_copy->dest));
!        !gsi_end_p (psi);
!        gsi_next (&psi), gsi_next (&psi_copy))
      {
!       phi = gsi_stmt (psi);
!       phi_copy = gsi_stmt (psi_copy);
        def = PHI_ARG_DEF_FROM_EDGE (phi, e);
        add_phi_arg (phi_copy, def, e_copy);
      }
  }
  
  
*************** add_phi_args_after_copy_edge (edge e_cop
*** 4781,4800 ****
     duplicated have BB_DUPLICATED set.  */
  
  void
! add_phi_args_after_copy_bb (basic_block bb_copy ATTRIBUTE_UNUSED)
  {
-   /* FIXME tuples.  */
- #if 0
-   basic_block bb, dest;
-   edge e, e_copy;
-   edge_iterator ei;
    edge e_copy;
  
    FOR_EACH_EDGE (e_copy, ei, bb_copy->succs)
      {
        add_phi_args_after_copy_edge (e_copy);
      }
- #endif
  }
  
  /* Blocks in REGION_COPY array of length N_REGION were created by
--- 4780,4794 ----
     duplicated have BB_DUPLICATED set.  */
  
  void
! add_phi_args_after_copy_bb (basic_block bb_copy)
  {
    edge e_copy;
+   edge_iterator ei;
  
    FOR_EACH_EDGE (e_copy, ei, bb_copy->succs)
      {
        add_phi_args_after_copy_edge (e_copy);
      }
  }
  
  /* Blocks in REGION_COPY array of length N_REGION were created by
Index: passes.c
===================================================================
*** passes.c	(revision 132890)
--- passes.c	(working copy)
*************** init_optimization_passes (void)
*** 615,621 ****
--- 615,623 ----
        NEXT_PASS (pass_tree_ifcombine);
        NEXT_PASS (pass_phiopt);
        NEXT_PASS (pass_tail_recursion);
+ #endif
        NEXT_PASS (pass_ch);
+ #if 0
        NEXT_PASS (pass_stdarg);
  #endif
        NEXT_PASS (pass_lower_complex);
*************** init_optimization_passes (void)
*** 658,664 ****
--- 660,668 ----
  #if 0
  	  NEXT_PASS (pass_predcom);
  	  NEXT_PASS (pass_tree_unswitch);
+ #endif
  	  NEXT_PASS (pass_scev_cprop);
+ #if 0
  	  NEXT_PASS (pass_empty_loop);
  	  NEXT_PASS (pass_record_bounds);
  	  NEXT_PASS (pass_check_data_deps);


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