ipa-cp.c (ipcp_cloning_candidate_p): Use opt_for_fn.
[gcc.git] / gcc / tree-ssa-dom.c
index ef92f3024b040506fd27a871f4ba4d3790c8595b..191d3e0c14664b6a6c2fe396fd736372775da5f4 100644 (file)
@@ -27,9 +27,20 @@ along with GCC; see the file COPYING3.  If not see
 #include "stor-layout.h"
 #include "flags.h"
 #include "tm_p.h"
+#include "predict.h"
+#include "vec.h"
+#include "hashtab.h"
+#include "hash-set.h"
+#include "machmode.h"
+#include "hard-reg-set.h"
+#include "input.h"
+#include "function.h"
+#include "dominance.h"
+#include "cfg.h"
+#include "cfganal.h"
 #include "basic-block.h"
 #include "cfgloop.h"
-#include "function.h"
+#include "inchash.h"
 #include "gimple-pretty-print.h"
 #include "tree-ssa-alias.h"
 #include "internal-fn.h"
@@ -54,6 +65,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "params.h"
 #include "tree-ssa-threadedge.h"
 #include "tree-ssa-dom.h"
+#include "inchash.h"
 
 /* This file implements optimizations on the dominator tree.  */
 
@@ -293,6 +305,8 @@ initialize_hash_element (gimple stmt, tree lhs,
         case GIMPLE_UNARY_RHS:
          expr->kind = EXPR_UNARY;
          expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
+         if (CONVERT_EXPR_CODE_P (subcode))
+           subcode = NOP_EXPR;
          expr->ops.unary.op = subcode;
          expr->ops.unary.opnd = gimple_assign_rhs1 (stmt);
          break;
@@ -556,45 +570,42 @@ hashable_expr_equal_p (const struct hashable_expr *expr0,
 }
 
 /* Generate a hash value for a pair of expressions.  This can be used
-   iteratively by passing a previous result as the VAL argument.
+   iteratively by passing a previous result in HSTATE.
 
    The same hash value is always returned for a given pair of expressions,
    regardless of the order in which they are presented.  This is useful in
    hashing the operands of commutative functions.  */
 
-static hashval_t
-iterative_hash_exprs_commutative (const_tree t1,
-                                  const_tree t2, hashval_t val)
+namespace inchash
 {
-  hashval_t one = iterative_hash_expr (t1, 0);
-  hashval_t two = iterative_hash_expr (t2, 0);
-  hashval_t t;
 
-  if (one > two)
-    t = one, one = two, two = t;
-  val = iterative_hash_hashval_t (one, val);
-  val = iterative_hash_hashval_t (two, val);
+static void
+add_expr_commutative (const_tree t1, const_tree t2, hash &hstate)
+{
+  hash one, two;
 
-  return val;
+  inchash::add_expr (t1, one);
+  inchash::add_expr (t2, two);
+  hstate.add_commutative (one, two);
 }
 
 /* Compute a hash value for a hashable_expr value EXPR and a
    previously accumulated hash value VAL.  If two hashable_expr
    values compare equal with hashable_expr_equal_p, they must
    hash to the same value, given an identical value of VAL.
-   The logic is intended to follow iterative_hash_expr in tree.c.  */
+   The logic is intended to follow inchash::add_expr in tree.c.  */
 
-static hashval_t
-iterative_hash_hashable_expr (const struct hashable_expr *expr, hashval_t val)
+static void
+add_hashable_expr (const struct hashable_expr *expr, hash &hstate)
 {
   switch (expr->kind)
     {
     case EXPR_SINGLE:
-      val = iterative_hash_expr (expr->ops.single.rhs, val);
+      inchash::add_expr (expr->ops.single.rhs, hstate);
       break;
 
     case EXPR_UNARY:
-      val = iterative_hash_object (expr->ops.unary.op, val);
+      hstate.add_object (expr->ops.unary.op);
 
       /* Make sure to include signedness in the hash computation.
          Don't hash the type, that can lead to having nodes which
@@ -602,34 +613,34 @@ iterative_hash_hashable_expr (const struct hashable_expr *expr, hashval_t val)
          have different hash codes.  */
       if (CONVERT_EXPR_CODE_P (expr->ops.unary.op)
           || expr->ops.unary.op == NON_LVALUE_EXPR)
-        val += TYPE_UNSIGNED (expr->type);
+        hstate.add_int (TYPE_UNSIGNED (expr->type));
 
-      val = iterative_hash_expr (expr->ops.unary.opnd, val);
+      inchash::add_expr (expr->ops.unary.opnd, hstate);
       break;
 
     case EXPR_BINARY:
-      val = iterative_hash_object (expr->ops.binary.op, val);
+      hstate.add_object (expr->ops.binary.op);
       if (commutative_tree_code (expr->ops.binary.op))
-       val = iterative_hash_exprs_commutative (expr->ops.binary.opnd0,
-                                               expr->ops.binary.opnd1, val);
+       inchash::add_expr_commutative (expr->ops.binary.opnd0,
+                                         expr->ops.binary.opnd1, hstate);
       else
         {
-          val = iterative_hash_expr (expr->ops.binary.opnd0, val);
-          val = iterative_hash_expr (expr->ops.binary.opnd1, val);
+          inchash::add_expr (expr->ops.binary.opnd0, hstate);
+          inchash::add_expr (expr->ops.binary.opnd1, hstate);
         }
       break;
 
     case EXPR_TERNARY:
-      val = iterative_hash_object (expr->ops.ternary.op, val);
+      hstate.add_object (expr->ops.ternary.op);
       if (commutative_ternary_tree_code (expr->ops.ternary.op))
-       val = iterative_hash_exprs_commutative (expr->ops.ternary.opnd0,
-                                               expr->ops.ternary.opnd1, val);
+       inchash::add_expr_commutative (expr->ops.ternary.opnd0,
+                                         expr->ops.ternary.opnd1, hstate);
       else
         {
-          val = iterative_hash_expr (expr->ops.ternary.opnd0, val);
-          val = iterative_hash_expr (expr->ops.ternary.opnd1, val);
+          inchash::add_expr (expr->ops.ternary.opnd0, hstate);
+          inchash::add_expr (expr->ops.ternary.opnd1, hstate);
         }
-      val = iterative_hash_expr (expr->ops.ternary.opnd2, val);
+      inchash::add_expr (expr->ops.ternary.opnd2, hstate);
       break;
 
     case EXPR_CALL:
@@ -638,15 +649,14 @@ iterative_hash_hashable_expr (const struct hashable_expr *expr, hashval_t val)
         enum tree_code code = CALL_EXPR;
         gimple fn_from;
 
-        val = iterative_hash_object (code, val);
+        hstate.add_object (code);
         fn_from = expr->ops.call.fn_from;
         if (gimple_call_internal_p (fn_from))
-          val = iterative_hash_hashval_t
-            ((hashval_t) gimple_call_internal_fn (fn_from), val);
+          hstate.merge_hash ((hashval_t) gimple_call_internal_fn (fn_from));
         else
-          val = iterative_hash_expr (gimple_call_fn (fn_from), val);
+          inchash::add_expr (gimple_call_fn (fn_from), hstate);
         for (i = 0; i < expr->ops.call.nargs; i++)
-          val = iterative_hash_expr (expr->ops.call.args[i], val);
+          inchash::add_expr (expr->ops.call.args[i], hstate);
       }
       break;
 
@@ -655,15 +665,15 @@ iterative_hash_hashable_expr (const struct hashable_expr *expr, hashval_t val)
         size_t i;
 
         for (i = 0; i < expr->ops.phi.nargs; i++)
-          val = iterative_hash_expr (expr->ops.phi.args[i], val);
+          inchash::add_expr (expr->ops.phi.args[i], hstate);
       }
       break;
 
     default:
       gcc_unreachable ();
     }
+}
 
