builtins.c (fold_builtin_0): Remove unused ignore parameter.
authorRichard Biener <rguenther@suse.de>
Mon, 8 Dec 2014 09:20:35 +0000 (09:20 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 8 Dec 2014 09:20:35 +0000 (09:20 +0000)
2014-12-08  Richard Biener  <rguenther@suse.de>

* builtins.c (fold_builtin_0): Remove unused ignore parameter.
(fold_builtin_1): Likewise.
(fold_builtin_3): Likewise.
(fold_builtin_varargs): Likewise.
(fold_builtin_2): Likewise.  Do not fold stpcpy here.
(fold_builtin_n): Adjust.
(fold_builtin_stpcpy): Move to gimple-fold.c.
(gimple_fold_builtin_stpcpy): Moved and gimplified from builtins.c.
(gimple_fold_builtin): Fold stpcpy here.

From-SVN: r218477

gcc/ChangeLog
gcc/builtins.c
gcc/gimple-fold.c

index 760f5fc3a0a723530867bf7246f1704c042ccb19..f17774fe3ffe00d631d9ce50de8a772f6335929c 100644 (file)
@@ -1,3 +1,15 @@
+2014-12-08  Richard Biener  <rguenther@suse.de>
+
+       * builtins.c (fold_builtin_0): Remove unused ignore parameter.
+       (fold_builtin_1): Likewise.
+       (fold_builtin_3): Likewise.
+       (fold_builtin_varargs): Likewise.
+       (fold_builtin_2): Likewise.  Do not fold stpcpy here.
+       (fold_builtin_n): Adjust.
+       (fold_builtin_stpcpy): Move to gimple-fold.c.
+       (gimple_fold_builtin_stpcpy): Moved and gimplified from builtins.c.
+       (gimple_fold_builtin): Fold stpcpy here.
+
 2014-12-07  Trevor Saunders  <tsaunders@mozilla.com>
 
        * symtab.c (symtab_node::verify): Check for section attribute before
index 257d001bfbf9c1fa98dc66854e44a757528e0b86..7cbac60851c6ca37bd1d1cfed0075ec0faba73fe 100644 (file)
@@ -191,11 +191,11 @@ static tree fold_builtin_fabs (location_t, tree, tree);
 static tree fold_builtin_abs (location_t, tree, tree);
 static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code,
                                        enum tree_code);
-static tree fold_builtin_0 (location_t, tree, bool);
-static tree fold_builtin_1 (location_t, tree, tree, bool);
-static tree fold_builtin_2 (location_t, tree, tree, tree, bool);
-static tree fold_builtin_3 (location_t, tree, tree, tree, tree, bool);
-static tree fold_builtin_varargs (location_t, tree, tree*, int, bool);
+static tree fold_builtin_0 (location_t, tree);
+static tree fold_builtin_1 (location_t, tree, tree);
+static tree fold_builtin_2 (location_t, tree, tree, tree);
+static tree fold_builtin_3 (location_t, tree, tree, tree, tree);
+static tree fold_builtin_varargs (location_t, tree, tree*, int);
 
 static tree fold_builtin_strpbrk (location_t, tree, tree, tree);
 static tree fold_builtin_strstr (location_t, tree, tree, tree);
@@ -8657,47 +8657,6 @@ fold_builtin_exponent (location_t loc, tree fndecl, tree arg,
   return NULL_TREE;
 }
 
-/* Fold function call to builtin stpcpy with arguments DEST and SRC.
-   Return NULL_TREE if no simplification can be made.  */
-
-static tree
-fold_builtin_stpcpy (location_t loc, tree fndecl, tree dest, tree src)
-{
-  tree fn, len, lenp1, call, type;
-
-  if (!validate_arg (dest, POINTER_TYPE)
-      || !validate_arg (src, POINTER_TYPE))
-    return NULL_TREE;
-
-  len = c_strlen (src, 1);
-  if (!len
-      || TREE_CODE (len) != INTEGER_CST)
-    return NULL_TREE;
-
-  if (optimize_function_for_size_p (cfun)
-      /* If length is zero it's small enough.  */
-      && !integer_zerop (len))
-    return NULL_TREE;
-
-  fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
-  if (!fn)
-    return NULL_TREE;
-
-  lenp1 = size_binop_loc (loc, PLUS_EXPR,
-                         fold_convert_loc (loc, size_type_node, len),
-                         build_int_cst (size_type_node, 1));
-  /* We use dest twice in building our expression.  Save it from
-     multiple expansions.  */
-  dest = builtin_save_expr (dest);
-  call = build_call_expr_loc (loc, fn, 3, dest, src, lenp1);
-
-  type = TREE_TYPE (TREE_TYPE (fndecl));
-  dest = fold_build_pointer_plus_loc (loc, dest, len);
-  dest = fold_convert_loc (loc, type, dest);
-  dest = omit_one_operand_loc (loc, type, dest, call);
-  return dest;
-}
-
 /* Fold function call to builtin memchr.  ARG1, ARG2 and LEN are the
    arguments to the call, and TYPE is its return type.
    Return NULL_TREE if no simplification can be made.  */
