gimple-fold.c (replace_stmt_with_simplification): Special-case valueizing call operands.
authorRichard Biener <rguenther@suse.de>
Fri, 24 Jul 2015 08:25:41 +0000 (08:25 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 24 Jul 2015 08:25:41 +0000 (08:25 +0000)
2015-07-24  Richard Biener  <rguenther@suse.de>

* gimple-fold.c (replace_stmt_with_simplification): Special-case
valueizing call operands.
* gimple-match-head.c (maybe_push_res_to_seq): Take
number of call arguments from ops array.
(do_valueize): New function.
(gimple_simplify): Return true if valueization changed
any operand even if the result didn't simplify further.

From-SVN: r226139

gcc/ChangeLog
gcc/gimple-fold.c
gcc/gimple-match-head.c

index 075c0fd4d96f0b87787706e1747feeb385d9c4dd..47f7237d224ff7d51b2c80a27aa65a1085610c4e 100644 (file)
@@ -1,3 +1,13 @@
+2015-07-24  Richard Biener  <rguenther@suse.de>
+
+       * gimple-fold.c (replace_stmt_with_simplification): Special-case
+       valueizing call operands.
+       * gimple-match-head.c (maybe_push_res_to_seq): Take
+       number of call arguments from ops array.
+       (do_valueize): New function.
+       (gimple_simplify): Return true if valueization changed
+       any operand even if the result didn't simplify further.
+
 2015-07-24  Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>
 
        PR middle-end/25530
index 2909c42ef19a6dd8454232fc3194a9e53d9b9c7d..64f27917e6152c763294d401ed9d6a877b57e73f 100644 (file)
@@ -3398,6 +3398,19 @@ replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
          return true;
        }
     }
