[tuples, commited] Convert ivopts

Zdenek Dvorak rakdver@kam.mff.cuni.cz
Sun Mar 16 21:18:00 GMT 2008


Hi,

this patch enables ivopts.

Zdenek

Index: ChangeLog.tuples
===================================================================
*** ChangeLog.tuples	(revision 133280)
--- ChangeLog.tuples	(working copy)
***************
*** 1,3 ****
--- 1,15 ----
+ 2008-03-16  Zdenek Dvorak  <ook@ucw.cz>
+ 
+ 	* tree-ssa-loop-ivopts.c: Tuplify.
+ 	* gimple-dummy.c (multiplier_allowed_in_address_p, multiply_by_cost,
+ 	tree_ssa_iv_optimize): Removed.
+ 	* tree-ssa-phiopt.c (empty_block_p): Tuplify.
+ 	* gimple.h (gimple_cond_lhs_ptr, gimple_cond_rhs_ptr): New.
+ 	* passes.c (init_optimization_passes): Enable pass_iv_optimize.
+ 
+ 	* gimplify.c (gimplify_omp_workshare, gimplify_expr): Avoid using
+ 	uninitialized sequence.
+ 
  2008-03-13  Bill Maddox  <maddox@google.com>
  
  	* tree.h (fold_call_stmt, gimple_fold_builtin_snprintf_chk):
Index: tree-ssa-loop-ivopts.c
===================================================================
*** tree-ssa-loop-ivopts.c	(revision 133280)
--- tree-ssa-loop-ivopts.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 92,99 ****
  #include "tree-affine.h"
  #include "target.h"
  
- /* FIXME tuples.  */
- #if 0
  /* The infinite cost.  */
  #define INFTY 10000000
  
--- 92,97 ----
*************** struct iv_use
*** 164,170 ****
    unsigned id;		/* The id of the use.  */
    enum use_type type;	/* Type of the use.  */
    struct iv *iv;	/* The induction variable it is based on.  */
!   tree stmt;		/* Statement in that it occurs.  */
    tree *op_p;		/* The place where it occurs.  */
    bitmap related_cands;	/* The set of "related" iv candidates, plus the common
  			   important ones.  */
--- 162,168 ----
    unsigned id;		/* The id of the use.  */
    enum use_type type;	/* Type of the use.  */
    struct iv *iv;	/* The induction variable it is based on.  */
!   gimple stmt;		/* Statement in that it occurs.  */
    tree *op_p;		/* The place where it occurs.  */
    bitmap related_cands;	/* The set of "related" iv candidates, plus the common
  			   important ones.  */
*************** struct iv_cand
*** 192,198 ****
    bool important;	/* Whether this is an "important" candidate, i.e. such
  			   that it should be considered by all uses.  */
    enum iv_position pos;	/* Where it is computed.  */
!   tree incremented_at;	/* For original biv, the statement where it is
  			   incremented.  */
    tree var_before;	/* The variable used for it before increment.  */
    tree var_after;	/* The variable used for it after increment.  */
--- 190,196 ----
    bool important;	/* Whether this is an "important" candidate, i.e. such
  			   that it should be considered by all uses.  */
    enum iv_position pos;	/* Where it is computed.  */
!   gimple incremented_at;/* For original biv, the statement where it is
  			   incremented.  */
    tree var_before;	/* The variable used for it before increment.  */
    tree var_after;	/* The variable used for it after increment.  */
*************** iv_cand (struct ivopts_data *data, unsig
*** 360,366 ****
  {
    return VEC_index (iv_cand_p, data->iv_candidates, i);
  }
- #endif
  
  /* The single loop exit if it dominates the latch, NULL otherwise.  */
  
--- 358,363 ----
*************** single_dom_exit (struct loop *loop)
*** 378,385 ****
    return exit;
  }
  
- /* FIXME tuples.  */
- #if 0
  /* Dumps information about the induction variable IV to FILE.  */
  
  extern void dump_iv (FILE *, struct iv *);
--- 375,380 ----
*************** dump_use (FILE *file, struct iv_use *use
*** 452,458 ****
      }
  
    fprintf (file, "  in statement ");
!   print_generic_expr (file, use->stmt, TDF_SLIM);
    fprintf (file, "\n");
  
    fprintf (file, "  at position ");
--- 447,453 ----
      }
  
    fprintf (file, "  in statement ");
!   print_gimple_stmt (file, use->stmt, 0, 0);
    fprintf (file, "\n");
  
    fprintf (file, "  at position ");