-  return val;
 }
 
 /* Print a diagnostic dump of an expression hash table entry.  */
@@ -1589,6 +1599,33 @@ record_const_or_copy (tree x, tree y)
   record_const_or_copy_1 (x, y, prev_x);
 }
 
+/* Return the loop depth of the basic block of the defining statement of X.
+   This number should not be treated as absolutely correct because the loop
+   information may not be completely up-to-date when dom runs.  However, it
+   will be relatively correct, and as more passes are taught to keep loop info
+   up to date, the result will become more and more accurate.  */
+
+static int
+loop_depth_of_name (tree x)
+{
+  gimple defstmt;
+  basic_block defbb;
+
+  /* If it's not an SSA_NAME, we have no clue where the definition is.  */
+  if (TREE_CODE (x) != SSA_NAME)
+    return 0;
+
+  /* Otherwise return the loop depth of the defining statement's bb.
+     Note that there may not actually be a bb for this statement, if the
+     ssa_name is live on entry.  */
+  defstmt = SSA_NAME_DEF_STMT (x);
+  defbb = gimple_bb (defstmt);
+  if (!defbb)
+    return 0;
+
+  return bb_loop_depth (defbb);
+}
+
 /* Similarly, but assume that X and Y are the two operands of an EQ_EXPR.
    This constrains the cases in which we may treat this as assignment.  */
 
@@ -1608,7 +1645,10 @@ record_equality (tree x, tree y)
      long as we canonicalize on one value.  */
   if (is_gimple_min_invariant (y))
     ;
-  else if (is_gimple_min_invariant (x))
+  else if (is_gimple_min_invariant (x)
+          /* ???  When threading over backedges the following is important
+             for correctness.  See PR61757.  */
+          || (loop_depth_of_name (x) <= loop_depth_of_name (y)))
     prev_x = x, x = y, y = prev_x, prev_x = prev_y;
   else if (prev_x && is_gimple_min_invariant (prev_x))
     x = y, y = prev_x, prev_x = prev_y;
@@ -2568,24 +2608,24 @@ avail_expr_hash (const void *p)
   gimple stmt = ((const struct expr_hash_elt *)p)->stmt;
   const struct hashable_expr *expr = &((const struct expr_hash_elt *)p)->expr;
   tree vuse;
-  hashval_t val = 0;
+  inchash::hash hstate;
 
-  val = iterative_hash_hashable_expr (expr, val);
+  inchash::add_hashable_expr (expr, hstate);
 
   /* If the hash table entry is not associated with a statement, then we
      can just hash the expression and not worry about virtual operands
      and such.  */
   if (!stmt)
-    return val;
+    return hstate.end ();
 
   /* Add the SSA version numbers of the vuse operand.  This is important
      because compound variables like arrays are not renamed in the
      operands.  Rather, the rename is done on the virtual variable
      representing all the elements of the array.  */
   if ((vuse = gimple_vuse (stmt)))
-    val = iterative_hash_expr (vuse, val);
+    inchash::add_expr (vuse, hstate);
 
-  return val;
+  return hstate.end ();
 }
 
 /* PHI-ONLY copy and constant propagation.  This pass is meant to clean