+  else if (rcode.is_fn_code ()
+          && gimple_call_builtin_p (stmt, rcode))
+    {
+      unsigned i;
+      for (i = 0; i < gimple_call_num_args (stmt); ++i)
+       {
+         gcc_assert (ops[i] != NULL_TREE);
+         gimple_call_set_arg (stmt, i, ops[i]);
+       }
+      if (i < 3)
+       gcc_assert (ops[i] == NULL_TREE);
+      return true;
+    }
   else if (!inplace)
     {
       if (gimple_has_lhs (stmt))
index 2c66dccb26024ce3de62024801b3f112d11af26e..ca7acdfb4a427b5b3db8d123b46ae9ebd3f0f802 100644 (file)
@@ -338,19 +338,18 @@ maybe_push_res_to_seq (code_helper rcode, tree type, tree *ops,
       tree decl = builtin_decl_implicit (rcode);
       if (!decl)
        return NULL_TREE;
-      unsigned nargs = type_num_arguments (TREE_TYPE (decl));
-      gcc_assert (nargs <= 3);
       /* Play safe and do not allow abnormals to be mentioned in
          newly created statements.  */
-      if ((TREE_CODE (ops[0]) == SSA_NAME
-          && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
-         || (nargs >= 2
-             && TREE_CODE (ops[1]) == SSA_NAME
-             && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
-         || (nargs == 3
-             && TREE_CODE (ops[2]) == SSA_NAME
-             && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
-       return NULL_TREE;
+      unsigned nargs;
+      for (nargs = 0; nargs < 3; ++nargs)
+       {
+         if (!ops[nargs])
+           break;
+         if (TREE_CODE (ops[nargs]) == SSA_NAME
+             && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[nargs]))
+           return NULL_TREE;
+       }
+      gcc_assert (nargs != 0);
       if (!res)
        res = make_ssa_name (type);
       gimple new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1], ops[2]);
@@ -563,6 +562,23 @@ gimple_simplify (enum built_in_function fn, tree type,
   return maybe_push_res_to_seq (rcode, type, ops, seq);
 }
 
+/* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
+   VALUEIZED to true if valueization changed OP.  */
+
+static inline tree
+do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
+{
+  if (valueize && TREE_CODE (op) == SSA_NAME)
+    {
+      tree tem = valueize (op);
+      if (tem && tem != op)
+       {
+         op = tem;
+         valueized = true;
+       }
+    }
+  return op;
+}
 
 /* The main STMT based simplification entry.  It is used by the fold_stmt
    and the fold_stmt_to_constant APIs.  */
@@ -587,31 +603,25 @@ gimple_simplify (gimple stmt,
                || code == VIEW_CONVERT_EXPR)
              {
                tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
-               if (top_valueize && TREE_CODE (op0) == SSA_NAME)
-                 {
-                   tree tem = top_valueize (op0);
-                   if (tem)
-                     op0 = tem;
-                 }
+               bool valueized = false;
+               op0 = do_valueize (op0, top_valueize, valueized);
                *rcode = code;
                ops[0] = op0;
-               return gimple_resimplify1 (seq, rcode, type, ops, valueize);
+               return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
+                       || valueized);
              }
            else if (code == BIT_FIELD_REF)
              {
                tree rhs1 = gimple_assign_rhs1 (stmt);
                tree op0 = TREE_OPERAND (rhs1, 0);
-               if (top_valueize && TREE_CODE (op0) == SSA_NAME)
-                 {
-                   tree tem = top_valueize (op0);
-                   if (tem)
-                     op0 = tem;
-                 }
+               bool valueized = false;
+               op0 = do_valueize (op0, top_valueize, valueized);
                *rcode = code;
                ops[0] = op0;
                ops[1] = TREE_OPERAND (rhs1, 1);
                ops[2] = TREE_OPERAND (rhs1, 2);
-               return gimple_resimplify3 (seq, rcode, type, ops, valueize);
+               return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
+                       || valueized);
              }
            else if (code == SSA_NAME
                     && top_valueize)
@@ -628,65 +638,41 @@ gimple_simplify (gimple stmt,
          case GIMPLE_UNARY_RHS:
            {
              tree rhs1 = gimple_assign_rhs1 (stmt);
-             if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
-               {
-                 tree tem = top_valueize (rhs1);
-                 if (tem)
-                   rhs1 = tem;
-               }
+             bool valueized = false;
+             rhs1 = do_valueize (rhs1, top_valueize, valueized);
              *rcode = code;
              ops[0] = rhs1;
-             return gimple_resimplify1 (seq, rcode, type, ops, valueize);
+             return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
+                     || valueized);
            }
          case GIMPLE_BINARY_RHS:
            {
              tree rhs1 = gimple_assign_rhs1 (stmt);
-             if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
-               {
-                 tree tem = top_valueize (rhs1);
-                 if (tem)
-                   rhs1 = tem;
-               }
              tree rhs2 = gimple_assign_rhs2 (stmt);
-             if (top_valueize && TREE_CODE (rhs2) == SSA_NAME)
-               {
-                 tree tem = top_valueize (rhs2);
-                 if (tem)
-                   rhs2 = tem;
-               }
+             bool valueized = false;
+             rhs1 = do_valueize (rhs1, top_valueize, valueized);
+             rhs2 = do_valueize (rhs2, top_valueize, valueized);
              *rcode = code;
              ops[0] = rhs1;
              ops[1] = rhs2;
-             return gimple_resimplify2 (seq, rcode, type, ops, valueize);
+             return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
+                     || valueized);
            }
          case GIMPLE_TERNARY_RHS:
            {
              tree rhs1 = gimple_assign_rhs1 (stmt);
-             if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
-               {
-                 tree tem = top_valueize (rhs1);
-                 if (tem)
-                   rhs1 = tem;
-               }
              tree rhs2 = gimple_assign_rhs2 (stmt);
-             if (top_valueize && TREE_CODE (rhs2) == SSA_NAME)
-               {
-                 tree tem = top_valueize (rhs2);
-                 if (tem)
-                   rhs2 = tem;
-               }
              tree rhs3 = gimple_assign_rhs3 (stmt);
-             if (top_valueize && TREE_CODE (rhs3) == SSA_NAME)
-               {
-                 tree tem = top_valueize (rhs3);
-                 if (tem)
-                   rhs3 = tem;
-               }
+             bool valueized = false;
+             rhs1 = do_valueize (rhs1, top_valueize, valueized);
+             rhs2 = do_valueize (rhs2, top_valueize, valueized);
+             rhs3 = do_valueize (rhs3, top_valueize, valueized);
              *rcode = code;
              ops[0] = rhs1;
              ops[1] = rhs2;
              ops[2] = rhs3;
-             return gimple_resimplify3 (seq, rcode, type, ops, valueize);
+             return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
+                     || valueized);
            }
          default:
            gcc_unreachable ();