@@ -9857,11 +9816,10 @@ fold_builtin_arith_overflow (location_t loc, enum built_in_function fcode,
 }
 
 /* Fold a call to built-in function FNDECL with 0 arguments.
-   IGNORE is true if the result of the function call is ignored.  This
-   function returns NULL_TREE if no simplification was possible.  */
+   This function returns NULL_TREE if no simplification was possible.  */
 
 static tree
-fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
+fold_builtin_0 (location_t loc, tree fndecl)
 {
   tree type = TREE_TYPE (TREE_TYPE (fndecl));
   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
@@ -9886,11 +9844,10 @@ fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
 }
 
 /* Fold a call to built-in function FNDECL with 1 argument, ARG0.
-   IGNORE is true if the result of the function call is ignored.  This
-   function returns NULL_TREE if no simplification was possible.  */
+   This function returns NULL_TREE if no simplification was possible.  */
 
 static tree
-fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool)
+fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
 {
   tree type = TREE_TYPE (TREE_TYPE (fndecl));
   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
@@ -10301,11 +10258,10 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool)
 }
 
 /* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
-   IGNORE is true if the result of the function call is ignored.  This
-   function returns NULL_TREE if no simplification was possible.  */
+   This function returns NULL_TREE if no simplification was possible.  */
 
 static tree
-fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
+fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1)
 {
   tree type = TREE_TYPE (TREE_TYPE (fndecl));
   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
@@ -10392,19 +10348,6 @@ fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
     case BUILT_IN_RINDEX:
       return fold_builtin_strrchr (loc, arg0, arg1, type);
 
-    case BUILT_IN_STPCPY:
-      if (ignore)
-       {
-         tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
-         if (!fn)
-           break;
-
-         return build_call_expr_loc (loc, fn, 2, arg0, arg1);
-       }
-      else
-       return fold_builtin_stpcpy (loc, fndecl, arg0, arg1);
-      break;
-
     case BUILT_IN_STRCMP:
       return fold_builtin_strcmp (loc, arg0, arg1);
 
@@ -10469,12 +10412,12 @@ fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
 }
 
 /* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
-   and ARG2.  IGNORE is true if the result of the function call is ignored.
+   and ARG2.
    This function returns NULL_TREE if no simplification was possible.  */
 
 static tree
 fold_builtin_3 (location_t loc, tree fndecl,
-               tree arg0, tree arg1, tree arg2, bool)
+               tree arg0, tree arg1, tree arg2)
 {
   tree type = TREE_TYPE (TREE_TYPE (fndecl));
   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
@@ -10543,26 +10486,26 @@ fold_builtin_3 (location_t loc, tree fndecl,
    simplification was possible.  */
 
 tree
-fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore)
+fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool)
 {
   tree ret = NULL_TREE;
 
   switch (nargs)
     {
     case 0:
-      ret = fold_builtin_0 (loc, fndecl, ignore);
+      ret = fold_builtin_0 (loc, fndecl);
       break;
     case 1:
-      ret = fold_builtin_1 (loc, fndecl, args[0], ignore);
+      ret = fold_builtin_1 (loc, fndecl, args[0]);
       break;
     case 2:
-      ret = fold_builtin_2 (loc, fndecl, args[0], args[1], ignore);
+      ret = fold_builtin_2 (loc, fndecl, args[0], args[1]);
       break;
     case 3:
-      ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2], ignore);
+      ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2]);
       break;
     default:
