OSDN Git Service

* tree-data-ref.c (compute_estimated_nb_iterations,
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-ccp.c
index 58b8c2c..6816daf 100644 (file)
@@ -199,7 +199,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "ggc.h"
 #include "basic-block.h"
 #include "output.h"
-#include "errors.h"
 #include "expr.h"
 #include "function.h"
 #include "diagnostic.h"
@@ -228,7 +227,7 @@ typedef enum
    (i.e., a V_MAY_DEF or V_MUST_DEF), CONST_VAL[I].MEM_REF will
    contain the actual memory reference used to store (i.e., the LHS of
    the assignment doing the store).  */
-prop_value_t *const_val;
+static prop_value_t *const_val;
 
 /* True if we are also propagating constants in stores and loads.  */
 static bool do_store_ccp;
@@ -581,7 +580,7 @@ static void
 ccp_finalize (void)
 {
   /* Perform substitutions based on the known constant values.  */
-  substitute_and_fold (const_val);
+  substitute_and_fold (const_val, false);
 
   free (const_val);
 }
@@ -849,27 +848,7 @@ ccp_fold (tree stmt)
            op0 = get_value (op0, true)->value;
        }
 
-      retval = fold_unary_to_constant (code, TREE_TYPE (rhs), op0);
-
-      /* If we folded, but did not create an invariant, then we can not
-        use this expression.  */
-      if (retval && ! is_gimple_min_invariant (retval))
-       return NULL;
-
-      /* If we could not fold the expression, but the arguments are all
-         constants and gimple values, then build and return the new
-        expression. 
-
-        In some cases the new expression is still something we can
-        use as a replacement for an argument.  This happens with
-        NOP conversions of types for example.
-
-        In other cases the new expression can not be used as a
-        replacement for an argument (as it would create non-gimple
-        code).  But the new expression can still be used to derive
-        other constants.  */
-      if (! retval && is_gimple_min_invariant (op0))
-       return build1 (code, TREE_TYPE (rhs), op0);
+      return fold_unary (code, TREE_TYPE (rhs), op0);
     }
 
   /* Binary and comparison operators.  We know one or both of the
@@ -900,29 +879,7 @@ ccp_fold (tree stmt)
            op1 = val->value;
        }
 
-      retval = fold_binary_to_constant (code, TREE_TYPE (rhs), op0, op1);
-
-      /* If we folded, but did not create an invariant, then we can not
-        use this expression.  */
-      if (retval && ! is_gimple_min_invariant (retval))
-       return NULL;
-      
-      /* If we could not fold the expression, but the arguments are all
-         constants and gimple values, then build and return the new
-        expression. 
-
-        In some cases the new expression is still something we can
-        use as a replacement for an argument.  This happens with
-        NOP conversions of types for example.
-
-        In other cases the new expression can not be used as a
-        replacement for an argument (as it would create non-gimple
-        code).  But the new expression can still be used to derive
-        other constants.  */
-      if (! retval
-         && is_gimple_min_invariant (op0)
-         && is_gimple_min_invariant (op1))
-       return build (code, TREE_TYPE (rhs), op0, op1);
+      return fold_binary (code, TREE_TYPE (rhs), op0, op1);
     }
 
   /* We may be able to fold away calls to builtin functions if their
@@ -1917,7 +1874,6 @@ maybe_fold_stmt_addition (tree expr)
   return t;
 }
 
-
 /* Subroutine of fold_stmt called via walk_tree.  We perform several
    simplifications of EXPR_P, mostly having to do with pointer arithmetic.  */
 
@@ -1991,6 +1947,10 @@ fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
       }
       break;
 
+    case TARGET_MEM_REF:
+      t = maybe_fold_tmr (expr);
+      break;
+
     default:
       return NULL_TREE;
     }
@@ -2308,6 +2268,32 @@ fold_stmt (tree *stmt_p)
   return changed;
 }
 
+/* Perform the minimal folding on statement STMT.  Only operations like
+   *&x created by constant propagation are handled.  The statement cannot
+   be replaced with a new one.  */
+
+bool
+fold_stmt_inplace (tree stmt)
+{
+  tree old_stmt = stmt, rhs, new_rhs;
+  bool changed = false;
+
+  walk_tree (&stmt, fold_stmt_r, &changed, NULL);
+  gcc_assert (stmt == old_stmt);
+
+  rhs = get_rhs (stmt);
+  if (!rhs || rhs == stmt)
+    return changed;
+
+  new_rhs = fold (rhs);
+  if (new_rhs == rhs)
+    return changed;
+
+  changed |= set_rhs (&stmt, new_rhs);
+  gcc_assert (stmt == old_stmt);
+
+  return changed;
+}
 \f
 /* Convert EXPR into a GIMPLE value suitable for substitution on the
    RHS of an assignment.  Insert the necessary statements before
@@ -2355,6 +2341,7 @@ execute_fold_all_builtins (void)
       for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
        {
          tree *stmtp = bsi_stmt_ptr (i);
+         tree old_stmt = *stmtp;
          tree call = get_rhs (*stmtp);
          tree callee, result;
 
@@ -2396,7 +2383,7 @@ execute_fold_all_builtins (void)
                }
            }
          update_stmt (*stmtp);
-         if (maybe_clean_eh_stmt (*stmtp)
+         if (maybe_clean_or_replace_eh_stmt (old_stmt, *stmtp)
              && tree_purge_dead_eh_edges (bb))
            cfg_changed = true;