@@ -696,96 +682,46 @@ gimple_simplify (gimple stmt,
 
     case GIMPLE_CALL:
       /* ???  This way we can't simplify calls with side-effects.  */
-      if (gimple_call_lhs (stmt) != NULL_TREE)
+      if (gimple_call_lhs (stmt) != NULL_TREE
+         && gimple_call_num_args (stmt) >= 1
+         && gimple_call_num_args (stmt) <= 3)
        {
          tree fn = gimple_call_fn (stmt);
          /* ???  Internal function support missing.  */
          if (!fn)
            return false;
-         if (top_valueize && TREE_CODE (fn) == SSA_NAME)
-           {
-             tree tem = top_valueize (fn);
-             if (tem)
-               fn = tem;
-           }
-         if (!fn
-             || TREE_CODE (fn) != ADDR_EXPR
-             || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL
-             || DECL_BUILT_IN_CLASS (TREE_OPERAND (fn, 0)) != BUILT_IN_NORMAL
-             || !builtin_decl_implicit (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0)))
-             || !gimple_builtin_call_types_compatible_p (stmt,
-                                                         TREE_OPERAND (fn, 0)))
+         bool valueized = false;
+         fn = do_valueize (fn, top_valueize, valueized);
+         if (TREE_CODE (fn) != ADDR_EXPR
+             || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
            return false;
 
          tree decl = TREE_OPERAND (fn, 0);
+         if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL
+             || !builtin_decl_implicit (DECL_FUNCTION_CODE (decl))
+             || !gimple_builtin_call_types_compatible_p (stmt, decl))
+           return false;
+
          tree type = TREE_TYPE (gimple_call_lhs (stmt));
+         *rcode = DECL_FUNCTION_CODE (decl);
+         for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
+           {
+             tree arg = gimple_call_arg (stmt, i);
+             ops[i] = do_valueize (arg, top_valueize, valueized);
+           }
          switch (gimple_call_num_args (stmt))
            {
            case 1:
-             {
-               tree arg1 = gimple_call_arg (stmt, 0);
-               if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
-                 {
-                   tree tem = top_valueize (arg1);
-                   if (tem)
-                     arg1 = tem;
-                 }
-               *rcode = DECL_FUNCTION_CODE (decl);
-               ops[0] = arg1;
-               return gimple_resimplify1 (seq, rcode, type, ops, valueize);
-             }
+             return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
+                     || valueized);
            case 2:
-             {
-               tree arg1 = gimple_call_arg (stmt, 0);
-               if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
-                 {
-                   tree tem = top_valueize (arg1);
-                   if (tem)
-                     arg1 = tem;
-                 }
-               tree arg2 = gimple_call_arg (stmt, 1);
-               if (top_valueize && TREE_CODE (arg2) == SSA_NAME)
-                 {
-                   tree tem = top_valueize (arg2);
-                   if (tem)
-                     arg2 = tem;
-                 }
-               *rcode = DECL_FUNCTION_CODE (decl);
-               ops[0] = arg1;
-               ops[1] = arg2;
-               return gimple_resimplify2 (seq, rcode, type, ops, valueize);
-             }
+             return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
+                     || valueized);
            case 3:
-             {
-               tree arg1 = gimple_call_arg (stmt, 0);
-               if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
-                 {
-                   tree tem = top_valueize (arg1);
-                   if (tem)
-                     arg1 = tem;
-                 }
-               tree arg2 = gimple_call_arg (stmt, 1);
-               if (top_valueize && TREE_CODE (arg2) == SSA_NAME)
-                 {
-                   tree tem = top_valueize (arg2);
-                   if (tem)
-                     arg2 = tem;
-                 }
-               tree arg3 = gimple_call_arg (stmt, 2);
-               if (top_valueize && TREE_CODE (arg3) == SSA_NAME)
-                 {
-                   tree tem = top_valueize (arg3);
-                   if (tem)
-                     arg3 = tem;
-                 }
-               *rcode = DECL_FUNCTION_CODE (decl);
-               ops[0] = arg1;
-               ops[1] = arg2;
-               ops[2] = arg3;
-               return gimple_resimplify3 (seq, rcode, type, ops, valueize);
-             }
+             return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
+                     || valueized);
            default:
-             return false;
+            gcc_unreachable ();
            }
        }
       break;
@@ -793,23 +729,16 @@ gimple_simplify (gimple stmt,
     case GIMPLE_COND:
       {
        tree lhs = gimple_cond_lhs (stmt);
-       if (top_valueize && TREE_CODE (lhs) == SSA_NAME)
-         {
-           tree tem = top_valueize (lhs);
-           if (tem)
-             lhs = tem;
-         }
        tree rhs = gimple_cond_rhs (stmt);
-       if (top_valueize && TREE_CODE (rhs) == SSA_NAME)
-         {
-           tree tem = top_valueize (rhs);
-           if (tem)
-             rhs = tem;
-         }
+       bool valueized = false;
+       lhs = do_valueize (lhs, top_valueize, valueized);
+       rhs = do_valueize (rhs, top_valueize, valueized);
        *rcode = gimple_cond_code (stmt);
        ops[0] = lhs;
        ops[1] = rhs;
-        return gimple_resimplify2 (seq, rcode, boolean_type_node, ops, valueize);
+        return (gimple_resimplify2 (seq, rcode,
+                                   boolean_type_node, ops, valueize)
+               || valueized);
       }
 
     default: