OSDN Git Service

2007-07-12 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-sccvn.c
index 45ebe08..a04bb21 100644 (file)
@@ -43,6 +43,7 @@ Boston, MA 02110-1301, USA.  */
 #include "bitmap.h"
 #include "langhooks.h"
 #include "cfgloop.h"
+#include "tree-ssa-propagate.h"
 #include "tree-ssa-sccvn.h"
 
 /* This algorithm is based on the SCC algorithm presented by Keith
@@ -528,6 +529,7 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
        case INTEGER_CST:
        case COMPLEX_CST:
        case VECTOR_CST:
+       case REAL_CST:
        case VALUE_HANDLE:
        case VAR_DECL:
        case PARM_DECL:
@@ -1014,16 +1016,9 @@ print_scc (FILE *out, VEC (tree, heap) *scc)
 static inline bool
 set_ssa_val_to (tree from, tree to)
 {
+  tree currval;
   gcc_assert (to != NULL);
 
-  /* Make sure we don't create chains of copies, so that we get the
-     best value numbering.  visit_copy has code to make sure this doesn't
-     happen, we are doing this here to assert that nothing else breaks
-     this.  */
-  gcc_assert (TREE_CODE (to) != SSA_NAME
-             || TREE_CODE (SSA_VAL (to)) != SSA_NAME
-             || SSA_VAL (to) == to
-             || to == from);
   /* The only thing we allow as value numbers are ssa_names and
      invariants.  So assert that here.  */
   gcc_assert (TREE_CODE (to) == SSA_NAME || is_gimple_min_invariant (to));
@@ -1037,7 +1032,9 @@ set_ssa_val_to (tree from, tree to)
       fprintf (dump_file, "\n");
     }
 
-  if (SSA_VAL (from) != to)
+  currval = SSA_VAL (from);
+
+  if (currval != to  && !operand_equal_p (currval, to, OEP_PURE_SAME))
     {
       SSA_VAL (from) = to;
       return true;
@@ -1337,6 +1334,7 @@ expr_has_constants (tree expr)
       /* Constants inside reference ops are rarely interesting, but
         it can take a lot of looking to find them.  */
     case tcc_reference:
+    case tcc_declaration:
       return false;
     default:
       return is_gimple_min_invariant (expr);
@@ -1401,42 +1399,16 @@ simplify_binary_expression (tree rhs)
       else if (SSA_VAL (op1) != VN_TOP && SSA_VAL (op1) != op1)
        op1 = VN_INFO (op1)->valnum;
     }
+
   result = fold_binary (TREE_CODE (rhs), TREE_TYPE (rhs), op0, op1);
 
-  /* Make sure result is not a complex expression consiting
+  /* Make sure result is not a complex expression consisting
      of operators of operators (IE (a + b) + (a + c))
      Otherwise, we will end up with unbounded expressions if
      fold does anything at all.  */
-  if (result)
-    {
-      if (is_gimple_min_invariant (result))
-       return result;
-      else if (SSA_VAR_P (result))
-       return result;
-      else if (EXPR_P (result))
-       {
-         switch (TREE_CODE_CLASS (TREE_CODE (result)))
-           {
-           case tcc_unary:
-             {
-               tree op0 = TREE_OPERAND (result, 0);
-               if (!EXPR_P (op0))
-                 return result;
-             }
-             break;
-           case tcc_binary:
-             {
-               tree op0 = TREE_OPERAND (result, 0);
-               tree op1 = TREE_OPERAND (result, 1);
-               if (!EXPR_P (op0) && !EXPR_P (op1))
-                 return result;
-             }
-             break;
-           default:
-             break;
-           }
-       }
-    }
+  if (result && valid_gimple_expression_p (result))
+    return result;
+
   return NULL_TREE;
 }
 
@@ -1458,7 +1430,15 @@ try_to_simplify (tree stmt, tree rhs)
        {
          /* For references, see if we find a result for the lookup,
             and use it if we do.  */
-
+       case tcc_declaration:
+         /* Pull out any truly constant values.  */
+         if (TREE_READONLY (rhs)
+             && TREE_STATIC (rhs)
+             && DECL_INITIAL (rhs)
+             && is_gimple_min_invariant (DECL_INITIAL (rhs)))
+           return DECL_INITIAL (rhs);
+
+           /* Fallthrough. */
        case tcc_reference:
          {
            tree result = vn_reference_lookup (rhs,
@@ -1545,6 +1525,13 @@ visit_use (tree use)
 
          STRIP_USELESS_TYPE_CONVERSION (rhs);
 
+         /* Shortcut for copies. Simplifying copies is pointless,
+            since we copy the expression and value they represent.  */
+         if (TREE_CODE (rhs) == SSA_NAME && TREE_CODE (lhs) == SSA_NAME)
+           {
+             changed = visit_copy (lhs, rhs);
+             goto done;
+           }
          simplified = try_to_simplify (stmt, rhs);
          if (simplified && simplified != rhs)
            {
@@ -1611,7 +1598,7 @@ visit_use (tree use)
          if (TREE_CODE (lhs) == SSA_NAME
              && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
            changed = defs_to_varying (stmt);
-         else if (REFERENCE_CLASS_P (lhs))
+         else if (REFERENCE_CLASS_P (lhs) || DECL_P (lhs))
            {
              changed = visit_reference_op_store (lhs, rhs, stmt);
            }
@@ -1623,8 +1610,6 @@ visit_use (tree use)
                  VN_INFO (lhs)->expr = rhs;
                  changed = set_ssa_val_to (lhs, rhs);
                }
-             else if (TREE_CODE (rhs) == SSA_NAME)
-               changed = visit_copy (lhs, rhs);
              else
                {
                  switch (TREE_CODE_CLASS (TREE_CODE (rhs)))