gimple-match.h (mprts_hook): Declare.
authorRichard Biener <rguenther@suse.de>
Thu, 1 Oct 2015 07:54:26 +0000 (07:54 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 1 Oct 2015 07:54:26 +0000 (07:54 +0000)
2015-10-01  Richard Biener  <rguenther@suse.de>

* gimple-match.h (mprts_hook): Declare.
* gimple-match.head.c (mprts_hook): Define.
(maybe_push_res_to_seq): Use new hook.
* gimple-fold.c (gimple_fold_stmt_to_constant_1): Likewise.
* tree-ssa-sccvn.h (vn_ssa_aux::expr): Change to a gimple_seq.
(vn_ssa_aux::has_constants): Remove.
* tree-ssa-sccvn.c: Include gimple-match.h.
(VN_INFO_GET): Assert we don't re-use SSA names.
(vn_get_expr_for): Remove.
(expr_has_constants): Likewise.
(stmt_has_constants): Likewise.
(simplify_binary_expression): Likewise.
(simplify_unary_expression): Likewise.
(vn_lookup_simplify_result): New hook.
(visit_copy): Adjust.
(visit_reference_op_call): Likewise.
(visit_phi): Likewise.
(visit_use): Likewise.
(process_scc): Likewise.
(init_scc_vn): Likewise.
(visit_reference_op_load): Likewise.  Use match-and-simplify and
a gimple seq for inserted expressions.
(try_to_simplify): Remove GENERIC stmt combining code.
(sccvn_dom_walker::before_dom_children): Use match-and-simplify.
* tree-ssa-pre.c (eliminate_insert): Adjust.
(eliminate_dom_walker::before_dom_children): Likewise.

* gcc.dg/tree-ssa/ssa-fre-7.c: Adjust.
* gcc.dg/tree-ssa/ssa-fre-8.c: Likewise.

From-SVN: r228320

gcc/ChangeLog
gcc/gimple-fold.c
gcc/gimple-match-head.c
gcc/gimple-match.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c
gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c
gcc/tree-ssa-pre.c
gcc/tree-ssa-sccvn.c
gcc/tree-ssa-sccvn.h

index d50f9916613a6e7edd815184c00edefc9927c716..122f3b410dce330166a2b1846568fcbe31325fd5 100644 (file)
@@ -1,3 +1,32 @@
+2015-10-01  Richard Biener  <rguenther@suse.de>
+
+       * gimple-match.h (mprts_hook): Declare.
+       * gimple-match.head.c (mprts_hook): Define.
+       (maybe_push_res_to_seq): Use new hook.
+       * gimple-fold.c (gimple_fold_stmt_to_constant_1): Likewise.
+       * tree-ssa-sccvn.h (vn_ssa_aux::expr): Change to a gimple_seq.
+       (vn_ssa_aux::has_constants): Remove.
+       * tree-ssa-sccvn.c: Include gimple-match.h.
+       (VN_INFO_GET): Assert we don't re-use SSA names.
+       (vn_get_expr_for): Remove.
+       (expr_has_constants): Likewise.
+       (stmt_has_constants): Likewise.
+       (simplify_binary_expression): Likewise.
+       (simplify_unary_expression): Likewise.
+       (vn_lookup_simplify_result): New hook.
+       (visit_copy): Adjust.
+       (visit_reference_op_call): Likewise.
+       (visit_phi): Likewise.
+       (visit_use): Likewise.
+       (process_scc): Likewise.
+       (init_scc_vn): Likewise.
+       (visit_reference_op_load): Likewise.  Use match-and-simplify and
+       a gimple seq for inserted expressions.
+       (try_to_simplify): Remove GENERIC stmt combining code.
+       (sccvn_dom_walker::before_dom_children): Use match-and-simplify.
+       * tree-ssa-pre.c (eliminate_insert): Adjust.
+       (eliminate_dom_walker::before_dom_children): Likewise.
+
 2015-10-01  Segher Boessenkool  <segher@kernel.crashing.org>
 
        * doc/invoke.texi (Optimization Options): Add
index 51309f2da61ae1721aa0bb2b910eff4906d4d514..9f5e4e99a2c7cbff9f748ea58751ccc0bfa4b03c 100644 (file)
@@ -4877,22 +4877,28 @@ gimple_fold_stmt_to_constant_1 (gimple *stmt, tree (*valueize) (tree),
      edges if there are intermediate VARYING defs.  For this reason
      do not follow SSA edges here even though SCCVN can technically
      just deal fine with that.  */
-  if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize, valueize)
-      && rcode.is_tree_code ()
-      && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
-         || ((tree_code) rcode) == ADDR_EXPR)
-      && is_gimple_val (ops[0]))
-    {
-      tree res = ops[0];
-      if (dump_file && dump_flags & TDF_DETAILS)
+  if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize, valueize))
+    {
+      tree res = NULL_TREE;
+      if (rcode.is_tree_code ()
+         && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
+             || ((tree_code) rcode) == ADDR_EXPR)
+         && is_gimple_val (ops[0]))
+       res = ops[0];
+      else if (mprts_hook)
+       res = mprts_hook (rcode, gimple_expr_type (stmt), ops);
+      if (res)
        {
-         fprintf (dump_file, "Match-and-simplified ");
-         print_gimple_expr (dump_file, stmt, 0, TDF_SLIM);
-         fprintf (dump_file, " to ");
-         print_generic_expr (dump_file, res, 0);
-         fprintf (dump_file, "\n");
+         if (dump_file && dump_flags & TDF_DETAILS)
+           {
+             fprintf (dump_file, "Match-and-simplified ");
+             print_gimple_expr (dump_file, stmt, 0, TDF_SLIM);
+             fprintf (dump_file, " to ");
+             print_generic_expr (dump_file, res, 0);
+             fprintf (dump_file, "\n");
+           }
+         return res;
        }