*************** name_info (struct ivopts_data *data, tre
*** 548,554 ****
     emitted in LOOP.  */
  
  static bool
! stmt_after_ip_normal_pos (struct loop *loop, tree stmt)
  {
    basic_block bb = ip_normal_pos (loop), sbb = gimple_bb (stmt);
  
--- 543,549 ----
     emitted in LOOP.  */
  
  static bool
! stmt_after_ip_normal_pos (struct loop *loop, gimple stmt)
  {
    basic_block bb = ip_normal_pos (loop), sbb = gimple_bb (stmt);
  
*************** stmt_after_ip_normal_pos (struct loop *l
*** 567,577 ****
     variable CAND is incremented.  */
  
  static bool
! stmt_after_ip_original_pos (struct iv_cand *cand, tree stmt)
  {
    basic_block cand_bb = gimple_bb (cand->incremented_at);
    basic_block stmt_bb = gimple_bb (stmt);
!   block_stmt_iterator bsi;
  
    if (!dominated_by_p (CDI_DOMINATORS, stmt_bb, cand_bb))
      return false;
--- 562,572 ----
     variable CAND is incremented.  */
  
  static bool
! stmt_after_ip_original_pos (struct iv_cand *cand, gimple stmt)
  {
    basic_block cand_bb = gimple_bb (cand->incremented_at);
    basic_block stmt_bb = gimple_bb (stmt);
!   gimple_stmt_iterator bsi;
  
    if (!dominated_by_p (CDI_DOMINATORS, stmt_bb, cand_bb))
      return false;
*************** stmt_after_ip_original_pos (struct iv_ca
*** 581,591 ****
  
    /* Scan the block from the end, since the original ivs are usually
       incremented at the end of the loop body.  */
!   for (bsi = bsi_last (stmt_bb); ; bsi_prev (&bsi))
      {
!       if (bsi_stmt (bsi) == cand->incremented_at)
  	return false;
!       if (bsi_stmt (bsi) == stmt)
  	return true;
      }
  }
--- 576,586 ----
  
    /* Scan the block from the end, since the original ivs are usually
       incremented at the end of the loop body.  */
!   for (bsi = gsi_last_bb (stmt_bb); ; gsi_prev (&bsi))
      {
!       if (gsi_stmt (bsi) == cand->incremented_at)
  	return false;
!       if (gsi_stmt (bsi) == stmt)
  	return true;
      }
  }
*************** stmt_after_ip_original_pos (struct iv_ca
*** 594,600 ****
     CAND is incremented in LOOP.  */
  
  static bool
! stmt_after_increment (struct loop *loop, struct iv_cand *cand, tree stmt)
  {
    switch (cand->pos)
      {
--- 589,595 ----
     CAND is incremented in LOOP.  */
  
  static bool
! stmt_after_increment (struct loop *loop, struct iv_cand *cand, gimple stmt)
  {
    switch (cand->pos)
      {
*************** stmt_after_increment (struct loop *loop,
*** 611,617 ****
        gcc_unreachable ();
      }
  }
- #endif
  
  /* Returns true if EXP is a ssa name that occurs in an abnormal phi node.  */
  
--- 606,611 ----
*************** contains_abnormal_ssa_name_p (tree expr)
*** 693,700 ****
    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.  */
  
--- 687,692 ----
*************** get_iv (struct ivopts_data *data, tree v
*** 880,886 ****
     not define a simple affine biv with nonzero step.  */
  
  static tree
! determine_biv_step (tree phi)
  {
    struct loop *loop = gimple_bb (phi)->loop_father;
    tree name = PHI_RESULT (phi);
--- 872,878 ----
     not define a simple affine biv with nonzero step.  */
  
  static tree
! determine_biv_step (gimple phi)
  {
    struct loop *loop = gimple_bb (phi)->loop_father;
    tree name = PHI_RESULT (phi);
*************** determine_biv_step (tree phi)
*** 900,911 ****
  static bool
  find_bivs (struct ivopts_data *data)
  {
!   tree phi, step, type, base;
    bool found = false;
    struct loop *loop = data->current_loop;
  
!   for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
      {
        if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)))
  	continue;
  
--- 892,909 ----
  static bool
  find_bivs (struct ivopts_data *data)
  {
!   gimple phi;
!   tree step, type, base;
    bool found = false;
    struct loop *loop = data->current_loop;
+   gimple_stmt_iterator psi;
  
!   for (psi = gsi_start (phi_nodes (loop->header)); 
!        !gsi_end_p (psi);
!        gsi_next (&psi))
      {
+       phi = gsi_stmt (psi);
+ 
        if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)))
  	continue;
  
*************** find_bivs (struct ivopts_data *data)
*** 936,948 ****
  static void
  mark_bivs (struct ivopts_data *data)
  {
!   tree phi, var;
    struct iv *iv, *incr_iv;
    struct loop *loop = data->current_loop;
    basic_block incr_bb;
  
!   for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
      {
        iv = get_iv (data, PHI_RESULT (phi));
        if (!iv)
  	continue;
--- 934,952 ----
  static void
  mark_bivs (struct ivopts_data *data)
  {
!   gimple phi;
!   tree var;
    struct iv *iv, *incr_iv;
    struct loop *loop = data->current_loop;
    basic_block incr_bb;
+   gimple_stmt_iterator psi;
  
!   for (psi = gsi_start (phi_nodes (loop->header)); 
!        !gsi_end_p (psi);
!        gsi_next (&psi))
      {
+       phi = gsi_stmt (psi);
+ 
        iv = get_iv (data, PHI_RESULT (phi));
        if (!iv)
  	continue;
*************** mark_bivs (struct ivopts_data *data)
*** 967,973 ****
     parameters to IV.  */
  
  static bool
! find_givs_in_stmt_scev (struct ivopts_data *data, tree stmt, affine_iv *iv)
  {
    tree lhs;
    struct loop *loop = data->current_loop;
--- 971,977 ----
     parameters to IV.  */
  
  static bool
! find_givs_in_stmt_scev (struct ivopts_data *data, gimple stmt, affine_iv *iv)
  {
    tree lhs;
    struct loop *loop = data->current_loop;
*************** find_givs_in_stmt_scev (struct ivopts_da
*** 975,988 ****
    iv->base = NULL_TREE;
    iv->step = NULL_TREE;
  
!   if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
      return false;
  
!   lhs = GIMPLE_STMT_OPERAND (stmt, 0);
    if (TREE_CODE (lhs) != SSA_NAME)
      return false;
  
!   if (!simple_iv (loop, stmt, GIMPLE_STMT_OPERAND (stmt, 1), iv, true))
      return false;
    iv->base = expand_simple_operations (iv->base);
  
--- 979,992 ----
    iv->base = NULL_TREE;
    iv->step = NULL_TREE;
  
!   if (gimple_code (stmt) != GIMPLE_ASSIGN)
      return false;
  
!   lhs = gimple_assign_lhs (stmt);
    if (TREE_CODE (lhs) != SSA_NAME)
      return false;
  
!   if (!simple_iv (loop, stmt, lhs, iv, true))
      return false;
    iv->base = expand_simple_operations (iv->base);
  
*************** find_givs_in_stmt_scev (struct ivopts_da
*** 996,1009 ****
  /* Finds general ivs in statement STMT.  */
  
  static void
! find_givs_in_stmt (struct ivopts_data *data, tree stmt)
  {
    affine_iv iv;
  
    if (!find_givs_in_stmt_scev (data, stmt, &iv))
      return;
  
!   set_iv (data, GIMPLE_STMT_OPERAND (stmt, 0), iv.base, iv.step);
  }
  
  /* Finds general ivs in basic block BB.  */
--- 1000,1013 ----
  /* Finds general ivs in statement STMT.  */
  
  static void
! find_givs_in_stmt (struct ivopts_data *data, gimple stmt)
  {
    affine_iv iv;
  
    if (!find_givs_in_stmt_scev (data, stmt, &iv))
      return;
  
!   set_iv (data, gimple_assign_lhs (stmt), iv.base, iv.step);
  }
  
  /* Finds general ivs in basic block BB.  */
*************** find_givs_in_stmt (struct ivopts_data *d
*** 1011,1020 ****
  static void
  find_givs_in_bb (struct ivopts_data *data, basic_block bb)
  {
!   block_stmt_iterator bsi;
  
!   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
!     find_givs_in_stmt (data, bsi_stmt (bsi));
  }
  
  /* Finds general ivs.  */
--- 1015,1024 ----
  static void
  find_givs_in_bb (struct ivopts_data *data, basic_block bb)
  {
!   gimple_stmt_iterator bsi;
  
!   for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
!     find_givs_in_stmt (data, gsi_stmt (bsi));
  }
  
  /* Finds general ivs.  */
*************** find_induction_variables (struct ivopts_
*** 1073,1079 ****
  
  static struct iv_use *
  record_use (struct ivopts_data *data, tree *use_p, struct iv *iv,
! 	    tree stmt, enum use_type use_type)
  {
    struct iv_use *use = XCNEW (struct iv_use);
  
--- 1077,1083 ----
  
  static struct iv_use *
  record_use (struct ivopts_data *data, tree *use_p, struct iv *iv,
! 	    gimple stmt, enum use_type use_type)
  {
    struct iv_use *use = XCNEW (struct iv_use);
  
*************** find_interesting_uses_op (struct ivopts_
*** 1130,1136 ****
  {
    struct iv *iv;
    struct iv *civ;
!   tree stmt;
    struct iv_use *use;
  
    if (TREE_CODE (op) != SSA_NAME)
--- 1134,1140 ----
  {
    struct iv *iv;
    struct iv *civ;
!   gimple stmt;
    struct iv_use *use;
  
    if (TREE_CODE (op) != SSA_NAME)
*************** find_interesting_uses_op (struct ivopts_
*** 1159,1166 ****
    *civ = *iv;
  
    stmt = SSA_NAME_DEF_STMT (op);
!   gcc_assert (TREE_CODE (stmt) == PHI_NODE
! 	      || TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
  
    use = record_use (data, NULL, civ, stmt, USE_NONLINEAR_EXPR);
    iv->use_id = use->id;
--- 1163,1170 ----
    *civ = *iv;
  
    stmt = SSA_NAME_DEF_STMT (op);
!   gcc_assert (gimple_code (stmt) == GIMPLE_PHI
! 	      || gimple_code (stmt) == GIMPLE_ASSIGN);
  
    use = record_use (data, NULL, civ, stmt, USE_NONLINEAR_EXPR);
    iv->use_id = use->id;
*************** find_interesting_uses_op (struct ivopts_
*** 1168,1214 ****
    return use;
  }
  
! /* Given a condition *COND_P, checks whether it is a compare of an induction
!    variable and an invariant.  If this is the case, CONTROL_VAR is set
!    to location of the iv, BOUND to the location of the invariant,
!    IV_VAR and IV_BOUND are set to the corresponding induction variable
!    descriptions, and true is returned.  If this is not the case,
!    CONTROL_VAR and BOUND are set to the arguments of the condition and
!    false is returned.  */
  
  static bool
! extract_cond_operands (struct ivopts_data *data, tree *cond_p,
  		       tree **control_var, tree **bound,
  		       struct iv **iv_var, struct iv **iv_bound)
  {
!   /* The nodes returned when COND has just one operand.  Note that you should
!      not modify anything in BOUND or IV_BOUND because of this.  */
    static struct iv const_iv;
    static tree zero;
-   tree cond = *cond_p;
    tree *op0 = &zero, *op1 = &zero, *tmp_op;
    struct iv *iv0 = &const_iv, *iv1 = &const_iv, *tmp_iv;
    bool ret = false;
  
!   zero = integer_zero_node;
!   const_iv.step = integer_zero_node;
! 
!   if (TREE_CODE (cond) == SSA_NAME)
      {
!       op0 = cond_p;
!       iv0 = get_iv (data, cond);
!       ret = (iv0 && !integer_zerop (iv0->step));
!       goto end;
      }
! 
!   if (!COMPARISON_CLASS_P (cond))
      {
!       op0 = cond_p;
!       goto end;
      }
  
!   op0 = &TREE_OPERAND (cond, 0);
!   op1 = &TREE_OPERAND (cond, 1);
    if (TREE_CODE (*op0) == SSA_NAME)
      iv0 = get_iv (data, *op0);
    if (TREE_CODE (*op1) == SSA_NAME)
--- 1172,1211 ----
    return use;
  }
  
! /* Given a condition in statement STMT, checks whether it is a compare
!    of an induction variable and an invariant.  If this is the case,
!    CONTROL_VAR is set to location of the iv, BOUND to the location of
!    the invariant, IV_VAR and IV_BOUND are set to the corresponding
!    induction variable descriptions, and true is returned.  If this is not
!    the case, CONTROL_VAR and BOUND are set to the arguments of the
!    condition and false is returned.  */
  
  static bool
! extract_cond_operands (struct ivopts_data *data, gimple stmt,
  		       tree **control_var, tree **bound,
  		       struct iv **iv_var, struct iv **iv_bound)
  {
!   /* The objects returned when COND has constant operands.  */
    static struct iv const_iv;
    static tree zero;
    tree *op0 = &zero, *op1 = &zero, *tmp_op;
    struct iv *iv0 = &const_iv, *iv1 = &const_iv, *tmp_iv;
    bool ret = false;
  
!   if (gimple_code (stmt) == GIMPLE_COND)
      {
!       op0 = gimple_cond_lhs_ptr (stmt);
!       op1 = gimple_cond_rhs_ptr (stmt);
      }
!   else
      {
!       op0 = gimple_assign_rhs1_ptr (stmt);
!       op1 = gimple_assign_rhs2_ptr (stmt);
      }
  
!   zero = integer_zero_node;
!   const_iv.step = integer_zero_node;
! 
    if (TREE_CODE (*op0) == SSA_NAME)
      iv0 = get_iv (data, *op0);
    if (TREE_CODE (*op1) == SSA_NAME)
*************** end:
*** 1240,1255 ****
    return ret;
  }
  
! /* Checks whether the condition *COND_P in STMT is interesting
!    and if so, records it.  */
  
  static void
! find_interesting_uses_cond (struct ivopts_data *data, tree stmt, tree *cond_p)
  {
    tree *var_p, *bound_p;
    struct iv *var_iv, *civ;
  
!   if (!extract_cond_operands (data, cond_p, &var_p, &bound_p, &var_iv, NULL))
      {
        find_interesting_uses_op (data, *var_p);
        find_interesting_uses_op (data, *bound_p);
--- 1237,1252 ----
    return ret;
  }
  
! /* Checks whether the condition in STMT is interesting and if so,
!    records it.  */
  
  static void
! find_interesting_uses_cond (struct ivopts_data *data, gimple stmt)
  {
    tree *var_p, *bound_p;
    struct iv *var_iv, *civ;
  
!   if (!extract_cond_operands (data, stmt, &var_p, &bound_p, &var_iv, NULL))
      {
        find_interesting_uses_op (data, *var_p);
        find_interesting_uses_op (data, *bound_p);
*************** find_interesting_uses_cond (struct ivopt
*** 1258,1268 ****
  
    civ = XNEW (struct iv);
    *civ = *var_iv;
!   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.  LOOP
     should not be the function body.  */
--- 1255,1263 ----
  
    civ = XNEW (struct iv);
    *civ = *var_iv;
!   record_use (data, NULL, civ, stmt, USE_COMPARE);
  }
  
  /* Returns true if expression EXPR is obviously invariant in LOOP,
     i.e. if all its operands are defined outside of the LOOP.  LOOP
     should not be the function body.  */
*************** expr_invariant_in_loop_p (struct loop *l
*** 1299,1307 ****
    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.  */
--- 1294,1299 ----
*************** expr_invariant_in_loop_p (struct loop *l
*** 1309,1315 ****
  struct ifs_ivopts_data
  {
    struct ivopts_data *ivopts_data;
!   tree stmt;
    tree step;
  };
  
--- 1301,1307 ----
  struct ifs_ivopts_data
  {
    struct ivopts_data *ivopts_data;
!   gimple stmt;
    tree step;
  };
  
*************** may_be_nonaddressable_p (tree expr)
*** 1563,1569 ****
  /* Finds addresses in *OP_P inside STMT.  */
  
  static void
! find_interesting_uses_address (struct ivopts_data *data, tree stmt, tree *op_p)
  {
    tree base = *op_p, step = build_int_cst (sizetype, 0);
    struct iv *civ;
--- 1555,1561 ----
  /* Finds addresses in *OP_P inside STMT.  */
  
  static void
! find_interesting_uses_address (struct ivopts_data *data, gimple stmt, tree *op_p)
  {
    tree base = *op_p, step = build_int_cst (sizetype, 0);
    struct iv *civ;
*************** find_interesting_uses_address (struct iv
*** 1571,1577 ****
  
    /* Do not play with volatile memory references.  A bit too conservative,
       perhaps, but safe.  */
!   if (stmt_ann (stmt)->has_volatile_ops)
      goto fail;
  
    /* Ignore bitfields for now.  Not really something terribly complicated
--- 1563,1569 ----
  
    /* Do not play with volatile memory references.  A bit too conservative,
       perhaps, but safe.  */
!   if (gimple_has_volatile_ops (stmt))
      goto fail;
  
    /* Ignore bitfields for now.  Not really something terribly complicated
*************** fail:
*** 1667,1673 ****
  /* Finds and records invariants used in STMT.  */
  
  static void
! find_invariants_stmt (struct ivopts_data *data, tree stmt)
  {
    ssa_op_iter iter;
    use_operand_p use_p;
--- 1659,1665 ----
  /* Finds and records invariants used in STMT.  */
  
  static void
! find_invariants_stmt (struct ivopts_data *data, gimple stmt)
  {
    ssa_op_iter iter;
    use_operand_p use_p;
*************** find_invariants_stmt (struct ivopts_data
*** 1683,1743 ****
  /* Finds interesting uses of induction variables in the statement STMT.  */
  
  static void
! find_interesting_uses_stmt (struct ivopts_data *data, tree stmt)
  {
    struct iv *iv;
!   tree op, lhs, rhs;
    ssa_op_iter iter;
    use_operand_p use_p;
  
    find_invariants_stmt (data, stmt);
  
!   if (TREE_CODE (stmt) == COND_EXPR)
      {
!       find_interesting_uses_cond (data, stmt, &COND_EXPR_COND (stmt));
        return;
      }
  
!   if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
      {
!       lhs = GIMPLE_STMT_OPERAND (stmt, 0);
!       rhs = GIMPLE_STMT_OPERAND (stmt, 1);
  
!       if (TREE_CODE (lhs) == SSA_NAME)
  	{
  	  /* If the statement defines an induction variable, the uses are not
  	     interesting by themselves.  */
  
! 	  iv = get_iv (data, lhs);
  
  	  if (iv && !integer_zerop (iv->step))
  	    return;
  	}
  
!       switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
  	{
! 	case tcc_comparison:
! 	  find_interesting_uses_cond (data, stmt,
! 	      			      &GIMPLE_STMT_OPERAND (stmt, 1));
! 	  return;
  
! 	case tcc_reference:
! 	  find_interesting_uses_address (data, stmt,
! 					 &GIMPLE_STMT_OPERAND (stmt, 1));
! 	  if (REFERENCE_CLASS_P (lhs))
! 	    find_interesting_uses_address (data, stmt,
! 					   &GIMPLE_STMT_OPERAND (stmt, 0));
  	  return;
- 
- 	default: ;
  	}
! 
!       if (REFERENCE_CLASS_P (lhs)
! 	  && is_gimple_val (rhs))
  	{
! 	  find_interesting_uses_address (data, stmt,
! 					 &GIMPLE_STMT_OPERAND (stmt, 0));
! 	  find_interesting_uses_op (data, rhs);
  	  return;
  	}
  
--- 1675,1729 ----
  /* Finds interesting uses of induction variables in the statement STMT.  */
  
  static void
! find_interesting_uses_stmt (struct ivopts_data *data, gimple stmt)
  {
    struct iv *iv;
!   tree op, *lhs, *rhs;
    ssa_op_iter iter;
    use_operand_p use_p;
+   enum tree_code code;
  
    find_invariants_stmt (data, stmt);
  
!   if (gimple_code (stmt) == GIMPLE_COND)
      {
!       find_interesting_uses_cond (data, stmt);
        return;
      }
  
!   if (gimple_code (stmt) == GIMPLE_ASSIGN)
      {
!       lhs = gimple_assign_lhs_ptr (stmt);
!       rhs = gimple_assign_rhs1_ptr (stmt);
  
!       if (TREE_CODE (*lhs) == SSA_NAME)
  	{
  	  /* If the statement defines an induction variable, the uses are not
  	     interesting by themselves.  */
  
! 	  iv = get_iv (data, *lhs);
  
  	  if (iv && !integer_zerop (iv->step))
  	    return;
  	}
  
!       code = gimple_assign_rhs_code (stmt);
!       if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS
! 	  && (REFERENCE_CLASS_P (*rhs)
! 	      || is_gimple_val (*rhs)))
  	{
! 	  if (REFERENCE_CLASS_P (*rhs))
! 	    find_interesting_uses_address (data, stmt, rhs);
! 	  else
! 	    find_interesting_uses_op (data, *rhs);
  
! 	  if (REFERENCE_CLASS_P (*lhs))
! 	    find_interesting_uses_address (data, stmt, lhs);
  	  return;
  	}
!       else if (TREE_CODE_CLASS (code) == tcc_comparison)
  	{
! 	  find_interesting_uses_cond (data, stmt);
  	  return;
  	}
  
*************** find_interesting_uses_stmt (struct ivopt
*** 1750,1760 ****
  	 call (memory).  */
      }
  
!   if (TREE_CODE (stmt) == PHI_NODE
        && gimple_bb (stmt) == data->current_loop->header)
      {
!       lhs = PHI_RESULT (stmt);
!       iv = get_iv (data, lhs);
  
        if (iv && !integer_zerop (iv->step))
  	return;
--- 1736,1745 ----
  	 call (memory).  */
      }
  
!   if (gimple_code (stmt) == GIMPLE_PHI
        && gimple_bb (stmt) == data->current_loop->header)
      {
!       iv = get_iv (data, PHI_RESULT (stmt));
  
        if (iv && !integer_zerop (iv->step))
  	return;
*************** find_interesting_uses_stmt (struct ivopt
*** 1781,1790 ****
  static void
  find_interesting_uses_outside (struct ivopts_data *data, edge exit)
  {
!   tree phi, def;
! 
!   for (phi = phi_nodes (exit->dest); phi; phi = PHI_CHAIN (phi))
      {
        def = PHI_ARG_DEF_FROM_EDGE (phi, exit);
        if (is_gimple_reg (def))
  	find_interesting_uses_op (data, def);
--- 1766,1780 ----
  static void
  find_interesting_uses_outside (struct ivopts_data *data, edge exit)
  {
!   gimple phi;
!   gimple_stmt_iterator psi;
!   tree def;
! 
!   for (psi = gsi_start (phi_nodes (exit->dest)); 
!        !gsi_end_p (psi);
!        gsi_next (&psi))
      {
+       phi = gsi_stmt (psi);
        def = PHI_ARG_DEF_FROM_EDGE (phi, exit);
        if (is_gimple_reg (def))
  	find_interesting_uses_op (data, def);
*************** static void
*** 1797,1804 ****
  find_interesting_uses (struct ivopts_data *data)
  {
    basic_block bb;
!   block_stmt_iterator bsi;
!   tree phi;
    basic_block *body = get_loop_body (data->current_loop);
    unsigned i;
    struct version_info *info;
--- 1787,1793 ----
  find_interesting_uses (struct ivopts_data *data)
  {
    basic_block bb;
!   gimple_stmt_iterator bsi;
    basic_block *body = get_loop_body (data->current_loop);
    unsigned i;
    struct version_info *info;
*************** find_interesting_uses (struct ivopts_dat
*** 1817,1826 ****
  	    && !flow_bb_inside_loop_p (data->current_loop, e->dest))
  	  find_interesting_uses_outside (data, e);
  
!       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
! 	find_interesting_uses_stmt (data, phi);
!       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
! 	find_interesting_uses_stmt (data, bsi_stmt (bsi));
      }
  
    if (dump_file && (dump_flags & TDF_DETAILS))
--- 1806,1815 ----
  	    && !flow_bb_inside_loop_p (data->current_loop, e->dest))
  	  find_interesting_uses_outside (data, e);
  
!       for (bsi = gsi_start (phi_nodes (bb)); !gsi_end_p (bsi); gsi_next (&bsi))
! 	find_interesting_uses_stmt (data, gsi_stmt (bsi));
!       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
! 	find_interesting_uses_stmt (data, gsi_stmt (bsi));
      }
  
    if (dump_file && (dump_flags & TDF_DETAILS))
*************** find_depends (tree *expr_p, int *ws ATTR
*** 2043,2049 ****
  static struct iv_cand *
  add_candidate_1 (struct ivopts_data *data,
  		 tree base, tree step, bool important, enum iv_position pos,
! 		 struct iv_use *use, tree incremented_at)
  {
    unsigned i;
    struct iv_cand *cand = NULL;
--- 2032,2038 ----
  static struct iv_cand *
  add_candidate_1 (struct ivopts_data *data,
  		 tree base, tree step, bool important, enum iv_position pos,
! 		 struct iv_use *use, gimple incremented_at)
  {
    unsigned i;
    struct iv_cand *cand = NULL;
*************** add_candidate (struct ivopts_data *data,
*** 2165,2174 ****
  	       tree base, tree step, bool important, struct iv_use *use)
  {
    if (ip_normal_pos (data->current_loop))
!     add_candidate_1 (data, base, step, important, IP_NORMAL, use, NULL_TREE);
    if (ip_end_pos (data->current_loop)
        && allow_ip_end_pos_p (data->current_loop))
!     add_candidate_1 (data, base, step, important, IP_END, use, NULL_TREE);
  }
  
  /* Add a standard "0 + 1 * iteration" iv candidate for a
--- 2154,2163 ----
  	       tree base, tree step, bool important, struct iv_use *use)
  {
    if (ip_normal_pos (data->current_loop))
!     add_candidate_1 (data, base, step, important, IP_NORMAL, use, NULL);
    if (ip_end_pos (data->current_loop)
        && allow_ip_end_pos_p (data->current_loop))
!     add_candidate_1 (data, base, step, important, IP_END, use, NULL);
  }
  
  /* Add a standard "0 + 1 * iteration" iv candidate for a
*************** add_standard_iv_candidates (struct ivopt
*** 2201,2207 ****
  static void
  add_old_iv_candidates (struct ivopts_data *data, struct iv *iv)
  {
!   tree phi, def;
    struct iv_cand *cand;
  
    add_candidate (data, iv->base, iv->step, true, NULL);
--- 2190,2197 ----
  static void
  add_old_iv_candidates (struct ivopts_data *data, struct iv *iv)
  {
!   gimple phi;
!   tree def;
    struct iv_cand *cand;
  
    add_candidate (data, iv->base, iv->step, true, NULL);
*************** add_old_iv_candidates (struct ivopts_dat
*** 2212,2218 ****
  		 iv->step, true, NULL);
  
    phi = SSA_NAME_DEF_STMT (iv->ssa_name);
!   if (TREE_CODE (phi) == PHI_NODE)
      {
        /* Additionally record the possibility of leaving the original iv
  	 untouched.  */
--- 2202,2208 ----
  		 iv->step, true, NULL);
  
    phi = SSA_NAME_DEF_STMT (iv->ssa_name);
!   if (gimple_code (phi) == GIMPLE_PHI)
      {
        /* Additionally record the possibility of leaving the original iv
  	 untouched.  */
*************** computation_cost (tree expr)
*** 2647,2653 ****
  /* Returns variable containing the value of candidate CAND at statement AT.  */
  
  static tree
! var_at_stmt (struct loop *loop, struct iv_cand *cand, tree stmt)
  {
    if (stmt_after_increment (loop, cand, stmt))
      return cand->var_after;
--- 2637,2643 ----
  /* Returns variable containing the value of candidate CAND at statement AT.  */
  
  static tree
! var_at_stmt (struct loop *loop, struct iv_cand *cand, gimple stmt)
  {
    if (stmt_after_increment (loop, cand, stmt))
      return cand->var_after;
*************** var_at_stmt (struct loop *loop, struct i
*** 2655,2662 ****
      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.  */
  
--- 2645,2650 ----
*************** tree_int_cst_sign_bit (const_tree t)
*** 2677,2684 ****
    return (w >> bitno) & 1;
  }
  
- /* FIXME tuples.  */
- #if 0
  /* If A is (TYPE) BA and B is (TYPE) BB, and the types of BA and BB have the
     same precision that is at least as wide as the precision of TYPE, stores
     BA to A and BB to B, and returns the type of BA.  Otherwise, returns the
--- 2665,2670 ----
*************** determine_common_wider_type (tree *a, tr
*** 2723,2729 ****
  
  static bool
  get_computation_aff (struct loop *loop,
! 		     struct iv_use *use, struct iv_cand *cand, tree at,
  		     struct affine_tree_combination *aff)
  {
    tree ubase = use->iv->base;
--- 2709,2715 ----
  
  static bool
  get_computation_aff (struct loop *loop,
! 		     struct iv_use *use, struct iv_cand *cand, gimple at,
  		     struct affine_tree_combination *aff)
  {
    tree ubase = use->iv->base;
*************** get_computation_aff (struct loop *loop,
*** 2798,2804 ****
  
  static tree
  get_computation_at (struct loop *loop,
! 		    struct iv_use *use, struct iv_cand *cand, tree at)
  {
    aff_tree aff;
    tree type = TREE_TYPE (use->iv->base);
--- 2784,2790 ----
  
  static tree
  get_computation_at (struct loop *loop,
! 		    struct iv_use *use, struct iv_cand *cand, gimple at)
  {
    aff_tree aff;
    tree type = TREE_TYPE (use->iv->base);
*************** difference_cost (struct ivopts_data *dat
*** 3468,3474 ****
  static comp_cost
  get_computation_cost_at (struct ivopts_data *data,
  			 struct iv_use *use, struct iv_cand *cand,
! 			 bool address_p, bitmap *depends_on, tree at)
  {
    tree ubase = use->iv->base, ustep = use->iv->step;
    tree cbase, cstep;
--- 3454,3460 ----
  static comp_cost
  get_computation_cost_at (struct ivopts_data *data,
  			 struct iv_use *use, struct iv_cand *cand,
! 			 bool address_p, bitmap *depends_on, gimple at)
  {
    tree ubase = use->iv->base, ustep = use->iv->step;
    tree cbase, cstep;
*************** determine_use_iv_cost_address (struct iv
*** 3682,3688 ****
     stores it to VAL.  */
  
  static void
! cand_value_at (struct loop *loop, struct iv_cand *cand, tree at, tree niter,
  	       aff_tree *val)
  {
    aff_tree step, delta, nit;
--- 3668,3674 ----
     stores it to VAL.  */
  
  static void
! cand_value_at (struct loop *loop, struct iv_cand *cand, gimple at, tree niter,
  	       aff_tree *val)
  {
    aff_tree step, delta, nit;
*************** may_eliminate_iv (struct ivopts_data *da
*** 3761,3769 ****
       for other conditions inside loop body.  */
    ex_bb = gimple_bb (use->stmt);
    if (use->stmt != last_stmt (ex_bb)
!       || TREE_CODE (use->stmt) != COND_EXPR)
!     return false;
!   if (!dominated_by_p (CDI_DOMINATORS, loop->latch, ex_bb))
      return false;
  
    exit = EDGE_SUCC (ex_bb, 0);
--- 3747,3754 ----
       for other conditions inside loop body.  */
    ex_bb = gimple_bb (use->stmt);
    if (use->stmt != last_stmt (ex_bb)
!       || gimple_code (use->stmt) != GIMPLE_COND
!       || !dominated_by_p (CDI_DOMINATORS, loop->latch, ex_bb))
      return false;
  
    exit = EDGE_SUCC (ex_bb, 0);
*************** determine_use_iv_cost_condition (struct 
*** 3828,3834 ****
  
    /* Try expressing the original giv.  If it is compared with an invariant,
       note that we cannot get rid of it.  */
!   ok = extract_cond_operands (data, use->op_p, NULL, NULL, NULL, &cmp_iv);
    gcc_assert (ok);
  
    express_cost = get_computation_cost (data, use, cand, false,
--- 3813,3819 ----
  
    /* Try expressing the original giv.  If it is compared with an invariant,
       note that we cannot get rid of it.  */
!   ok = extract_cond_operands (data, use->stmt, NULL, NULL, NULL, &cmp_iv);
    gcc_assert (ok);
  
    express_cost = get_computation_cost (data, use, cand, false,
*************** static void
*** 4044,4050 ****
  determine_set_costs (struct ivopts_data *data)
  {
    unsigned j, n;
!   tree phi, op;
    struct loop *loop = data->current_loop;
    bitmap_iterator bi;
  
--- 4029,4037 ----
  determine_set_costs (struct ivopts_data *data)
  {
    unsigned j, n;
!   gimple phi;
!   gimple_stmt_iterator psi;
!   tree op;
    struct loop *loop = data->current_loop;
    bitmap_iterator bi;
  
*************** determine_set_costs (struct ivopts_data 
*** 4077,4084 ****
      }
  
    n = 0;
!   for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
      {
        op = PHI_RESULT (phi);
  
        if (!is_gimple_reg (op))
--- 4064,4074 ----
      }
  
    n = 0;
!   for (psi = gsi_start (phi_nodes (loop->header));
!        !gsi_end_p (psi);
!        gsi_next (&psi))
      {
+       phi = gsi_stmt (psi);
        op = PHI_RESULT (phi);
  
        if (!is_gimple_reg (op))
*************** find_optimal_iv_set (struct ivopts_data 
*** 4919,4925 ****
  static void
  create_new_iv (struct ivopts_data *data, struct iv_cand *cand)
  {
!   block_stmt_iterator incr_pos;
    tree base;
    bool after = false;
  
--- 4909,4915 ----
  static void
  create_new_iv (struct ivopts_data *data, struct iv_cand *cand)
  {
!   gimple_stmt_iterator incr_pos;
    tree base;
    bool after = false;
  
*************** create_new_iv (struct ivopts_data *data,
*** 4929,4939 ****
    switch (cand->pos)
      {
      case IP_NORMAL:
!       incr_pos = bsi_last (ip_normal_pos (data->current_loop));
        break;
  
      case IP_END:
!       incr_pos = bsi_last (ip_end_pos (data->current_loop));
        after = true;
        break;
  
--- 4919,4929 ----
    switch (cand->pos)
      {
      case IP_NORMAL:
!       incr_pos = gsi_last_bb (ip_normal_pos (data->current_loop));
        break;
  
      case IP_END:
!       incr_pos = gsi_last_bb (ip_end_pos (data->current_loop));
        after = true;
        break;
  
*************** create_new_ivs (struct ivopts_data *data
*** 4978,4994 ****
     is true, remove also the ssa name defined by the statement.  */
  
  static void
! remove_statement (tree stmt, bool including_defined_name)
  {
!   if (TREE_CODE (stmt) == PHI_NODE)
!     {
!       remove_phi_node (stmt, NULL_TREE, including_defined_name);
!     }
    else
      {
!       block_stmt_iterator bsi = bsi_for_stmt (stmt);
! 
!       bsi_remove (&bsi, true);
        release_defs (stmt); 
      }
  }
--- 4968,4982 ----
     is true, remove also the ssa name defined by the statement.  */
  
  static void
! remove_statement (gimple stmt, bool including_defined_name)
  {
!   gimple_stmt_iterator bsi = gsi_for_stmt (stmt);
! 
!   if (gimple_code (stmt) == GIMPLE_PHI)
!     remove_phi_node (&bsi, including_defined_name);
    else
      {
!       gsi_remove (&bsi, true);
        release_defs (stmt); 
      }
  }
*************** rewrite_use_nonlinear_expr (struct ivopt
*** 5001,5008 ****
  			    struct iv_use *use, struct iv_cand *cand)
  {
    tree comp;
!   tree op, tgt, ass;
!   block_stmt_iterator bsi;
  
    /* An important special case -- if we are asked to express value of
       the original iv by itself, just exit; there is no need to
--- 4989,4997 ----
  			    struct iv_use *use, struct iv_cand *cand)
  {
    tree comp;
!   tree op, tgt;
!   gimple ass;
!   gimple_stmt_iterator bsi;
  
    /* An important special case -- if we are asked to express value of
       the original iv by itself, just exit; there is no need to
*************** rewrite_use_nonlinear_expr (struct ivopt
*** 5012,5021 ****
        && cand->incremented_at == use->stmt)
      {
        tree step, ctype, utype;
!       enum tree_code incr_code = PLUS_EXPR;
  
!       gcc_assert (TREE_CODE (use->stmt) == GIMPLE_MODIFY_STMT);
!       gcc_assert (GIMPLE_STMT_OPERAND (use->stmt, 0) == cand->var_after);
  
        step = cand->iv->step;
        ctype = TREE_TYPE (step);
--- 5001,5010 ----
        && cand->incremented_at == use->stmt)
      {
        tree step, ctype, utype;
!       enum tree_code incr_code = PLUS_EXPR, old_code;
  
!       gcc_assert (gimple_code (use->stmt) == GIMPLE_ASSIGN);
!       gcc_assert (gimple_assign_lhs (use->stmt) == cand->var_after);
  
        step = cand->iv->step;
        ctype = TREE_TYPE (step);
*************** rewrite_use_nonlinear_expr (struct ivopt
*** 5031,5046 ****
  	 computations in the loop -- otherwise, the computation
  	 we rely upon may be removed in remove_unused_ivs,
  	 thus leading to ICE.  */
!       op = GIMPLE_STMT_OPERAND (use->stmt, 1);
!       if (TREE_CODE (op) == PLUS_EXPR
! 	  || TREE_CODE (op) == MINUS_EXPR
! 	  || TREE_CODE (op) == POINTER_PLUS_EXPR)
! 	{
! 	  if (TREE_OPERAND (op, 0) == cand->var_before)
! 	    op = TREE_OPERAND (op, 1);
! 	  else if (TREE_CODE (op) != MINUS_EXPR
! 		   && TREE_OPERAND (op, 1) == cand->var_before)
! 	    op = TREE_OPERAND (op, 0);
  	  else
  	    op = NULL_TREE;
  	}
--- 5020,5035 ----
  	 computations in the loop -- otherwise, the computation
  	 we rely upon may be removed in remove_unused_ivs,
  	 thus leading to ICE.  */
!       old_code = gimple_assign_rhs_code (use->stmt);
!       if (old_code == PLUS_EXPR
! 	  || old_code == MINUS_EXPR
! 	  || old_code == POINTER_PLUS_EXPR)
! 	{
! 	  if (gimple_assign_rhs1 (use->stmt) == cand->var_before)
! 	    op = gimple_assign_rhs2 (use->stmt);
! 	  else if (old_code != MINUS_EXPR
! 		   && gimple_assign_rhs2 (use->stmt) == cand->var_before)
! 	    op = gimple_assign_rhs1 (use->stmt);
  	  else
  	    op = NULL_TREE;
  	}
*************** rewrite_use_nonlinear_expr (struct ivopt
*** 5065,5103 ****
        gcc_assert (comp != NULL_TREE);
      }
  
!   switch (TREE_CODE (use->stmt))
      {
!     case PHI_NODE:
        tgt = PHI_RESULT (use->stmt);
  
        /* If we should keep the biv, do not replace it.  */
        if (name_info (data, tgt)->preserve_biv)
  	return;
  
!       bsi = bsi_after_labels (gimple_bb (use->stmt));
        break;
  
!     case GIMPLE_MODIFY_STMT:
!       tgt = GIMPLE_STMT_OPERAND (use->stmt, 0);
!       bsi = bsi_for_stmt (use->stmt);
        break;
  
      default:
        gcc_unreachable ();
      }
  
!   op = force_gimple_operand_bsi (&bsi, comp, false, SSA_NAME_VAR (tgt),
! 				 true, BSI_SAME_STMT);
  
!   if (TREE_CODE (use->stmt) == PHI_NODE)
      {
!       ass = build_gimple_modify_stmt (tgt, op);
!       bsi_insert_before (&bsi, ass, BSI_SAME_STMT);
        remove_statement (use->stmt, false);
        SSA_NAME_DEF_STMT (tgt) = ass;
      }
    else
!     GIMPLE_STMT_OPERAND (use->stmt, 1) = op;
  }
  
  /* Replaces ssa name in index IDX by its basic variable.  Callback for
--- 5054,5092 ----
        gcc_assert (comp != NULL_TREE);
      }
  
!   switch (gimple_code (use->stmt))
      {
!     case GIMPLE_PHI:
        tgt = PHI_RESULT (use->stmt);
  
        /* If we should keep the biv, do not replace it.  */
        if (name_info (data, tgt)->preserve_biv)
  	return;
  
!       bsi = gsi_after_labels (gimple_bb (use->stmt));
        break;
  
!     case GIMPLE_ASSIGN:
!       tgt = gimple_assign_lhs (use->stmt);
!       bsi = gsi_for_stmt (use->stmt);
        break;
  
      default:
        gcc_unreachable ();
      }
  
!   op = force_gimple_operand_gsi (&bsi, comp, false, SSA_NAME_VAR (tgt),
! 				 true, GSI_SAME_STMT);
  
!   if (gimple_code (use->stmt) == GIMPLE_PHI)
      {
!       ass = gimple_build_assign (tgt, op);
!       gsi_insert_before (&bsi, ass, GSI_SAME_STMT);
        remove_statement (use->stmt, false);
        SSA_NAME_DEF_STMT (tgt) = ass;
      }
    else
!     gimple_assign_set_rhs_from_tree (use->stmt, op);
  }
  
  /* Replaces ssa name in index IDX by its basic variable.  Callback for
*************** rewrite_use_address (struct ivopts_data 
*** 5219,5225 ****
  		     struct iv_use *use, struct iv_cand *cand)
  {
    aff_tree aff;
!   block_stmt_iterator bsi = bsi_for_stmt (use->stmt);
    tree ref;
    bool ok;
  
--- 5208,5214 ----
  		     struct iv_use *use, struct iv_cand *cand)
  {
    aff_tree aff;
!   gimple_stmt_iterator bsi = gsi_for_stmt (use->stmt);
    tree ref;
    bool ok;
  
*************** rewrite_use_compare (struct ivopts_data 
*** 5240,5246 ****
  		     struct iv_use *use, struct iv_cand *cand)
  {
    tree comp, *var_p, op, bound;
!   block_stmt_iterator bsi = bsi_for_stmt (use->stmt);
    enum tree_code compare;
    struct cost_pair *cp = get_use_iv_cost (data, use, cand);
    bool ok;
--- 5229,5235 ----
  		     struct iv_use *use, struct iv_cand *cand)
  {
    tree comp, *var_p, op, bound;
!   gimple_stmt_iterator bsi = gsi_for_stmt (use->stmt);
    enum tree_code compare;
    struct cost_pair *cp = get_use_iv_cost (data, use, cand);
    bool ok;
*************** rewrite_use_compare (struct ivopts_data 
*** 5253,5262 ****
  
        compare = iv_elimination_compare (data, use);
        bound = unshare_expr (fold_convert (var_type, bound));
!       op = force_gimple_operand_bsi (&bsi, bound, true, NULL_TREE,
! 				     true, BSI_SAME_STMT);
  
!       *use->op_p = build2 (compare, boolean_type_node, var, op);
        return;
      }
  
--- 5242,5253 ----
  
        compare = iv_elimination_compare (data, use);
        bound = unshare_expr (fold_convert (var_type, bound));
!       op = force_gimple_operand_gsi (&bsi, bound, true, NULL_TREE,
! 				     true, GSI_SAME_STMT);
  
!       gimple_cond_set_lhs (use->stmt, var);
!       gimple_cond_set_code (use->stmt, compare);
!       gimple_cond_set_rhs (use->stmt, op);
        return;
      }
  
*************** rewrite_use_compare (struct ivopts_data 
*** 5265,5275 ****
    comp = get_computation (data->current_loop, use, cand);
    gcc_assert (comp != NULL_TREE);
  
!   ok = extract_cond_operands (data, use->op_p, &var_p, NULL, NULL, NULL);
    gcc_assert (ok);
  
!   *var_p = force_gimple_operand_bsi (&bsi, comp, true, SSA_NAME_VAR (*var_p),
! 				     true, BSI_SAME_STMT);
  }
  
  /* Rewrites USE using candidate CAND.  */
--- 5256,5266 ----
    comp = get_computation (data->current_loop, use, cand);
    gcc_assert (comp != NULL_TREE);
  
!   ok = extract_cond_operands (data, use->stmt, &var_p, NULL, NULL, NULL);
    gcc_assert (ok);
  
!   *var_p = force_gimple_operand_gsi (&bsi, comp, true, SSA_NAME_VAR (*var_p),
! 				     true, GSI_SAME_STMT);
  }
  
  /* Rewrites USE using candidate CAND.  */
*************** tree_ssa_iv_optimize_loop (struct ivopts
*** 5449,5455 ****
  	{
  	  fprintf (dump_file, "  single exit %d -> %d, exit condition ",
  		   exit->src->index, exit->dest->index);
! 	  print_generic_expr (dump_file, last_stmt (exit->src), TDF_SLIM);
  	  fprintf (dump_file, "\n");
  	}
  
--- 5440,5446 ----
  	{
  	  fprintf (dump_file, "  single exit %d -> %d, exit condition ",
  		   exit->src->index, exit->dest->index);
! 	  print_gimple_stmt (dump_file, last_stmt (exit->src), 0, TDF_SLIM);
  	  fprintf (dump_file, "\n");
  	}
  
*************** tree_ssa_iv_optimize (void)
*** 5523,5526 ****
  
    tree_ssa_iv_optimize_finalize (&data);
  }
- #endif
--- 5514,5516 ----
Index: gimple-dummy.c
===================================================================
*** gimple-dummy.c	(revision 133280)
--- gimple-dummy.c	(working copy)
*************** DUMMY_FN (ipa_node_create)
*** 45,56 ****
  DUMMY_FN (ipa_nodes_create)
  DUMMY_FN (ipa_nodes_free)
  DUMMY_FN (ipa_remove_method)
- DUMMY_FN (multiplier_allowed_in_address_p)
- DUMMY_FN (multiply_by_cost)
  DUMMY_FN (optimize_inline_calls)
  DUMMY_FN (remove_empty_loops)
  DUMMY_FN (tree_function_versioning)
- DUMMY_FN (tree_ssa_iv_optimize)
  DUMMY_FN (tree_ssa_unswitch_loops)
  DUMMY_FN (tree_unroll_loops_completely)
  DUMMY_FN (tree_versionable_function_p)
--- 45,53 ----
Index: gimplify.c
===================================================================
*** gimplify.c	(revision 133280)
--- gimplify.c	(working copy)
*************** static void
*** 5542,5548 ****
  gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
  {
    tree stmt = *expr_p;
!   gimple_seq body;
  
    gimplify_scan_omp_clauses (&OMP_CLAUSES (stmt), pre_p, false, false);
  
--- 5542,5548 ----
  gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
  {
    tree stmt = *expr_p;
!   gimple_seq body = NULL;
  
    gimplify_scan_omp_clauses (&OMP_CLAUSES (stmt), pre_p, false, false);
  
*************** gimplify_expr (tree *expr_p, gimple_seq 
*** 6246,6252 ****
  	case OMP_ORDERED:
  	case OMP_CRITICAL:
  	  {
! 	    gimple_seq body;
  	    gimple g;
  
  	    gimplify_and_add (OMP_BODY (*expr_p), &body);
--- 6246,6252 ----
  	case OMP_ORDERED:
  	case OMP_CRITICAL:
  	  {
! 	    gimple_seq body = NULL;
  	    gimple g;
  
  	    gimplify_and_add (OMP_BODY (*expr_p), &body);
Index: tree-ssa-phiopt.c
===================================================================
*** tree-ssa-phiopt.c	(revision 133280)
--- tree-ssa-phiopt.c	(working copy)
*************** blocks_in_phiopt_order (void)
*** 392,397 ****
--- 392,398 ----
  #undef VISITED_P
  }
  
+ #endif
  
  /* Return TRUE if block BB has no executable statements, otherwise return
     FALSE.  */
*************** blocks_in_phiopt_order (void)
*** 399,419 ****
  bool
  empty_block_p (basic_block bb)
  {
-   block_stmt_iterator bsi;
- 
    /* BB must have no executable statements.  */
!   bsi = bsi_start (bb);
!   while (!bsi_end_p (bsi)
! 	  && (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR
! 	      || gimple_nop_p (bsi_stmt (bsi))))
!     bsi_next (&bsi);
! 
!   if (!bsi_end_p (bsi))
!     return false;
! 
!   return true;
  }
  
  /* Replace PHI node element whose edge is E in block BB with variable NEW.
     Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
     is known to have two edges, one of which must reach BB).  */
--- 400,411 ----
  bool
  empty_block_p (basic_block bb)
  {
    /* BB must have no executable statements.  */
!   return gsi_end_p (gsi_after_labels (bb));
  }
  
+ /* FIXME tuples.  */
+ #if 0
  /* Replace PHI node element whose edge is E in block BB with variable NEW.
     Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
     is known to have two edges, one of which must reach BB).  */
Index: gimple.h
===================================================================
*** gimple.h	(revision 133280)
--- gimple.h	(working copy)
*************** gimple_cond_lhs (const_gimple gs)
*** 1418,1423 ****
--- 1418,1432 ----
    return gimple_op (gs, 0);
  }
  
+ /* Return the pointer to the LHS of the predicate computed by conditional
+    statement GS.  */
+ 
+ static inline tree *
+ gimple_cond_lhs_ptr (const_gimple gs)
+ {
+   GIMPLE_CHECK (gs, GIMPLE_COND);
+   return gimple_op_ptr (gs, 0);
+ }
  
  /* Set LHS to be the LHS operand of the predicate computed by
     conditional statement GS.  */
*************** gimple_cond_rhs (const_gimple gs)
*** 1440,1445 ****
--- 1449,1464 ----
    return gimple_op (gs, 1);
  }
  
+ /* Return the pointer to the RHS operand of the predicate computed by
+    conditional GS.  */
+ 
+ static inline tree *
+ gimple_cond_rhs_ptr (const_gimple gs)
+ {
+   GIMPLE_CHECK (gs, GIMPLE_COND);
+   return gimple_op_ptr (gs, 1);
+ }
+ 
  
  /* Set RHS to be the RHS operand of the predicate computed by
     conditional statement GS.  */
Index: passes.c
===================================================================
*** passes.c	(revision 133280)
--- passes.c	(working copy)
*************** init_optimization_passes (void)
*** 695,703 ****
  	  NEXT_PASS (pass_parallelize_loops);
  #endif
  	  NEXT_PASS (pass_loop_prefetch);
- #if 0
  	  NEXT_PASS (pass_iv_optimize);
- #endif
  	  NEXT_PASS (pass_tree_loop_done);
  	}
  #if 0
--- 695,701 ----



More information about the Gcc-patches mailing list