OSDN Git Service

Revert "Fix PR debug/49047"
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-copy.c
index d552c3a..211d7de 100644 (file)
@@ -191,7 +191,10 @@ propagate_value (use_operand_p op_p, tree val)
 
    Use this version when not const/copy propagating values.  For example,
    PRE uses this version when building expressions as they would appear
-   in specific blocks taking into account actions of PHI nodes.  */
+   in specific blocks taking into account actions of PHI nodes.
+
+   The statement in which an expression has been replaced should be
+   folded using fold_stmt_inplace.  */
 
 void
 replace_exp (use_operand_p op_p, tree val)
@@ -241,7 +244,6 @@ propagate_tree_value_into_stmt (gimple_stmt_iterator *gsi, tree val)
         expr = gimple_assign_rhs1 (stmt);
       propagate_tree_value (&expr, val);
       gimple_assign_set_rhs_from_tree (gsi, expr);
-      stmt = gsi_stmt (*gsi);
     }
   else if (gimple_code (stmt) == GIMPLE_COND)
     {
@@ -313,8 +315,9 @@ stmt_may_generate_copy (gimple stmt)
   /* Otherwise, the only statements that generate useful copies are
      assignments whose RHS is just an SSA name that doesn't flow
      through abnormal edges.  */
-  return (gimple_assign_rhs_code (stmt) == SSA_NAME
-         && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)));
+  return ((gimple_assign_rhs_code (stmt) == SSA_NAME
+          && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)))
+         || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)));
 }
 
 
@@ -564,6 +567,7 @@ copy_prop_visit_phi_node (gimple phi)
   for (i = 0; i < gimple_phi_num_args (phi); i++)
     {
       prop_value_t *arg_val;
+      tree arg_value;
       tree arg = gimple_phi_arg_def (phi, i);
       edge e = gimple_phi_arg_edge (phi, i);
 
@@ -572,24 +576,9 @@ copy_prop_visit_phi_node (gimple phi)
       if (!(e->flags & EDGE_EXECUTABLE))
        continue;
 
-      /* Constants in the argument list never generate a useful copy.
-        Similarly, names that flow through abnormal edges cannot be
-        used to derive copies.  */
-      if (TREE_CODE (arg) != SSA_NAME || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg))
-       {
-         phi_val.value = lhs;
-         break;
-       }
-
-      /* Avoid copy propagation from an inner into an outer loop.
-        Otherwise, this may move loop variant variables outside of
-        their loops and prevent coalescing opportunities.  If the
-        value was loop invariant, it will be hoisted by LICM and
-        exposed for copy propagation.  Not a problem for virtual
-        operands though.
-        ???  The value will be always loop invariant.  */
-      if (is_gimple_reg (lhs)
-         && loop_depth_of_name (arg) > loop_depth_of_name (lhs))
+      /* Names that flow through abnormal edges cannot be used to
+        derive copies.  */
+      if (TREE_CODE (arg) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg))
        {
          phi_val.value = lhs;
          break;
@@ -602,26 +591,51 @@ copy_prop_visit_phi_node (gimple phi)
          fprintf (dump_file, "\n");
        }
 
-      arg_val = get_copy_of_val (arg);
+      if (TREE_CODE (arg) == SSA_NAME)
+       {
+         arg_val = get_copy_of_val (arg);
 
-      /* If we didn't visit the definition of arg yet treat it as
-         UNDEFINED.  This also handles PHI arguments that are the
-        same as lhs.  We'll come here again.  */
-      if (!arg_val->value)
-       continue;
+         /* If we didn't visit the definition of arg yet treat it as
+            UNDEFINED.  This also handles PHI arguments that are the
+            same as lhs.  We'll come here again.  */
+         if (!arg_val->value)
+           continue;
+
+         arg_value = arg_val->value;
+       }
+      else
+       arg_value = valueize_val (arg);
+
+      /* Avoid copy propagation from an inner into an outer loop.
+        Otherwise, this may move loop variant variables outside of
+        their loops and prevent coalescing opportunities.  If the
+        value was loop invariant, it will be hoisted by LICM and
+        exposed for copy propagation.
+        ???  The value will be always loop invariant.
+        In loop-closed SSA form do not copy-propagate through
+        PHI nodes in blocks with a loop exit edge predecessor.  */
+      if (current_loops
+         && TREE_CODE (arg_value) == SSA_NAME
+         && (loop_depth_of_name (arg_value) > loop_depth_of_name (lhs)
+             || (loops_state_satisfies_p (LOOP_CLOSED_SSA)
+                 && loop_exit_edge_p (e->src->loop_father, e))))
+       {
+         phi_val.value = lhs;
+         break;
+       }
 
       /* If the LHS didn't have a value yet, make it a copy of the
         first argument we find.   */
       if (phi_val.value == NULL_TREE)
        {
-         phi_val.value = arg_val->value;
+         phi_val.value = arg_value;
          continue;
        }
 
       /* If PHI_VAL and ARG don't have a common copy-of chain, then
         this PHI node cannot be a copy operation.  */
-      if (phi_val.value != arg_val->value
-         && !operand_equal_p (phi_val.value, arg_val->value, 0))
+      if (phi_val.value != arg_value
+         && !operand_equal_p (phi_val.value, arg_value, 0))
        {
          phi_val.value = lhs;
          break;
@@ -666,7 +680,6 @@ init_copy_prop (void)
     {
       gimple_stmt_iterator si;
       int depth = bb->loop_depth;
-      bool loop_exit_p = false;
 
       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
        {
@@ -703,26 +716,13 @@ init_copy_prop (void)
              set_copy_of_val (def, def);
        }
 
-      /* In loop-closed SSA form do not copy-propagate through
-        PHI nodes in blocks with a loop exit edge predecessor.  */
-      if (current_loops
-         && loops_state_satisfies_p (LOOP_CLOSED_SSA))
-       {
-         edge_iterator ei;
-         edge e;
-         FOR_EACH_EDGE (e, ei, bb->preds)
-           if (loop_exit_edge_p (e->src->loop_father, e))
-             loop_exit_p = true;
-       }
-
       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
        {
           gimple phi = gsi_stmt (si);
           tree def;
 
          def = gimple_phi_result (phi);
-         if (!is_gimple_reg (def)
-             || loop_exit_p)
+         if (!is_gimple_reg (def))
             prop_set_simulate_again (phi, false);
          else
             prop_set_simulate_again (phi, true);
@@ -769,6 +769,7 @@ fini_copy_prop (void)
         of the representative to the first solution we find if
         it doesn't have one already.  */
       if (copy_of[i].value != var
+         && TREE_CODE (copy_of[i].value) == SSA_NAME
          && POINTER_TYPE_P (TREE_TYPE (var))
          && SSA_NAME_PTR_INFO (var)
          && !SSA_NAME_PTR_INFO (copy_of[i].value))