-      return res;
     }
 
   location_t loc = gimple_location (stmt);
index 0587ce14019a8f40e7413f821b0681df7aeb5460..cab77a4e18db931e2df5a1f1e7f09eab5a48966f 100644 (file)
@@ -293,6 +293,8 @@ maybe_build_generic_op (enum tree_code code, tree type,
     }
 }
 
+tree (*mprts_hook) (code_helper, tree, tree *);
+
 /* Push the exploded expression described by RCODE, TYPE and OPS
    as a statement to SEQ if necessary and return a gimple value
    denoting the value of the expression.  If RES is not NULL
@@ -310,6 +312,12 @@ maybe_push_res_to_seq (code_helper rcode, tree type, tree *ops,
              || ((tree_code) rcode) == ADDR_EXPR)
          && is_gimple_val (ops[0]))
        return ops[0];
+      if (mprts_hook)
+       {
+         tree tem = mprts_hook (rcode, type, ops);
+         if (tem)
+           return tem;
+       }
       if (!seq)
        return NULL_TREE;
       /* Play safe and do not allow abnormals to be mentioned in
index 9e58755defb521f948e342b647d723eb0c6b7d5e..4663a34b8f9d0ede5a5cb4cbd1b94d5b7b5e8736 100644 (file)
@@ -40,6 +40,8 @@ private:
   int rep;
 };
 
+extern tree (*mprts_hook) (code_helper, tree, tree *);
+
 bool gimple_simplify (gimple *, code_helper *, tree *, gimple_seq *,
                      tree (*)(tree), tree (*)(tree));
 tree maybe_push_res_to_seq (code_helper, tree, tree *,
index 46f355aa993687bfc82977403e60c9c9a4b272f8..a8a3481389abfcf55185f26771f165df9a05f527 100644 (file)
@@ -1,3 +1,8 @@
+2015-10-01  Richard Biener  <rguenther@suse.de>
+
+       * gcc.dg/tree-ssa/ssa-fre-7.c: Adjust.
+       * gcc.dg/tree-ssa/ssa-fre-8.c: Likewise.
+
 2015-09-30  Jeff Law  <law@redhat.com>
 
        * gcc.dg/tree-ssa/ssa-dom-branch-1.c: New test.
index 9a555f14b399a654f9f1b100d15f19efd1b843ec..2b2353172cfc23e196a5cc43d33914f5d3d3a368 100644 (file)
@@ -29,8 +29,8 @@ intflt foo(intflt j)
   return a.u.k;
 }
 
-/* { dg-final { scan-tree-dump-times "Inserted pretmp" 1 "fre1" } } */
-/* { dg-final { scan-tree-dump-times "Replaced a.u.f with pretmp" 3 "fre1" } } */
+/* { dg-final { scan-tree-dump-times "Inserted" 1 "fre1" } } */
+/* { dg-final { scan-tree-dump-times "Replaced a.u.f with" 3 "fre1" } } */
 /* { dg-final { scan-tree-dump-times "Replaced a.u.k with j" 1 "fre1" } } */
 /* { dg-final { scan-tree-dump "= VIEW_CONVERT_EXPR<float>\\\(j_" "fre1" } } */
 /* { dg-final { scan-tree-dump "return j" "optimized" } } */
index c04f69927de14be041e10a80f6405402b1edf57c..1a537d8beeaf8b8b2ce920a4792bad91ab11e540 100644 (file)
@@ -28,5 +28,5 @@ intflt foo(int i, int b)
     }
 }
 
