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] Tuplify predictive commoning


Hi,

this patch tuplifies predictive commoning (and fixes a few bugs in data
dependence analysis that this change exposed).  Commited,

Zdenek

Index: ChangeLog.tuples
===================================================================
*** ChangeLog.tuples	(revision 134500)
--- ChangeLog.tuples	(working copy)
***************
*** 1,3 ****
--- 1,12 ----
+ 2008-04-20  Zdenek Dvorak  <ook@ucw.cz>
+ 
+ 	* tree-data-ref.c (split_constant_offset_1): Use POINTER_PLUS_EXPR
+ 	for pointer addition.
+ 	(split_constant_offset): Set VAR to EXP before conversions are
+ 	stripped, when no offset is removed.  Handle chrec_dont_know.
+ 	* tree-predcom.c: Tuplified.
+ 	* passes.c (init_optimization_passes): Enable pass_predcom.
+ 
  2008-04-18  Aldy Hernandez  <aldyh@redhat.com>
  
  	* omp-low.c (lower_rec_input_clauses): Remove fixme and
Index: tree-data-ref.c
===================================================================
*** tree-data-ref.c	(revision 134500)
--- tree-data-ref.c	(working copy)
*************** split_constant_offset_1 (tree type, tree
*** 512,517 ****
--- 512,518 ----
  {
    tree var0, var1;
    tree off0, off1;
+   enum tree_code ocode = code;
  
    *var = NULL_TREE;
    *off = NULL_TREE;
*************** split_constant_offset_1 (tree type, tree
*** 524,537 ****
        return true;
  
      case POINTER_PLUS_EXPR:
!       code = PLUS_EXPR;
        /* FALLTHROUGH */
      case PLUS_EXPR:
      case MINUS_EXPR:
        split_constant_offset (op0, &var0, &off0);
        split_constant_offset (op1, &var1, &off1);
        *var = fold_build2 (code, type, var0, var1);
!       *off = size_binop (code, off0, off1);
        return true;
  
      case MULT_EXPR:
--- 525,538 ----
        return true;
  
      case POINTER_PLUS_EXPR:
!       ocode = PLUS_EXPR;
        /* FALLTHROUGH */
      case PLUS_EXPR:
      case MINUS_EXPR:
        split_constant_offset (op0, &var0, &off0);
        split_constant_offset (op1, &var1, &off1);
        *var = fold_build2 (code, type, var0, var1);
!       *off = size_binop (ocode, off0, off1);
        return true;
  
      case MULT_EXPR:
*************** split_constant_offset_1 (tree type, tree
*** 624,642 ****
  void
  split_constant_offset (tree exp, tree *var, tree *off)
  {
!   tree type = TREE_TYPE (exp), otype, op0, op1;
    enum tree_code code;
  
    STRIP_NOPS (exp);
    otype = TREE_TYPE (exp);
    code = TREE_CODE (exp);
    extract_ops_from_tree (exp, &code, &op0, &op1);
!   if (split_constant_offset_1 (otype, op0, code, op1, var, off))
!     *var = fold_convert (type, *var);
!   else
      {
!       *var = exp;
!       *off = ssize_int (0);
      }
  }
  
--- 625,647 ----
  void
  split_constant_offset (tree exp, tree *var, tree *off)
  {
!   tree type = TREE_TYPE (exp), otype, op0, op1, e, o;
    enum tree_code code;
  
+   *var = exp;
+   *off = ssize_int (0);
    STRIP_NOPS (exp);
+ 
+   if (automatically_generated_chrec_p (exp))
+     return;
+ 
    otype = TREE_TYPE (exp);
    code = TREE_CODE (exp);
    extract_ops_from_tree (exp, &code, &op0, &op1);
!   if (split_constant_offset_1 (otype, op0, code, op1, &e, &o))
      {
!       *var = fold_convert (type, e);
!       *off = o;
      }
  }
  
Index: tree-predcom.c
===================================================================
*** tree-predcom.c	(revision 134500)
--- tree-predcom.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 202,215 ****
  #include "tree-affine.h"
  #include "tree-inline.h"
  
-    /* FIXME tuples.  */
- #if 0
  /* The maximum number of iterations between the considered memory
     references.  */
  
  #define MAX_DISTANCE (target_avail_regs < 16 ? 4 : 8)
     
! /* Data references.  */
  
  typedef struct dref
  {
--- 202,214 ----
  #include "tree-affine.h"
  #include "tree-inline.h"
  
  /* The maximum number of iterations between the considered memory
     references.  */
  
  #define MAX_DISTANCE (target_avail_regs < 16 ? 4 : 8)
     
! /* Data references (or phi nodes that carry data reference values across
!    loop iterations).  */
  
  typedef struct dref
  {
*************** typedef struct dref
*** 217,223 ****
    struct data_reference *ref;
  
    /* The statement in that the reference appears.  */
!   tree stmt;
  
    /* Distance of the reference from the root of the chain (in number of
       iterations of the loop).  */
--- 216,227 ----
    struct data_reference *ref;
  
    /* The statement in that the reference appears.  */
!   gimple stmt;
! 
!   /* In case that STMT is a phi node, this field is set to the SSA name
!      defined by it in replace_phis_by_defined_names (in order to avoid
!      pointing to phi node that got reallocated in the meantime).  */
!   tree name_defined_by_phi;
  
    /* Distance of the reference from the root of the chain (in number of
       iterations of the loop).  */
*************** dump_dref (FILE *file, dref ref)
*** 356,362 ****
        else
  	fprintf (file, "    combination ref\n");
        fprintf (file, "      in statement ");
!       print_generic_expr (file, ref->stmt, TDF_SLIM);
        fprintf (file, "\n");
        fprintf (file, "      distance %u\n", ref->distance);
      }
--- 360,366 ----
        else
  	fprintf (file, "    combination ref\n");
        fprintf (file, "      in statement ");
!       print_gimple_stmt (file, ref->stmt, 0, TDF_SLIM);
        fprintf (file, "\n");
        fprintf (file, "      distance %u\n", ref->distance);
      }
*************** name_for_ref (dref ref)
*** 990,1001 ****
  {
    tree name;
  
!   if (TREE_CODE (ref->stmt) == GIMPLE_MODIFY_STMT)
      {
        if (!ref->ref || DR_IS_READ (ref->ref))
! 	name = GIMPLE_STMT_OPERAND (ref->stmt, 0);
        else
! 	name = GIMPLE_STMT_OPERAND (ref->stmt, 1);
      }
    else
      name = PHI_RESULT (ref->stmt);
--- 994,1005 ----
  {
    tree name;
  
!   if (gimple_code (ref->stmt) == GIMPLE_ASSIGN)
      {
        if (!ref->ref || DR_IS_READ (ref->ref))
! 	name = gimple_assign_lhs (ref->stmt);
        else
! 	name = gimple_assign_rhs1 (ref->stmt);
      }
    else
      name = PHI_RESULT (ref->stmt);
*************** valid_initializer_p (struct data_referen
*** 1053,1096 ****
     iteration), returns the phi node.  Otherwise, NULL_TREE is returned.  ROOT
     is the root of the current chain.  */
  
! static tree
  find_looparound_phi (struct loop *loop, dref ref, dref root)
  {
!   tree name, phi, init, init_stmt, init_ref;
    edge latch = loop_latch_edge (loop);
    struct data_reference init_dr;
  
!   if (TREE_CODE (ref->stmt) == GIMPLE_MODIFY_STMT)
      {
        if (DR_IS_READ (ref->ref))
! 	name = GIMPLE_STMT_OPERAND (ref->stmt, 0);
        else
! 	name = GIMPLE_STMT_OPERAND (ref->stmt, 1);
      }
    else
      name = PHI_RESULT (ref->stmt);
    if (!name)
!     return NULL_TREE;
  
!   for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
!     if (PHI_ARG_DEF_FROM_EDGE (phi, latch) == name)
!       break;
  
!   if (!phi)
!     return NULL_TREE;
  
    init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
    if (TREE_CODE (init) != SSA_NAME)
!     return NULL_TREE;
    init_stmt = SSA_NAME_DEF_STMT (init);
!   if (TREE_CODE (init_stmt) != GIMPLE_MODIFY_STMT)
!     return NULL_TREE;
!   gcc_assert (GIMPLE_STMT_OPERAND (init_stmt, 0) == init);
  
!   init_ref = GIMPLE_STMT_OPERAND (init_stmt, 1);
    if (!REFERENCE_CLASS_P (init_ref)
        && !DECL_P (init_ref))
!     return NULL_TREE;
  
    /* Analyze the behavior of INIT_REF with respect to LOOP (innermost
       loop enclosing PHI).  */
--- 1057,1105 ----
     iteration), returns the phi node.  Otherwise, NULL_TREE is returned.  ROOT
     is the root of the current chain.  */
  
! static gimple
  find_looparound_phi (struct loop *loop, dref ref, dref root)
  {
!   tree name, init, init_ref;
!   gimple phi = NULL, init_stmt;
    edge latch = loop_latch_edge (loop);
    struct data_reference init_dr;
+   gimple_stmt_iterator psi;
  
!   if (gimple_code (ref->stmt) == GIMPLE_ASSIGN)
      {
        if (DR_IS_READ (ref->ref))
! 	name = gimple_assign_lhs (ref->stmt);
        else
! 	name = gimple_assign_rhs1 (ref->stmt);
      }
    else
      name = PHI_RESULT (ref->stmt);
    if (!name)
!     return NULL;
  
!   for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
!     {
!       phi = gsi_stmt (psi);
!       if (PHI_ARG_DEF_FROM_EDGE (phi, latch) == name)
! 	break;
!     }
  
!   if (gsi_end_p (psi))
!     return NULL;
  
    init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
    if (TREE_CODE (init) != SSA_NAME)
!     return NULL;
    init_stmt = SSA_NAME_DEF_STMT (init);
!   if (gimple_code (init_stmt) != GIMPLE_ASSIGN)
!     return NULL;
!   gcc_assert (gimple_assign_lhs (init_stmt) == init);
  
!   init_ref = gimple_assign_rhs1 (init_stmt);
    if (!REFERENCE_CLASS_P (init_ref)
        && !DECL_P (init_ref))
!     return NULL;
  
    /* Analyze the behavior of INIT_REF with respect to LOOP (innermost
       loop enclosing PHI).  */
*************** find_looparound_phi (struct loop *loop, 
*** 1100,1106 ****
    dr_analyze_innermost (&init_dr);
  
    if (!valid_initializer_p (&init_dr, ref->distance + 1, root->ref))
!     return NULL_TREE;
  
    return phi;
  }
--- 1109,1115 ----
    dr_analyze_innermost (&init_dr);
  
    if (!valid_initializer_p (&init_dr, ref->distance + 1, root->ref))
!     return NULL;
  
    return phi;
  }
*************** find_looparound_phi (struct loop *loop, 
*** 1108,1114 ****
  /* Adds a reference for the looparound copy of REF in PHI to CHAIN.  */
  
  static void
! insert_looparound_copy (chain_p chain, dref ref, tree phi)
  {
    dref nw = XCNEW (struct dref), aref;
    unsigned i;
--- 1117,1123 ----
  /* Adds a reference for the looparound copy of REF in PHI to CHAIN.  */
  
  static void
! insert_looparound_copy (chain_p chain, dref ref, gimple phi)
  {
    dref nw = XCNEW (struct dref), aref;
    unsigned i;
*************** add_looparound_copies (struct loop *loop
*** 1139,1145 ****
  {
    unsigned i;
    dref ref, root = get_chain_root (chain);
!   tree phi;
  
    for (i = 0; VEC_iterate (dref, chain->refs, i, ref); i++)
      {
--- 1148,1154 ----
  {
    unsigned i;
    dref ref, root = get_chain_root (chain);
!   gimple phi;
  
    for (i = 0; VEC_iterate (dref, chain->refs, i, ref); i++)
      {
*************** determine_roots (struct loop *loop,
*** 1221,1286 ****
  static void
  replace_ref_with (gimple stmt, tree new, bool set, bool in_lhs)
  {
!   tree val, new_stmt;
!   block_stmt_iterator bsi;
  
    if (gimple_code (stmt) == GIMPLE_PHI)
      {
        gcc_assert (!in_lhs && !set);
  
        val = PHI_RESULT (stmt);
!       bsi = bsi_after_labels (gimple_bb (stmt));
!       remove_phi_node (stmt, NULL_TREE, false);
  
        /* Turn the phi node into GIMPLE_MODIFY_STMT.  */
!       new_stmt = build_gimple_modify_stmt (val, new);
        SSA_NAME_DEF_STMT (val) = new_stmt;
!       bsi_insert_before (&bsi, new_stmt, BSI_NEW_STMT);
        return;
      }
        
    /* Since the reference is of gimple_reg type, it should only
       appear as lhs or rhs of modify statement.  */
!   gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
  
    /* If we do not need to initialize NEW, just replace the use of OLD.  */
    if (!set)
      {
        gcc_assert (!in_lhs);
!       GIMPLE_STMT_OPERAND (stmt, 1) = new;
        update_stmt (stmt);
        return;
      }
  
!   bsi = bsi_for_stmt (stmt);
    if (in_lhs)
      {
!       val = GIMPLE_STMT_OPERAND (stmt, 1);
! 
!       /* OLD = VAL
  
! 	 is transformed to
  
  	 OLD = VAL
  	 NEW = VAL
  
! 	 (since the reference is of gimple_reg type, VAL is either gimple
! 	 invariant or ssa name).  */
      }
    else
      {
-       val = GIMPLE_STMT_OPERAND (stmt, 0);
- 
        /* VAL = OLD
  
  	 is transformed to
  
  	 VAL = OLD
  	 NEW = VAL  */
      }
  
!   new_stmt = build_gimple_modify_stmt (new, unshare_expr (val));
!   bsi_insert_after (&bsi, new_stmt, BSI_NEW_STMT);
    SSA_NAME_DEF_STMT (new) = new_stmt;
  }
  
--- 1230,1311 ----
  static void
  replace_ref_with (gimple stmt, tree new, bool set, bool in_lhs)
  {
!   tree val;
!   gimple new_stmt;
!   gimple_stmt_iterator bsi, psi;
  
    if (gimple_code (stmt) == GIMPLE_PHI)
      {
        gcc_assert (!in_lhs && !set);
  
        val = PHI_RESULT (stmt);
!       bsi = gsi_after_labels (gimple_bb (stmt));
!       psi = gsi_for_stmt (stmt);
!       remove_phi_node (&psi, false);
  
        /* Turn the phi node into GIMPLE_MODIFY_STMT.  */
!       new_stmt = gimple_build_assign (val, new);
        SSA_NAME_DEF_STMT (val) = new_stmt;
!       gsi_insert_before (&bsi, new_stmt, GSI_NEW_STMT);
        return;
      }
        
    /* Since the reference is of gimple_reg type, it should only
       appear as lhs or rhs of modify statement.  */
!   gcc_assert (gimple_code (stmt) == GIMPLE_ASSIGN);
  
    /* If we do not need to initialize NEW, just replace the use of OLD.  */
    if (!set)
      {
        gcc_assert (!in_lhs);
!       gimple_assign_set_rhs_from_tree (stmt, new);
        update_stmt (stmt);
        return;
      }
  
!   bsi = gsi_for_stmt (stmt);
    if (in_lhs)
      {
!       /* We have statement
! 	 
! 	 OLD = VAL
  
! 	 If OLD is a memory reference, then VAL is gimple_val, and we transform
! 	 this to
  
  	 OLD = VAL
  	 NEW = VAL
  
! 	 Otherwise, we are replacing a combination chain, 
! 	 VAL is the expression that performs the combination, and OLD is an
! 	 SSA name.  In this case, we transform the assignment to
! 
! 	 OLD = VAL
! 	 NEW = OLD
! 
! 	 */
! 
!       val = gimple_assign_lhs (stmt);
!       if (TREE_CODE (val) != SSA_NAME)
! 	{
! 	  gcc_assert (gimple_assign_copy_p (stmt));
! 	  val = gimple_assign_rhs1 (stmt);
! 	}
      }
    else
      {
        /* VAL = OLD
  
  	 is transformed to
  
  	 VAL = OLD
  	 NEW = VAL  */
+ 
+       val = gimple_assign_lhs (stmt);
      }
  
!   new_stmt = gimple_build_assign (new, unshare_expr (val));
!   gsi_insert_after (&bsi, new_stmt, GSI_NEW_STMT);
    SSA_NAME_DEF_STMT (new) = new_stmt;
  }
  
*************** get_init_expr (chain_p chain, unsigned i
*** 1386,1393 ****
      return VEC_index (tree, chain->inits, index);
  }
  
- #endif
- 
  /* Marks all virtual operands of statement STMT for renaming.  */
  
  void
--- 1411,1416 ----
*************** mark_virtual_ops_for_renaming (gimple st
*** 1418,1434 ****
      }
  }
  
-    /* FIXME tuples.  */
- #if 0
  /* Calls mark_virtual_ops_for_renaming for all members of LIST.  */
  
  static void
! mark_virtual_ops_for_renaming_list (tree list)
  {
!   tree_stmt_iterator tsi;
  
!   for (tsi = tsi_start (list); !tsi_end_p (tsi); tsi_next (&tsi))
!     mark_virtual_ops_for_renaming (tsi_stmt (tsi));
  }
  
  /* Returns a new temporary variable used for the I-th variable carrying
--- 1441,1455 ----
      }
  }
  
  /* Calls mark_virtual_ops_for_renaming for all members of LIST.  */
  
  static void
! mark_virtual_ops_for_renaming_list (gimple_seq list)
  {
!   gimple_stmt_iterator gsi;
  
!   for (gsi = gsi_start (list); !gsi_end_p (gsi); gsi_next (&gsi))
!     mark_virtual_ops_for_renaming (gsi_stmt (gsi));
  }
  
  /* Returns a new temporary variable used for the I-th variable carrying
*************** initialize_root_vars (struct loop *loop,
*** 1462,1469 ****
    unsigned n = chain->length;
    dref root = get_chain_root (chain);
    bool reuse_first = !chain->has_max_use_after;
!   tree ref, init, var, next, stmts;
!   tree phi;
    edge entry = loop_preheader_edge (loop), latch = loop_latch_edge (loop);
  
    /* If N == 0, then all the references are within the single iteration.  And
--- 1483,1491 ----
    unsigned n = chain->length;
    dref root = get_chain_root (chain);
    bool reuse_first = !chain->has_max_use_after;
!   tree ref, init, var, next;
!   gimple phi;
!   gimple_seq stmts;
    edge entry = loop_preheader_edge (loop), latch = loop_latch_edge (loop);
  
    /* If N == 0, then all the references are within the single iteration.  And
*************** initialize_root_vars (struct loop *loop,
*** 1473,1479 ****
    chain->vars = VEC_alloc (tree, heap, n + 1);
  
    if (chain->type == CT_COMBINATION)
!     ref = GIMPLE_STMT_OPERAND (root->stmt, 0);
    else
      ref = DR_REF (root->ref);
  
--- 1495,1501 ----
    chain->vars = VEC_alloc (tree, heap, n + 1);
  
    if (chain->type == CT_COMBINATION)
!     ref = gimple_assign_lhs (root->stmt);
    else
      ref = DR_REF (root->ref);
  
*************** initialize_root_vars (struct loop *loop,
*** 1486,1492 ****
      VEC_quick_push (tree, chain->vars, VEC_index (tree, chain->vars, 0));
    
    for (i = 0; VEC_iterate (tree, chain->vars, i, var); i++)
!     VEC_replace (tree, chain->vars, i, make_ssa_name (var, NULL_TREE));
  
    for (i = 0; i < n; i++)
      {
--- 1508,1514 ----
      VEC_quick_push (tree, chain->vars, VEC_index (tree, chain->vars, 0));
    
    for (i = 0; VEC_iterate (tree, chain->vars, i, var); i++)
!     VEC_replace (tree, chain->vars, i, make_ssa_name (var, NULL));
  
    for (i = 0; i < n; i++)
      {
*************** initialize_root_vars (struct loop *loop,
*** 1498,1504 ****
        if (stmts)
  	{
  	  mark_virtual_ops_for_renaming_list (stmts);
! 	  bsi_insert_on_edge_immediate (entry, stmts);
  	}
  
        phi = create_phi_node (var, loop->header);
--- 1520,1526 ----
        if (stmts)
  	{
  	  mark_virtual_ops_for_renaming_list (stmts);
! 	  gsi_insert_seq_on_edge_immediate (entry, stmts);
  	}
  
        phi = create_phi_node (var, loop->header);
*************** initialize_root_vars_lm (struct loop *lo
*** 1538,1545 ****
  			 bitmap tmp_vars)
  {
    unsigned i;
!   tree ref = DR_REF (root->ref), init, var, next, stmts;
!   tree phi;
    edge entry = loop_preheader_edge (loop), latch = loop_latch_edge (loop);
  
    /* Find the initializer for the variable, and check that it cannot
--- 1560,1568 ----
  			 bitmap tmp_vars)
  {
    unsigned i;
!   tree ref = DR_REF (root->ref), init, var, next;
!   gimple_seq stmts;
!   gimple phi;
    edge entry = loop_preheader_edge (loop), latch = loop_latch_edge (loop);
  
    /* Find the initializer for the variable, and check that it cannot
*************** initialize_root_vars_lm (struct loop *lo
*** 1553,1559 ****
      VEC_quick_push (tree, *vars, VEC_index (tree, *vars, 0));
    
    for (i = 0; VEC_iterate (tree, *vars, i, var); i++)
!     VEC_replace (tree, *vars, i, make_ssa_name (var, NULL_TREE));
  
    var = VEC_index (tree, *vars, 0);
        
--- 1576,1582 ----
      VEC_quick_push (tree, *vars, VEC_index (tree, *vars, 0));
    
    for (i = 0; VEC_iterate (tree, *vars, i, var); i++)
!     VEC_replace (tree, *vars, i, make_ssa_name (var, NULL));
  
    var = VEC_index (tree, *vars, 0);
        
*************** initialize_root_vars_lm (struct loop *lo
*** 1561,1567 ****
    if (stmts)
      {
        mark_virtual_ops_for_renaming_list (stmts);
!       bsi_insert_on_edge_immediate (entry, stmts);
      }
  
    if (written)
--- 1584,1590 ----
    if (stmts)
      {
        mark_virtual_ops_for_renaming_list (stmts);
!       gsi_insert_seq_on_edge_immediate (entry, stmts);
      }
  
    if (written)
*************** initialize_root_vars_lm (struct loop *lo
*** 1574,1583 ****
      }
    else
      {
!       init = build_gimple_modify_stmt (var, init);
!       SSA_NAME_DEF_STMT (var) = init;
!       mark_virtual_ops_for_renaming (init);
!       bsi_insert_on_edge_immediate (entry, init);
      }
  }
  
--- 1597,1606 ----
      }
    else
      {
!       gimple init_stmt = gimple_build_assign (var, init);
!       SSA_NAME_DEF_STMT (var) = init_stmt;
!       mark_virtual_ops_for_renaming (init_stmt);
!       gsi_insert_on_edge_immediate (entry, init_stmt);
      }
  }
  
*************** execute_load_motion (struct loop *loop, 
*** 1618,1624 ****
  	  if (n_writes)
  	    {
  	      var = VEC_index (tree, vars, 0);
! 	      var = make_ssa_name (SSA_NAME_VAR (var), NULL_TREE);
  	      VEC_replace (tree, vars, 0, var);
  	    }
  	  else
--- 1641,1647 ----
  	  if (n_writes)
  	    {
  	      var = VEC_index (tree, vars, 0);
! 	      var = make_ssa_name (SSA_NAME_VAR (var), NULL);
  	      VEC_replace (tree, vars, 0, var);
  	    }
  	  else
*************** execute_load_motion (struct loop *loop, 
*** 1634,1647 ****
  
  /* Returns the single statement in that NAME is used, excepting
     the looparound phi nodes contained in one of the chains.  If there is no
!    such statement, or more statements, NULL_TREE is returned.  */
  
! static tree
  single_nonlooparound_use (tree name)
  {
    use_operand_p use;
    imm_use_iterator it;
!   tree stmt, ret = NULL_TREE;
  
    FOR_EACH_IMM_USE_FAST (use, it, name)
      {
--- 1657,1670 ----
  
  /* Returns the single statement in that NAME is used, excepting
     the looparound phi nodes contained in one of the chains.  If there is no
!    such statement, or more statements, NULL is returned.  */
  
! static gimple
  single_nonlooparound_use (tree name)
  {
    use_operand_p use;
    imm_use_iterator it;
!   gimple stmt, ret = NULL;
  
    FOR_EACH_IMM_USE_FAST (use, it, name)
      {
*************** single_nonlooparound_use (tree name)
*** 1655,1664 ****
  			    SSA_NAME_VERSION (PHI_RESULT (stmt))))
  	    continue;
  
! 	  return NULL_TREE;
  	}
!       else if (ret != NULL_TREE)
! 	return NULL_TREE;
        else
  	ret = stmt;
      }
--- 1678,1687 ----
  			    SSA_NAME_VERSION (PHI_RESULT (stmt))))
  	    continue;
  
! 	  return NULL;
  	}
!       else if (ret != NULL)
! 	return NULL;
        else
  	ret = stmt;
      }
*************** single_nonlooparound_use (tree name)
*** 1670,1688 ****
     used.  */
  
  static void
! remove_stmt (tree stmt)
  {
!   tree next, name;
  
    if (gimple_code (stmt) == GIMPLE_PHI)
      {
        name = PHI_RESULT (stmt);
        next = single_nonlooparound_use (name);
!       remove_phi_node (stmt, NULL_TREE, true);
  
        if (!next
! 	  || TREE_CODE (next) != GIMPLE_MODIFY_STMT
! 	  || GIMPLE_STMT_OPERAND (next, 1) != name)
  	return;
  
        stmt = next;
--- 1693,1714 ----
     used.  */
  
  static void
! remove_stmt (gimple stmt)
  {
!   tree name;
!   gimple next;
!   gimple_stmt_iterator psi;
  
    if (gimple_code (stmt) == GIMPLE_PHI)
      {
        name = PHI_RESULT (stmt);
        next = single_nonlooparound_use (name);
!       psi = gsi_for_stmt (stmt);
!       remove_phi_node (&psi, true);
  
        if (!next
! 	  || !gimple_assign_copy_p (next)
! 	  || gimple_assign_rhs1 (next) != name)
  	return;
  
        stmt = next;
*************** remove_stmt (tree stmt)
*** 1690,1710 ****
  
    while (1)
      {
!       block_stmt_iterator bsi;
      
!       bsi = bsi_for_stmt (stmt);
  
!       name = GIMPLE_STMT_OPERAND (stmt, 0);
        gcc_assert (TREE_CODE (name) == SSA_NAME);
  
        next = single_nonlooparound_use (name);
  
        mark_virtual_ops_for_renaming (stmt);
!       bsi_remove (&bsi, true);
  
        if (!next
! 	  || TREE_CODE (next) != GIMPLE_MODIFY_STMT
! 	  || GIMPLE_STMT_OPERAND (next, 1) != name)
  	return;
  
        stmt = next;
--- 1716,1736 ----
  
    while (1)
      {
!       gimple_stmt_iterator bsi;
      
!       bsi = gsi_for_stmt (stmt);
  
!       name = gimple_assign_lhs (stmt);
        gcc_assert (TREE_CODE (name) == SSA_NAME);
  
        next = single_nonlooparound_use (name);
  
        mark_virtual_ops_for_renaming (stmt);
!       gsi_remove (&bsi, true);
  
        if (!next
! 	  || !gimple_assign_copy_p (next)
! 	  || gimple_assign_rhs1 (next) != name)
  	return;
  
        stmt = next;
*************** execute_pred_commoning (struct loop *loo
*** 1799,1805 ****
  }
  
  /* For each reference in CHAINS, if its defining statement is
!    ssa name, set it to phi node that defines it.  */
  
  static void
  replace_phis_by_defined_names (VEC (chain_p, heap) *chains)
--- 1825,1831 ----
  }
  
  /* For each reference in CHAINS, if its defining statement is
!    phi node, record the ssa name that is defined by it.  */
  
  static void
  replace_phis_by_defined_names (VEC (chain_p, heap) *chains)
*************** replace_phis_by_defined_names (VEC (chai
*** 1811,1824 ****
    for (i = 0; VEC_iterate (chain_p, chains, i, chain); i++)
      for (j = 0; VEC_iterate (dref, chain->refs, j, a); j++)
        {
- 	gcc_assert (TREE_CODE (a->stmt) != SSA_NAME);
  	if (gimple_code (a->stmt) == GIMPLE_PHI)
! 	  a->stmt = PHI_RESULT (a->stmt);
        }
  }
  
! /* For each reference in CHAINS, if its defining statement is
!    phi node, set it to the ssa name that is defined by it.  */
  
  static void
  replace_names_by_phis (VEC (chain_p, heap) *chains)
--- 1837,1852 ----
    for (i = 0; VEC_iterate (chain_p, chains, i, chain); i++)
      for (j = 0; VEC_iterate (dref, chain->refs, j, a); j++)
        {
  	if (gimple_code (a->stmt) == GIMPLE_PHI)
! 	  {
! 	    a->name_defined_by_phi = PHI_RESULT (a->stmt);
! 	    a->stmt = NULL;
! 	  }
        }
  }
  
! /* For each reference in CHAINS, if name_defined_by_phi is not
!    NULL, use it to set the stmt field.  */
  
  static void
  replace_names_by_phis (VEC (chain_p, heap) *chains)
*************** replace_names_by_phis (VEC (chain_p, hea
*** 1829,1838 ****
  
    for (i = 0; VEC_iterate (chain_p, chains, i, chain); i++)
      for (j = 0; VEC_iterate (dref, chain->refs, j, a); j++)
!       if (TREE_CODE (a->stmt) == SSA_NAME)
  	{
! 	  a->stmt = SSA_NAME_DEF_STMT (a->stmt);
  	  gcc_assert (gimple_code (a->stmt) == GIMPLE_PHI);
  	}
  }
  
--- 1857,1867 ----
  
    for (i = 0; VEC_iterate (chain_p, chains, i, chain); i++)
      for (j = 0; VEC_iterate (dref, chain->refs, j, a); j++)
!       if (a->stmt == NULL)
  	{
! 	  a->stmt = SSA_NAME_DEF_STMT (a->name_defined_by_phi);
  	  gcc_assert (gimple_code (a->stmt) == GIMPLE_PHI);
+ 	  a->name_defined_by_phi = NULL_TREE;
  	}
  }
  
*************** should_unroll_loop_p (struct loop *loop,
*** 1901,1907 ****
  static void
  base_names_in_chain_on (struct loop *loop, tree name, tree var)
  {
!   tree stmt, phi;
    imm_use_iterator iter;
    edge e;
  
--- 1930,1936 ----
  static void
  base_names_in_chain_on (struct loop *loop, tree name, tree var)
  {
!   gimple stmt, phi;
    imm_use_iterator iter;
    edge e;
  
*************** static void
*** 1941,1951 ****
  eliminate_temp_copies (struct loop *loop, bitmap tmp_vars)
  {
    edge e;
!   tree phi, name, use, var, stmt;
  
    e = loop_latch_edge (loop);
!   for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
      {
        name = PHI_RESULT (phi);
        var = SSA_NAME_VAR (name);
        if (!bitmap_bit_p (tmp_vars, DECL_UID (var)))
--- 1970,1983 ----
  eliminate_temp_copies (struct loop *loop, bitmap tmp_vars)
  {
    edge e;
!   gimple phi, stmt;
!   tree name, use, var;
!   gimple_stmt_iterator psi;
  
    e = loop_latch_edge (loop);
!   for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
      {
+       phi = gsi_stmt (psi);
        name = PHI_RESULT (phi);
        var = SSA_NAME_VAR (name);
        if (!bitmap_bit_p (tmp_vars, DECL_UID (var)))
*************** eliminate_temp_copies (struct loop *loop
*** 1955,1961 ****
  
        /* Base all the ssa names in the ud and du chain of NAME on VAR.  */
        stmt = SSA_NAME_DEF_STMT (use);
!       while (TREE_CODE (stmt) == PHI_NODE
  	     /* In case we could not unroll the loop enough to eliminate
  		all copies, we may reach the loop header before the defining
  		statement (in that case, some register copies will be present
--- 1987,1993 ----
  
        /* Base all the ssa names in the ud and du chain of NAME on VAR.  */
        stmt = SSA_NAME_DEF_STMT (use);
!       while (gimple_code (stmt) == GIMPLE_PHI
  	     /* In case we could not unroll the loop enough to eliminate
  		all copies, we may reach the loop header before the defining
  		statement (in that case, some register copies will be present
*************** chain_can_be_combined_p (chain_p chain)
*** 1985,2022 ****
     statements, NAME is replaced with the actual name used in the returned
     statement.  */
  
! static tree
  find_use_stmt (tree *name)
  {
!   tree stmt, rhs, lhs;
  
    /* Skip over assignments.  */
    while (1)
      {
        stmt = single_nonlooparound_use (*name);
        if (!stmt)
! 	return NULL_TREE;
  
!       if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
! 	return NULL_TREE;
  
!       lhs = GIMPLE_STMT_OPERAND (stmt, 0);
        if (TREE_CODE (lhs) != SSA_NAME)
! 	return NULL_TREE;
  
!       rhs = GIMPLE_STMT_OPERAND (stmt, 1);
!       if (rhs != *name)
! 	break;
  
!       *name = lhs;
      }
- 
-   if (!EXPR_P (rhs)
-       || REFERENCE_CLASS_P (rhs)
-       || TREE_CODE_LENGTH (TREE_CODE (rhs)) != 2)
-     return NULL_TREE;
- 
-   return stmt;
  }
  
  /* Returns true if we may perform reassociation for operation CODE in TYPE.  */
--- 2017,2056 ----
     statements, NAME is replaced with the actual name used in the returned
     statement.  */
  
! static gimple
  find_use_stmt (tree *name)
  {
!   gimple stmt;
!   tree rhs, lhs;
  
    /* Skip over assignments.  */
    while (1)
      {
        stmt = single_nonlooparound_use (*name);
        if (!stmt)
! 	return NULL;
  
!       if (gimple_code (stmt) != GIMPLE_ASSIGN)
! 	return NULL;
  
!       lhs = gimple_assign_lhs (stmt);
        if (TREE_CODE (lhs) != SSA_NAME)
! 	return NULL;
  
!       if (gimple_assign_copy_p (stmt))
! 	{
! 	  rhs = gimple_assign_rhs1 (stmt);
! 	  if (rhs != *name)
! 	    return NULL;
  
! 	  *name = lhs;
! 	}
!       else if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
! 	       == GIMPLE_BINARY_RHS)
! 	return stmt;
!       else
! 	return NULL;
      }
  }
  
  /* Returns true if we may perform reassociation for operation CODE in TYPE.  */
*************** may_reassociate_p (tree type, enum tree_
*** 2036,2062 ****
     tree of the same operations and returns its root.  Distance to the root
     is stored in DISTANCE.  */
  
! static tree
! find_associative_operation_root (tree stmt, unsigned *distance)
  {
!   tree rhs = GIMPLE_STMT_OPERAND (stmt, 1), lhs, next;
!   enum tree_code code = TREE_CODE (rhs);
    unsigned dist = 0;
  
!   if (!may_reassociate_p (TREE_TYPE (rhs), code))
!     return NULL_TREE;
  
    while (1)
      {
!       lhs = GIMPLE_STMT_OPERAND (stmt, 0);
        gcc_assert (TREE_CODE (lhs) == SSA_NAME);
  
        next = find_use_stmt (&lhs);
!       if (!next)
! 	break;
! 
!       rhs = GIMPLE_STMT_OPERAND (next, 1);
!       if (TREE_CODE (rhs) != code)
  	break;
  
        stmt = next;
--- 2070,2095 ----
     tree of the same operations and returns its root.  Distance to the root
     is stored in DISTANCE.  */
  
! static gimple
! find_associative_operation_root (gimple stmt, unsigned *distance)
  {
!   tree lhs;
!   gimple next;
!   enum tree_code code = gimple_assign_rhs_code (stmt);
!   tree type = TREE_TYPE (gimple_assign_lhs (stmt));
    unsigned dist = 0;
  
!   if (!may_reassociate_p (type, code))
!     return NULL;
  
    while (1)
      {
!       lhs = gimple_assign_lhs (stmt);
        gcc_assert (TREE_CODE (lhs) == SSA_NAME);
  
        next = find_use_stmt (&lhs);
!       if (!next
! 	  || gimple_assign_rhs_code (next) != code)
  	break;
  
        stmt = next;
*************** find_associative_operation_root (tree st
*** 2074,2103 ****
     tree formed by this operation instead of the statement that uses NAME1 or
     NAME2.  */
  
! static tree
  find_common_use_stmt (tree *name1, tree *name2)
  {
!   tree stmt1, stmt2;
  
    stmt1 = find_use_stmt (name1);
    if (!stmt1)
!     return NULL_TREE;
  
    stmt2 = find_use_stmt (name2);
    if (!stmt2)
!     return NULL_TREE;
  
    if (stmt1 == stmt2)
      return stmt1;
  
    stmt1 = find_associative_operation_root (stmt1, NULL);
    if (!stmt1)
!     return NULL_TREE;
    stmt2 = find_associative_operation_root (stmt2, NULL);
    if (!stmt2)
!     return NULL_TREE;
  
!   return (stmt1 == stmt2 ? stmt1 : NULL_TREE);
  }
  
  /* Checks whether R1 and R2 are combined together using CODE, with the result
--- 2107,2136 ----
     tree formed by this operation instead of the statement that uses NAME1 or
     NAME2.  */
  
! static gimple
  find_common_use_stmt (tree *name1, tree *name2)
  {
!   gimple stmt1, stmt2;
  
    stmt1 = find_use_stmt (name1);
    if (!stmt1)
!     return NULL;
  
    stmt2 = find_use_stmt (name2);
    if (!stmt2)
!     return NULL;
  
    if (stmt1 == stmt2)
      return stmt1;
  
    stmt1 = find_associative_operation_root (stmt1, NULL);
    if (!stmt1)
!     return NULL;
    stmt2 = find_associative_operation_root (stmt2, NULL);
    if (!stmt2)
!     return NULL;
  
!   return (stmt1 == stmt2 ? stmt1 : NULL);
  }
  
  /* Checks whether R1 and R2 are combined together using CODE, with the result
*************** combinable_refs_p (dref r1, dref r2,
*** 2111,2117 ****
    enum tree_code acode;
    bool aswap;
    tree atype;
!   tree name1, name2, stmt, rhs;
  
    name1 = name_for_ref (r1);
    name2 = name_for_ref (r2);
--- 2144,2151 ----
    enum tree_code acode;
    bool aswap;
    tree atype;
!   tree name1, name2;
!   gimple stmt;
  
    name1 = name_for_ref (r1);
    name2 = name_for_ref (r2);
*************** combinable_refs_p (dref r1, dref r2,
*** 2122,2132 ****
    if (!stmt)
      return false;
  
!   rhs = GIMPLE_STMT_OPERAND (stmt, 1);
!   acode = TREE_CODE (rhs);
    aswap = (!commutative_tree_code (acode)
! 	   && TREE_OPERAND (rhs, 0) != name1);
!   atype = TREE_TYPE (rhs);
  
    if (*code == ERROR_MARK)
      {
--- 2156,2165 ----
    if (!stmt)
      return false;
  
!   acode = gimple_assign_rhs_code (stmt);
    aswap = (!commutative_tree_code (acode)
! 	   && gimple_assign_rhs1 (stmt) != name1);
!   atype = TREE_TYPE (gimple_assign_lhs (stmt));
  
    if (*code == ERROR_MARK)
      {
*************** combinable_refs_p (dref r1, dref r2,
*** 2145,2187 ****
     an assignment of the remaining operand.  */
  
  static void
! remove_name_from_operation (tree stmt, tree op)
  {
!   tree *rhs;
  
!   gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
  
!   rhs = &GIMPLE_STMT_OPERAND (stmt, 1);
!   if (TREE_OPERAND (*rhs, 0) == op)
!     *rhs = TREE_OPERAND (*rhs, 1);
!   else if (TREE_OPERAND (*rhs, 1) == op)
!     *rhs = TREE_OPERAND (*rhs, 0);
    else
!     gcc_unreachable ();
    update_stmt (stmt);
  }
  
  /* Reassociates the expression in that NAME1 and NAME2 are used so that they
     are combined in a single statement, and returns this statement.  */
  
! static tree
  reassociate_to_the_same_stmt (tree name1, tree name2)
  {
!   tree stmt1, stmt2, root1, root2, r1, r2, s1, s2;
!   tree new_stmt, tmp_stmt, new_name, tmp_name, var;
    unsigned dist1, dist2;
    enum tree_code code;
    tree type = TREE_TYPE (name1);
!   block_stmt_iterator bsi;
  
    stmt1 = find_use_stmt (&name1);
    stmt2 = find_use_stmt (&name2);
    root1 = find_associative_operation_root (stmt1, &dist1);
    root2 = find_associative_operation_root (stmt2, &dist2);
!   code = TREE_CODE (GIMPLE_STMT_OPERAND (stmt1, 1));
  
    gcc_assert (root1 && root2 && root1 == root2
! 	      && code == TREE_CODE (GIMPLE_STMT_OPERAND (stmt2, 1)));
  
    /* Find the root of the nearest expression in that both NAME1 and NAME2
       are used.  */
--- 2178,2220 ----
     an assignment of the remaining operand.  */
  
  static void
! remove_name_from_operation (gimple stmt, tree op)
  {
!   tree other_op;
  
!   gcc_assert (gimple_code (stmt) == GIMPLE_ASSIGN);
  
!   if (gimple_assign_rhs1 (stmt) == op)
!     other_op = gimple_assign_rhs2 (stmt);
    else
!     other_op = gimple_assign_rhs1 (stmt);
! 
!   gimple_assign_set_rhs_from_tree (stmt, other_op);
    update_stmt (stmt);
  }
  
  /* Reassociates the expression in that NAME1 and NAME2 are used so that they
     are combined in a single statement, and returns this statement.  */
  
! static gimple
  reassociate_to_the_same_stmt (tree name1, tree name2)
  {
!   gimple stmt1, stmt2, root1, root2, s1, s2;
!   gimple new_stmt, tmp_stmt;
!   tree new_name, tmp_name, var, r1, r2;
    unsigned dist1, dist2;
    enum tree_code code;
    tree type = TREE_TYPE (name1);
!   gimple_stmt_iterator bsi;
  
    stmt1 = find_use_stmt (&name1);
    stmt2 = find_use_stmt (&name2);
    root1 = find_associative_operation_root (stmt1, &dist1);
    root2 = find_associative_operation_root (stmt2, &dist2);
!   code = gimple_assign_rhs_code (stmt1);
  
    gcc_assert (root1 && root2 && root1 == root2
! 	      && code == gimple_assign_rhs_code (stmt2));
  
    /* Find the root of the nearest expression in that both NAME1 and NAME2
       are used.  */
*************** reassociate_to_the_same_stmt (tree name1
*** 2193,2214 ****
    while (dist1 > dist2)
      {
        s1 = find_use_stmt (&r1);
!       r1 = GIMPLE_STMT_OPERAND (s1, 0);
        dist1--;
      }
    while (dist2 > dist1)
      {
        s2 = find_use_stmt (&r2);
!       r2 = GIMPLE_STMT_OPERAND (s2, 0);
        dist2--;
      }
  
    while (s1 != s2)
      {
        s1 = find_use_stmt (&r1);
!       r1 = GIMPLE_STMT_OPERAND (s1, 0);
        s2 = find_use_stmt (&r2);
!       r2 = GIMPLE_STMT_OPERAND (s2, 0);
      }
  
    /* Remove NAME1 and NAME2 from the statements in that they are used
--- 2226,2247 ----
    while (dist1 > dist2)
      {
        s1 = find_use_stmt (&r1);
!       r1 = gimple_assign_lhs (s1);
        dist1--;
      }
    while (dist2 > dist1)
      {
        s2 = find_use_stmt (&r2);
!       r2 = gimple_assign_lhs (s2);
        dist2--;
      }
  
    while (s1 != s2)
      {
        s1 = find_use_stmt (&r1);
!       r1 = gimple_assign_lhs (s1);
        s2 = find_use_stmt (&r2);
!       r2 = gimple_assign_lhs (s2);
      }
  
    /* Remove NAME1 and NAME2 from the statements in that they are used
*************** reassociate_to_the_same_stmt (tree name1
*** 2220,2243 ****
       combine it with the rhs of S1.  */
    var = create_tmp_var (type, "predreastmp");
    add_referenced_var (var);
!   new_name = make_ssa_name (var, NULL_TREE);
!   new_stmt = build_gimple_modify_stmt (new_name,
! 			    fold_build2 (code, type, name1, name2));
    SSA_NAME_DEF_STMT (new_name) = new_stmt;
  
    var = create_tmp_var (type, "predreastmp");
    add_referenced_var (var);
!   tmp_name = make_ssa_name (var, NULL_TREE);
!   tmp_stmt = build_gimple_modify_stmt (tmp_name,
! 					    GIMPLE_STMT_OPERAND (s1, 1));
    SSA_NAME_DEF_STMT (tmp_name) = tmp_stmt;
  
!   GIMPLE_STMT_OPERAND (s1, 1) = fold_build2 (code, type, new_name, tmp_name);
    update_stmt (s1);
  
!   bsi = bsi_for_stmt (s1);
!   bsi_insert_before (&bsi, new_stmt, BSI_SAME_STMT);
!   bsi_insert_before (&bsi, tmp_stmt, BSI_SAME_STMT);
  
    return new_stmt;
  }
--- 2253,2281 ----
       combine it with the rhs of S1.  */
    var = create_tmp_var (type, "predreastmp");
    add_referenced_var (var);
!   new_name = make_ssa_name (var, NULL);
!   new_stmt = gimple_build_assign_with_ops (code, new_name, name1, name2);
    SSA_NAME_DEF_STMT (new_name) = new_stmt;
  
    var = create_tmp_var (type, "predreastmp");
    add_referenced_var (var);
!   tmp_name = make_ssa_name (var, NULL);
! 
!   /* Rhs of S1 may now be either a binary expression with operation
!      CODE, or gimple_val (in case that stmt1 == s1 or stmt2 == s1,
!      so that name1 or name2 was removed from it).  */
!   tmp_stmt = gimple_build_assign_with_ops (gimple_assign_rhs_code (s1),
! 					   tmp_name,
! 					   gimple_assign_rhs1 (s1),
! 					   gimple_assign_rhs2 (s1));
    SSA_NAME_DEF_STMT (tmp_name) = tmp_stmt;
  
!   gimple_assign_set_rhs_with_ops (s1, code, new_name, tmp_name);
    update_stmt (s1);
  
!   bsi = gsi_for_stmt (s1);
!   gsi_insert_before (&bsi, new_stmt, GSI_SAME_STMT);
!   gsi_insert_before (&bsi, tmp_stmt, GSI_SAME_STMT);
  
    return new_stmt;
  }
*************** reassociate_to_the_same_stmt (tree name1
*** 2247,2256 ****
     associative and commutative operation in the same expression, reassociate
     the expression so that they are used in the same statement.  */
  
! static tree
  stmt_combining_refs (dref r1, dref r2)
  {
!   tree stmt1, stmt2;
    tree name1 = name_for_ref (r1);
    tree name2 = name_for_ref (r2);
  
--- 2285,2294 ----
     associative and commutative operation in the same expression, reassociate
     the expression so that they are used in the same statement.  */
  
! static gimple
  stmt_combining_refs (dref r1, dref r2)
  {
!   gimple stmt1, stmt2;
    tree name1 = name_for_ref (r1);
    tree name2 = name_for_ref (r2);
  
*************** combine_chains (chain_p ch1, chain_p ch2
*** 2273,2279 ****
    bool swap = false;
    chain_p new_chain;
    unsigned i;
!   tree root_stmt;
    tree rslt_type = NULL_TREE;
  
    if (ch1 == ch2)
--- 2311,2317 ----
    bool swap = false;
    chain_p new_chain;
    unsigned i;
!   gimple root_stmt;
    tree rslt_type = NULL_TREE;
  
    if (ch1 == ch2)
*************** prepare_initializers_chain (struct loop 
*** 2406,2412 ****
  {
    unsigned i, n = (chain->type == CT_INVARIANT) ? 1 : chain->length;
    struct data_reference *dr = get_chain_root (chain)->ref;
!   tree init, stmts;
    dref laref;
    edge entry = loop_preheader_edge (loop);
  
--- 2444,2451 ----
  {
    unsigned i, n = (chain->type == CT_INVARIANT) ? 1 : chain->length;
    struct data_reference *dr = get_chain_root (chain)->ref;
!   tree init;
!   gimple_seq stmts;
    dref laref;
    edge entry = loop_preheader_edge (loop);
  
*************** prepare_initializers_chain (struct loop 
*** 2420,2426 ****
       instead of creating our own.  */
    for (i = 0; VEC_iterate (dref, chain->refs, i, laref); i++)
      {
!       if (TREE_CODE (laref->stmt) != PHI_NODE)
  	continue;
  
        gcc_assert (laref->distance > 0);
--- 2459,2465 ----
       instead of creating our own.  */
    for (i = 0; VEC_iterate (dref, chain->refs, i, laref); i++)
      {
!       if (gimple_code (laref->stmt) != GIMPLE_PHI)
  	continue;
  
        gcc_assert (laref->distance > 0);
*************** prepare_initializers_chain (struct loop 
*** 2444,2450 ****
        if (stmts)
  	{
  	  mark_virtual_ops_for_renaming_list (stmts);
! 	  bsi_insert_on_edge_immediate (entry, stmts);
  	}
        set_alias_info (init, dr);
  
--- 2483,2489 ----
        if (stmts)
  	{
  	  mark_virtual_ops_for_renaming_list (stmts);
! 	  gsi_insert_seq_on_edge_immediate (entry, stmts);
  	}
        set_alias_info (init, dr);
  
*************** end: ;
*** 2594,2608 ****
  
    return unroll;
  }
- #endif
  
  /* Runs predictive commoning.  */
  
  unsigned
  tree_predictive_commoning (void)
  {
-   /* FIXME tuples.  */
- #if 0
    bool unrolled = false;
    struct loop *loop;
    loop_iterator li;
--- 2633,2644 ----
*************** tree_predictive_commoning (void)
*** 2622,2629 ****
    free_original_copy_tables ();
  
    return ret;
- #else
-   gimple_unreachable ();
-   return 0;
- #endif
  }
--- 2658,2661 ----
Index: passes.c
===================================================================
*** passes.c	(revision 134500)
--- passes.c	(working copy)
*************** init_optimization_passes (void)
*** 671,678 ****
  	  NEXT_PASS (pass_dce_loop);
  #endif
  	  NEXT_PASS (pass_lim);
- #if 0
  	  NEXT_PASS (pass_predcom);
  	  NEXT_PASS (pass_tree_unswitch);
  #endif
  	  NEXT_PASS (pass_scev_cprop);
--- 671,678 ----
  	  NEXT_PASS (pass_dce_loop);
  #endif
  	  NEXT_PASS (pass_lim);
  	  NEXT_PASS (pass_predcom);
+ #if 0
  	  NEXT_PASS (pass_tree_unswitch);
  #endif
  	  NEXT_PASS (pass_scev_cprop);


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