-      ret = fold_builtin_varargs (loc, fndecl, args, nargs, ignore);
+      ret = fold_builtin_varargs (loc, fndecl, args, nargs);
       break;
     }
   if (ret)
@@ -11656,12 +11599,10 @@ fold_builtin_object_size (tree ptr, tree ost)
    need special handling; we need to store the arguments in a convenient
    data structure before attempting any folding.  Fortunately there are
    only a few builtins that fall into this category.  FNDECL is the
-   function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
-   result of the function call is ignored.  */
+   function, EXP is the CALL_EXPR for the call.  */
 
 static tree
-fold_builtin_varargs (location_t loc, tree fndecl, tree *args, int nargs,
-                     bool ignore ATTRIBUTE_UNUSED)
+fold_builtin_varargs (location_t loc, tree fndecl, tree *args, int nargs)
 {
   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
   tree ret = NULL_TREE;
index f22281ac206079fca054c8d2e5752d6145862726..e71e0954f6cab2a140158a450076bd2e492f6228 100644 (file)
@@ -2052,6 +2052,70 @@ gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi,
   return true;
 }
 
+/* Fold function call to builtin stpcpy with arguments DEST and SRC.
+   Return NULL_TREE if no simplification can be made.  */
+
+static bool
+gimple_fold_builtin_stpcpy (gimple_stmt_iterator *gsi)
+{
+  gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
+  location_t loc = gimple_location (stmt);
+  tree dest = gimple_call_arg (stmt, 0);
+  tree src = gimple_call_arg (stmt, 1);
+  tree fn, len, lenp1;
+
+  /* If the result is unused, replace stpcpy with strcpy.  */
+  if (gimple_call_lhs (stmt) == NULL_TREE)
+    {
+      tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
+      if (!fn)
+       return false;
+      gimple_call_set_fndecl (stmt, fn);
+      fold_stmt (gsi);
+      return true;
+    }
+
+  len = c_strlen (src, 1);
+  if (!len
+      || TREE_CODE (len) != INTEGER_CST)
+    return false;
+
+  if (optimize_function_for_size_p (cfun)
+      /* If length is zero it's small enough.  */
+      && !integer_zerop (len))
+    return false;
+
+  /* If the source has a known length replace stpcpy with memcpy.  */
+  fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
+  if (!fn)
+    return false;
+
+  gimple_seq stmts = NULL;
+  tree tem = gimple_convert (&stmts, loc, size_type_node, len);
+  lenp1 = gimple_build (&stmts, loc, PLUS_EXPR, size_type_node,
+                       tem, build_int_cst (size_type_node, 1));
+  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+  gcall *repl = gimple_build_call (fn, 3, dest, src, lenp1);
+  gimple_set_vuse (repl, gimple_vuse (stmt));
+  gimple_set_vdef (repl, gimple_vdef (stmt));
+  if (gimple_vdef (repl)
+      && TREE_CODE (gimple_vdef (repl)) == SSA_NAME)
+    SSA_NAME_DEF_STMT (gimple_vdef (repl)) = repl;
+  gsi_insert_before (gsi, repl, GSI_SAME_STMT);
+  /* Replace the result with dest + len.  */
+  stmts = NULL;
+  tem = gimple_convert (&stmts, loc, sizetype, len);
+  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+  gassign *ret = gimple_build_assign (gimple_call_lhs (stmt),
+                                     POINTER_PLUS_EXPR, dest, tem);
+  gsi_replace (gsi, ret, true);
+  /* Finally fold the memcpy call.  */
+  gimple_stmt_iterator gsi2 = *gsi;
+  gsi_prev (&gsi2);
+  fold_stmt (&gsi2);
+  return true;
+}
+
 /* Fold a call EXP to {,v}snprintf having NARGS passed as ARGS.  Return
    NULL_TREE if a normal call should be emitted rather than expanding
    the function inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
@@ -2849,6 +2913,8 @@ gimple_fold_builtin (gimple_stmt_iterator *gsi)
                                             gimple_call_arg (stmt, 2),
                                             gimple_call_arg (stmt, 3),
                                             fcode);
+    case BUILT_IN_STPCPY:
+      return gimple_fold_builtin_stpcpy (gsi);
     case BUILT_IN_STRCPY_CHK:
     case BUILT_IN_STPCPY_CHK:
       return gimple_fold_builtin_stxcpy_chk (gsi,