-/* { dg-final { scan-tree-dump-times "Replaced u.f with pretmp" 2 "fre1" } } */
-/* { dg-final { scan-tree-dump-times "Inserted pretmp" 2 "fre1" } } */
+/* { dg-final { scan-tree-dump-times "Replaced u.f with" 2 "fre1" } } */
+/* { dg-final { scan-tree-dump-times "Inserted" 2 "fre1" } } */
index ac298d3cabd052d00944eba7ea077ce6eab99c63..f8feaa19c16ba9414951a408e57b4a67b099b5b1 100644 (file)
@@ -3945,21 +3945,23 @@ eliminate_push_avail (tree op)
 static tree
 eliminate_insert (gimple_stmt_iterator *gsi, tree val)
 {
-  tree expr = vn_get_expr_for (val);
-  if (!CONVERT_EXPR_P (expr)
-      && TREE_CODE (expr) != VIEW_CONVERT_EXPR)
+  gimple *stmt = gimple_seq_first_stmt (VN_INFO (val)->expr);
+  if (!is_gimple_assign (stmt)
+      || (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
+         && gimple_assign_rhs_code (stmt) != VIEW_CONVERT_EXPR))
     return NULL_TREE;
 
-  tree op = TREE_OPERAND (expr, 0);
+  tree op = gimple_assign_rhs1 (stmt);
+  if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)
+    op = TREE_OPERAND (op, 0);
   tree leader = TREE_CODE (op) == SSA_NAME ? eliminate_avail (op) : op;
   if (!leader)
     return NULL_TREE;
 
-  tree res = make_temp_ssa_name (TREE_TYPE (val), NULL, "pretmp");
-  gassign *tem = gimple_build_assign (res,
-                                     fold_build1 (TREE_CODE (expr),
-                                                  TREE_TYPE (expr), leader));
-  gsi_insert_before (gsi, tem, GSI_SAME_STMT);
+  gimple_seq stmts = NULL;
+  tree res = gimple_build (&stmts, gimple_assign_rhs_code (stmt),
+                          TREE_TYPE (val), leader);
+  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   VN_INFO_GET (res)->valnum = val;
 
   if (TREE_CODE (leader) == SSA_NAME)
@@ -3969,7 +3971,7 @@ eliminate_insert (gimple_stmt_iterator *gsi, tree val)
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
       fprintf (dump_file, "Inserted ");
-      print_gimple_stmt (dump_file, tem, 0, 0);
+      print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (res), 0, 0);
     }
 
   return res;
@@ -4093,7 +4095,7 @@ eliminate_dom_walker::before_dom_children (basic_block b)
              if (val != VN_TOP
                  && TREE_CODE (val) == SSA_NAME
                  && VN_INFO (val)->needs_insertion
-                 && VN_INFO (val)->expr != NULL_TREE
+                 && VN_INFO (val)->expr != NULL
                  && (sprime = eliminate_insert (&gsi, val)) != NULL_TREE)
                eliminate_push_avail (sprime);
            }
index 5b06d29f62205bf3e0c568169a1ec913d60b6ca7..9db5a7fc0ec1b13d1207f36a56305c677c247d9e 100644 (file)
@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "domwalk.h"
 #include "cgraph.h"
 #include "gimple-iterator.h"
+#include "gimple-match.h"
 
 /* This algorithm is based on the SCC algorithm presented by Keith
    Cooper and L. Taylor Simpson in "SCC-Based Value numbering"
@@ -391,6 +392,8 @@ VN_INFO_GET (tree name)
 {
   vn_ssa_aux_t newinfo;
 
+  gcc_assert (SSA_NAME_VERSION (name) >= vn_ssa_aux_table.length ()
+             || vn_ssa_aux_table[SSA_NAME_VERSION (name)] == NULL);
   newinfo = XOBNEW (&vn_ssa_aux_obstack, struct vn_ssa_aux);
   memset (newinfo, 0, sizeof (struct vn_ssa_aux));
   if (SSA_NAME_VERSION (name) >= vn_ssa_aux_table.length ())
@@ -400,92 +403,6 @@ VN_INFO_GET (tree name)
 }
 
 
-/* Get the representative expression for the SSA_NAME NAME.  Returns
-   the representative SSA_NAME if there is no expression associated with it.  */
-
-tree
-vn_get_expr_for (tree name)
-{
-  vn_ssa_aux_t vn = VN_INFO (name);
-  gimple *def_stmt;
-  tree expr = NULL_TREE;
-  enum tree_code code;
-
-  if (vn->valnum == VN_TOP)
-    return name;
-
-  /* If the value-number is a constant it is the representative
-     expression.  */
-  if (TREE_CODE (vn->valnum) != SSA_NAME)
-    return vn->valnum;
-
-  /* Get to the information of the value of this SSA_NAME.  */
-  vn = VN_INFO (vn->valnum);
-
-  /* If the value-number is a constant it is the representative
-     expression.  */
-  if (TREE_CODE (vn->valnum) != SSA_NAME)
-    return vn->valnum;
-
-  /* Else if we have an expression, return it.  */
-  if (vn->expr != NULL_TREE)
-    return vn->expr;
-
-  /* Otherwise use the defining statement to build the expression.  */
-  def_stmt = SSA_NAME_DEF_STMT (vn->valnum);
-
-  /* If the value number is not an assignment use it directly.  */
-  if (!is_gimple_assign (def_stmt))
-    return vn->valnum;
-
-  /* Note that we can valueize here because we clear the cached
-     simplified expressions after each optimistic iteration.  */
-  code = gimple_assign_rhs_code (def_stmt);
-  switch (TREE_CODE_CLASS (code))
-    {
-    case tcc_reference:
-      if ((code == REALPART_EXPR
-          || code == IMAGPART_EXPR
-          || code == VIEW_CONVERT_EXPR)
-         && TREE_CODE (TREE_OPERAND (gimple_assign_rhs1 (def_stmt),
-                                     0)) == SSA_NAME)
-       expr = fold_build1 (code,
-                           gimple_expr_type (def_stmt),
-                           vn_valueize (TREE_OPERAND
-                                          (gimple_assign_rhs1 (def_stmt), 0)));
-      break;
-
-    case tcc_unary:
-      expr = fold_build1 (code,
-                         gimple_expr_type (def_stmt),
-                         vn_valueize (gimple_assign_rhs1 (def_stmt)));
-      break;
-
-    case tcc_binary:
-      expr = fold_build2 (code,
-                         gimple_expr_type (def_stmt),
-                         vn_valueize (gimple_assign_rhs1 (def_stmt)),
-                         vn_valueize (gimple_assign_rhs2 (def_stmt)));
-      break;
-
-    case tcc_exceptional:
-      if (code == CONSTRUCTOR
-         && TREE_CODE
-              (TREE_TYPE (gimple_assign_rhs1 (def_stmt))) == VECTOR_TYPE)
-       expr = gimple_assign_rhs1 (def_stmt);
-      break;
-
-    default:;
-    }
-  if (expr == NULL_TREE)
-    return vn->valnum;
-
-  /* Cache the expression.  */
-  vn->expr = expr;
-
-  return expr;
-}
-
 /* Return the vn_kind the expression computed by the stmt should be
    associated with.  */
 
@@ -2629,6 +2546,18 @@ vn_nary_op_lookup_stmt (gimple *stmt, vn_nary_op_t *vnresult)
   return vn_nary_op_lookup_1 (vno1, vnresult);
 }
 
+/* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables.  */
+
+static tree
+vn_lookup_simplify_result (code_helper rcode, tree type, tree *ops)
+{
+  if (!rcode.is_tree_code ())
+    return NULL_TREE;
+  vn_nary_op_t vnresult = NULL;
+  return vn_nary_op_lookup_pieces (TREE_CODE_LENGTH ((tree_code) rcode),
+                                  (tree_code) rcode, type, ops, &vnresult);
+}
+
 /* Allocate a vn_nary_op_t with LENGTH operands on STACK.  */
 
 static vn_nary_op_t
@@ -2991,20 +2920,13 @@ defs_to_varying (gimple *stmt)
   return changed;
 }
 
-static bool expr_has_constants (tree expr);
-
 /* Visit a copy between LHS and RHS, return true if the value number
    changed.  */
 
 static bool
 visit_copy (tree lhs, tree rhs)
 {
-  /* The copy may have a more interesting constant filled expression
-     (we don't, since we know our RHS is just an SSA name).  */
-  VN_INFO (lhs)->has_constants = VN_INFO (rhs)->has_constants;
-  VN_INFO (lhs)->expr = VN_INFO (rhs)->expr;
-
-  /* And finally valueize.  */
+  /* Valueize.  */
   rhs = SSA_VAL (rhs);
 
   return set_ssa_val_to (lhs, rhs);
@@ -3055,12 +2977,7 @@ visit_reference_op_call (tree lhs, gcall *stmt)
        vnresult->result = lhs;
 
       if (vnresult->result && lhs)
-       {
-         changed |= set_ssa_val_to (lhs, vnresult->result);
-
-         if (VN_INFO (vnresult->result)->has_constants)
-           VN_INFO (lhs)->has_constants = true;
-       }
+       changed |= set_ssa_val_to (lhs, vnresult->result);
     }
   else
     {
@@ -3116,33 +3033,38 @@ visit_reference_op_load (tree lhs, tree op, gimple *stmt)
         of VIEW_CONVERT_EXPR <TREE_TYPE (result)> (result).
         So first simplify and lookup this expression to see if it
         is already available.  */
-      tree val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (op), result);
-      if ((CONVERT_EXPR_P (val)
-          || TREE_CODE (val) == VIEW_CONVERT_EXPR)
-         && TREE_CODE (TREE_OPERAND (val, 0)) == SSA_NAME)
-        {
-         tree tem = vn_get_expr_for (TREE_OPERAND (val, 0));
-         if ((CONVERT_EXPR_P (tem)
-              || TREE_CODE (tem) == VIEW_CONVERT_EXPR)
-             && (tem = fold_unary_ignore_overflow (TREE_CODE (val),
-                                                   TREE_TYPE (val), tem)))
-           val = tem;
+      gimple_seq stmts = NULL;
+      mprts_hook = vn_lookup_simplify_result;
+      tree val = gimple_simplify (VIEW_CONVERT_EXPR, TREE_TYPE (op),
+                                 result, &stmts, vn_valueize);
+      mprts_hook = NULL;
+      if (!val)
+       {
+         val = vn_nary_op_lookup_pieces (1, VIEW_CONVERT_EXPR,
+                                         TREE_TYPE (op), &result, NULL);
+         if (!val)
+           {
+             val = make_ssa_name (TREE_TYPE (op));
+             gimple *new_stmt = gimple_build_assign (val, VIEW_CONVERT_EXPR,
+                                                     build1 (VIEW_CONVERT_EXPR,
+                                                             TREE_TYPE (op),
+                                                             result));
+             gimple_seq_add_stmt_without_update (&stmts, new_stmt);
+           }
        }
-      result = val;
-      if (!is_gimple_min_invariant (val)
-         && TREE_CODE (val) != SSA_NAME)
-       result = vn_nary_op_lookup (val, NULL);
-      /* If the expression is not yet available, value-number lhs to
-        a new SSA_NAME we create.  */
-      if (!result)
-        {
-         result = make_temp_ssa_name (TREE_TYPE (lhs), gimple_build_nop (),
-                                      "vntemp");
+      if (gimple_seq_empty_p (stmts))
+       /* The expression is already available.  */
+       result = val;
+      else
+       {
+         gcc_assert (gimple_seq_singleton_p (stmts));
+         /* The expression is not yet available, value-number lhs to
+            the new SSA_NAME we created.  */
+         result = val;
          /* Initialize value-number information properly.  */
          VN_INFO_GET (result)->valnum = result;
          VN_INFO (result)->value_id = get_next_value_id ();
-         VN_INFO (result)->expr = val;
-         VN_INFO (result)->has_constants = expr_has_constants (val);
+         VN_INFO (result)->expr = stmts;
          VN_INFO (result)->needs_insertion = true;
          /* As all "inserted" statements are singleton SCCs, insert
             to the valid table.  This is strictly needed to
@@ -3154,32 +3076,25 @@ visit_reference_op_load (tree lhs, tree op, gimple *stmt)
          if (current_info == optimistic_info)
            {
              current_info = valid_info;
-             vn_nary_op_insert (val, result);
+             vn_nary_op_insert_stmt (gimple_seq_first_stmt (stmts), result);
              current_info = optimistic_info;
            }
          else
-           vn_nary_op_insert (val, result);
+           vn_nary_op_insert_stmt (gimple_seq_first_stmt (stmts), result);
          if (dump_file && (dump_flags & TDF_DETAILS))
            {
              fprintf (dump_file, "Inserting name ");
              print_generic_expr (dump_file, result, 0);
              fprintf (dump_file, " for expression ");
-             print_generic_expr (dump_file, val, 0);
+             print_gimple_expr (dump_file, gimple_seq_first_stmt (stmts),
+                                0, TDF_SLIM);
              fprintf (dump_file, "\n");
            }
        }
     }
 
   if (result)
-    {
-      changed = set_ssa_val_to (lhs, result);
-      if (TREE_CODE (result) == SSA_NAME
-         && VN_INFO (result)->has_constants)
-       {
-         VN_INFO (lhs)->expr = VN_INFO (result)->expr;
-         VN_INFO (lhs)->has_constants = true;
-       }
-    }
+    changed = set_ssa_val_to (lhs, result);
   else
     {
       changed = set_ssa_val_to (lhs, lhs);
@@ -3346,208 +3261,12 @@ visit_phi (gimple *phi)
   else
     {
       vn_phi_insert (phi, PHI_RESULT (phi));
-      VN_INFO (PHI_RESULT (phi))->has_constants = false;
-      VN_INFO (PHI_RESULT (phi))->expr = PHI_RESULT (phi);
       changed = set_ssa_val_to (PHI_RESULT (phi), PHI_RESULT (phi));
     }
 
   return changed;
 }
 
-/* Return true if EXPR contains constants.  */
-
-static bool
-expr_has_constants (tree expr)
-{
-  switch (TREE_CODE_CLASS (TREE_CODE (expr)))
-    {
-    case tcc_unary:
-      return is_gimple_min_invariant (TREE_OPERAND (expr, 0));
-
-    case tcc_binary:
-      return is_gimple_min_invariant (TREE_OPERAND (expr, 0))
-       || is_gimple_min_invariant (TREE_OPERAND (expr, 1));
-      /* 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);
-    }
-  return false;
-}
-
-/* Return true if STMT contains constants.  */
-
-static bool
-stmt_has_constants (gimple *stmt)
-{
-  tree tem;
-
-  if (gimple_code (stmt) != GIMPLE_ASSIGN)
-    return false;
-
-  switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
-    {
-    case GIMPLE_TERNARY_RHS:
-      tem = gimple_assign_rhs3 (stmt);
-      if (TREE_CODE (tem) == SSA_NAME)
-       tem = SSA_VAL (tem);
-      if (is_gimple_min_invariant (tem))
-       return true;
-      /* Fallthru.  */
-
-    case GIMPLE_BINARY_RHS:
-      tem = gimple_assign_rhs2 (stmt);
-      if (TREE_CODE (tem) == SSA_NAME)
-       tem = SSA_VAL (tem);
-      if (is_gimple_min_invariant (tem))
-       return true;
-      /* Fallthru.  */
-
-    case GIMPLE_SINGLE_RHS:
-      /* Constants inside reference ops are rarely interesting, but
-        it can take a lot of looking to find them.  */
-    case GIMPLE_UNARY_RHS:
-      tem = gimple_assign_rhs1 (stmt);
-      if (TREE_CODE (tem) == SSA_NAME)
-       tem = SSA_VAL (tem);
-      return is_gimple_min_invariant (tem);
-
-    default:
-      gcc_unreachable ();
-    }
-  return false;
-}
-
-/* Simplify the binary expression RHS, and return the result if
-   simplified. */
-
-static tree
-simplify_binary_expression (gimple *stmt)
-{
-  tree result = NULL_TREE;
-  tree op0 = gimple_assign_rhs1 (stmt);
-  tree op1 = gimple_assign_rhs2 (stmt);
-  enum tree_code code = gimple_assign_rhs_code (stmt);
-
-  /* This will not catch every single case we could combine, but will
-     catch those with constants.  The goal here is to simultaneously
-     combine constants between expressions, but avoid infinite
-     expansion of expressions during simplification.  */
-  op0 = vn_valueize (op0);
-  if (TREE_CODE (op0) == SSA_NAME
-      && (VN_INFO (op0)->has_constants
-         || TREE_CODE_CLASS (code) == tcc_comparison
-         || code == COMPLEX_EXPR))
-    op0 = vn_get_expr_for (op0);
-
-  op1 = vn_valueize (op1);
-  if (TREE_CODE (op1) == SSA_NAME
-      && (VN_INFO (op1)->has_constants
-         || code == COMPLEX_EXPR))
-    op1 = vn_get_expr_for (op1);
-
-  /* Pointer plus constant can be represented as invariant address.
-     Do so to allow further propatation, see also tree forwprop.  */
-  if (code == POINTER_PLUS_EXPR
-      && tree_fits_uhwi_p (op1)
-      && TREE_CODE (op0) == ADDR_EXPR
-      && is_gimple_min_invariant (op0))
-    return build_invariant_address (TREE_TYPE (op0),
-                                   TREE_OPERAND (op0, 0),
-                                   tree_to_uhwi (op1));
-
-  /* Avoid folding if nothing changed.  */
-  if (op0 == gimple_assign_rhs1 (stmt)
-      && op1 == gimple_assign_rhs2 (stmt))
-    return NULL_TREE;
-
-  fold_defer_overflow_warnings ();
-
-  result = fold_binary (code, gimple_expr_type (stmt), op0, op1);
-  if (result)
-    STRIP_USELESS_TYPE_CONVERSION (result);
-
-  fold_undefer_overflow_warnings (result && valid_gimple_rhs_p (result),
-                                 stmt, 0);
-
-  /* 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 && valid_gimple_rhs_p (result))
-    return result;
-
-  return NULL_TREE;
-}
-
-/* Simplify the unary expression RHS, and return the result if
-   simplified. */
-
-static tree
-simplify_unary_expression (gassign *stmt)
-{
-  tree result = NULL_TREE;
-  tree orig_op0, op0 = gimple_assign_rhs1 (stmt);
-  enum tree_code code = gimple_assign_rhs_code (stmt);
-
-  /* We handle some tcc_reference codes here that are all
-     GIMPLE_ASSIGN_SINGLE codes.  */
-  if (code == REALPART_EXPR
-      || code == IMAGPART_EXPR
-      || code == VIEW_CONVERT_EXPR
-      || code == BIT_FIELD_REF)
-    op0 = TREE_OPERAND (op0, 0);
-
-  orig_op0 = op0;
-  op0 = vn_valueize (op0);
-  if (TREE_CODE (op0) == SSA_NAME)
-    {
-      if (VN_INFO (op0)->has_constants)
-       op0 = vn_get_expr_for (op0);
-      else if (CONVERT_EXPR_CODE_P (code)
-              || code == REALPART_EXPR
-              || code == IMAGPART_EXPR
-              || code == VIEW_CONVERT_EXPR
-              || code == BIT_FIELD_REF)
-       {
-         /* We want to do tree-combining on conversion-like expressions.
-            Make sure we feed only SSA_NAMEs or constants to fold though.  */
-         tree tem = vn_get_expr_for (op0);
-         if (UNARY_CLASS_P (tem)
-             || BINARY_CLASS_P (tem)
-             || TREE_CODE (tem) == VIEW_CONVERT_EXPR
-             || TREE_CODE (tem) == SSA_NAME
-             || TREE_CODE (tem) == CONSTRUCTOR
-             || is_gimple_min_invariant (tem))
-           op0 = tem;
-       }
-    }
-
-  /* Avoid folding if nothing changed, but remember the expression.  */
-  if (op0 == orig_op0)
-    return NULL_TREE;
-
-  if (code == BIT_FIELD_REF)
-    {
-      tree rhs = gimple_assign_rhs1 (stmt);
-      result = fold_ternary (BIT_FIELD_REF, TREE_TYPE (rhs),
-                            op0, TREE_OPERAND (rhs, 1), TREE_OPERAND (rhs, 2));
-    }
-  else
-    result = fold_unary_ignore_overflow (code, gimple_expr_type (stmt), op0);
-  if (result)
-    {
-      STRIP_USELESS_TYPE_CONVERSION (result);
-      if (valid_gimple_rhs_p (result))
-        return result;
-    }
-
-  return NULL_TREE;
-}
-
 /* Try to simplify RHS using equivalences and constant folding.  */
 
 static tree
@@ -3562,35 +3281,14 @@ try_to_simplify (gassign *stmt)
     return NULL_TREE;
 
   /* First try constant folding based on our current lattice.  */
+  mprts_hook = vn_lookup_simplify_result;
   tem = gimple_fold_stmt_to_constant_1 (stmt, vn_valueize, vn_valueize);
+  mprts_hook = NULL;
   if (tem
       && (TREE_CODE (tem) == SSA_NAME
          || is_gimple_min_invariant (tem)))
     return tem;
 
-  /* If that didn't work try combining multiple statements.  */
-  switch (TREE_CODE_CLASS (code))
-    {
-    case tcc_reference:
-      /* Fallthrough for some unary codes that can operate on registers.  */
-      if (!(code == REALPART_EXPR
-           || code == IMAGPART_EXPR
-           || code == VIEW_CONVERT_EXPR
-           || code == BIT_FIELD_REF))
-       break;
-      /* We could do a little more with unary ops, if they expand
-        into binary ops, but it's debatable whether it is worth it. */
-    case tcc_unary:
-      return simplify_unary_expression (stmt);
-
-    case tcc_comparison:
-    case tcc_binary:
-      return simplify_binary_expression (stmt);
-
-    default:
-      break;
-    }
-
   return NULL_TREE;
 }
 
@@ -3648,11 +3346,7 @@ visit_use (tree use)
                  print_gimple_expr (dump_file, stmt, 0, 0);
                  fprintf (dump_file, " simplified to ");
                  print_generic_expr (dump_file, simplified, 0);
-                 if (TREE_CODE (lhs) == SSA_NAME)
-                   fprintf (dump_file, " has constants %d\n",
-                            expr_has_constants (simplified));
-                 else
-                   fprintf (dump_file, "\n");
+                 fprintf (dump_file, "\n");
                }
            }
          /* Setting value numbers to constants will occasionally
@@ -3663,8 +3357,6 @@ visit_use (tree use)
              && is_gimple_min_invariant (simplified)
              && TREE_CODE (lhs) == SSA_NAME)
            {
-             VN_INFO (lhs)->expr = simplified;
-             VN_INFO (lhs)->has_constants = true;
              changed = set_ssa_val_to (lhs, simplified);
              goto done;
            }
@@ -3675,29 +3367,6 @@ visit_use (tree use)
              changed = visit_copy (lhs, simplified);
              goto done;
            }
-         else if (simplified)
-           {
-             if (TREE_CODE (lhs) == SSA_NAME)
-               {
-                 VN_INFO (lhs)->has_constants = expr_has_constants (simplified);
-                 /* We have to unshare the expression or else
-                    valuizing may change the IL stream.  */
-                 VN_INFO (lhs)->expr = unshare_expr (simplified);
-               }
-           }
-         else if (stmt_has_constants (stmt)
-                  && TREE_CODE (lhs) == SSA_NAME)
-           VN_INFO (lhs)->has_constants = true;
-         else if (TREE_CODE (lhs) == SSA_NAME)
-           {
-             /* We reset expr and constantness here because we may
-                have been value numbering optimistically, and
-                iterating. They may become non-constant in this case,
-                even if they were optimistically constant. */
-
-             VN_INFO (lhs)->has_constants = false;
-             VN_INFO (lhs)->expr = NULL_TREE;
-           }
 
          if ((TREE_CODE (lhs) == SSA_NAME
               /* We can substitute SSA_NAMEs that are live over
@@ -3722,7 +3391,6 @@ visit_use (tree use)
                  || (simplified
                      && is_gimple_min_invariant (simplified)))
                {
-                 VN_INFO (lhs)->has_constants = true;
                  if (simplified)
                    changed = set_ssa_val_to (lhs, simplified);
                  else
@@ -3785,11 +3453,7 @@ visit_use (tree use)
                      print_gimple_expr (dump_file, stmt, 0, 0);
                      fprintf (dump_file, " simplified to ");
                      print_generic_expr (dump_file, simplified, 0);
-                     if (TREE_CODE (lhs) == SSA_NAME)
-                       fprintf (dump_file, " has constants %d\n",
-                                expr_has_constants (simplified));
-                     else
-                       fprintf (dump_file, "\n");
+                     fprintf (dump_file, "\n");
                    }
                }
              /* Setting value numbers to constants will occasionally
@@ -3799,8 +3463,6 @@ visit_use (tree use)
              if (simplified
                  && is_gimple_min_invariant (simplified))
                {
-                 VN_INFO (lhs)->expr = simplified;
-                 VN_INFO (lhs)->has_constants = true;
                  changed = set_ssa_val_to (lhs, simplified);
                  if (gimple_vdef (stmt))
                    changed |= set_ssa_val_to (gimple_vdef (stmt),
@@ -3818,18 +3480,6 @@ visit_use (tree use)
                }
              else
                {
-                 if (stmt_has_constants (stmt))
-                   VN_INFO (lhs)->has_constants = true;
-                 else
-                   {
-                     /* We reset expr and constantness here because we may
-                        have been value numbering optimistically, and
-                        iterating.  They may become non-constant in this case,
-                        even if they were optimistically constant.  */
-                     VN_INFO (lhs)->has_constants = false;
-                     VN_INFO (lhs)->expr = NULL_TREE;
-                   }
-
                  if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
                    {
                      changed = defs_to_varying (stmt);
@@ -4028,7 +3678,8 @@ process_scc (vec<tree> scc)
       optimistic_info->phis_pool->release ();
       optimistic_info->references_pool->release ();
       FOR_EACH_VEC_ELT (scc, i, var)
-       VN_INFO (var)->expr = NULL_TREE;
+       gcc_assert (!VN_INFO (var)->needs_insertion
+                   && VN_INFO (var)->expr == NULL);
       FOR_EACH_VEC_ELT (scc, i, var)
        changed |= visit_use (var);
     }
@@ -4283,7 +3934,8 @@ init_scc_vn (void)
        continue;
 
       VN_INFO_GET (name)->valnum = VN_TOP;
-      VN_INFO (name)->expr = NULL_TREE;
+      VN_INFO (name)->needs_insertion = false;
+      VN_INFO (name)->expr = NULL;
       VN_INFO (name)->value_id = 0;
 
       if (!SSA_NAME_IS_DEFAULT_DEF (name))
@@ -4638,23 +4290,18 @@ sccvn_dom_walker::before_dom_children (basic_block bb)
     {
     case GIMPLE_COND:
       {
-       tree lhs = gimple_cond_lhs (stmt);
-       tree rhs = gimple_cond_rhs (stmt);
-       /* Work hard in computing the condition and take into account
-          the valueization of the defining stmt.  */
-       if (TREE_CODE (lhs) == SSA_NAME)
-         lhs = vn_get_expr_for (lhs);
-       if (TREE_CODE (rhs) == SSA_NAME)
-         rhs = vn_get_expr_for (rhs);
-       val = fold_binary (gimple_cond_code (stmt),
-                          boolean_type_node, lhs, rhs);
+       tree lhs = vn_valueize (gimple_cond_lhs (stmt));
+       tree rhs = vn_valueize (gimple_cond_rhs (stmt));
+       val = gimple_simplify (gimple_cond_code (stmt),
+                              boolean_type_node, lhs, rhs,
+                              NULL, vn_valueize);
        /* If that didn't simplify to a constant see if we have recorded
           temporary expressions from taken edges.  */
        if (!val || TREE_CODE (val) != INTEGER_CST)
          {
            tree ops[2];
-           ops[0] = gimple_cond_lhs (stmt);
-           ops[1] = gimple_cond_rhs (stmt);
+           ops[0] = lhs;
+           ops[1] = rhs;
            val = vn_nary_op_lookup_pieces (2, gimple_cond_code (stmt),
                                            boolean_type_node, ops, NULL);
          }
index d0a911fc0ea122dd2b7eb4d2aab08b676505372f..c8b918aa4e998c137f9dfa4be6b8e5a2481ffcbf 100644 (file)
@@ -165,8 +165,8 @@ typedef struct vn_ssa_aux
 {
   /* Value number. This may be an SSA name or a constant.  */
   tree valnum;
-  /* Representative expression, if not a direct constant. */
-  tree expr;
+  /* Statements to insert if needs_insertion is true.  */
+  gimple_seq expr;
 
   /* Unique identifier that all expressions with the same value have. */
   unsigned int value_id;
@@ -177,8 +177,6 @@ typedef struct vn_ssa_aux
   unsigned visited : 1;
   unsigned on_sccstack : 1;
 
-  /* Whether the representative expression contains constants.  */
-  unsigned has_constants : 1;
   /* Whether the SSA_NAME has been value numbered already.  This is
      only saying whether visit_use has been called on it at least
      once.  It cannot be used to avoid visitation for SSA_NAME's