builtins.c (fold_builtin_strcpy): Merge functionality from simplify_builtin_strcpy.
authorRoger Sayle <roger@eyesopen.com>
Thu, 8 Jul 2004 17:40:22 +0000 (17:40 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Thu, 8 Jul 2004 17:40:22 +0000 (17:40 +0000)
* builtins.c (fold_builtin_strcpy): Merge functionality from
simplify_builtin_strcpy.  Add additional len argument.  No longer
static.  Remove function prototype.
(fold_builtin_strncpy): Likewise integrate functionality from
simplify_builtin_strncpy.  Add additional slen argument.  No
longer static.  Remove function prototype.
(simplify_builtin_strcy, simplify_builtin_strncpy): Delete.
(simplify_builtin_fputs): Rename to fold_builtin_fputs.  Change
types of "ignore" and "unlocked" parameters to bool.
(fold_builtin_1):  Add additional ignore argument.  Call renamed
fold_builtin_fputs to simplify GCC "fputs" and "fputs_unlocked"
builtins.  Update arguments to fold_builtin_strncpy and
fold_builtin_strcpy.  Add function prototype.
(fold_builtin): Add additional Boolean ignore argument to pass
to fold_builtin_1.
(simplify_builtin): Call fold_builtin_fputs, fold_builtin_strcpy
and fold_builtin_strncpy instead of simplify_builtin_fputs,
simplify_builtin_strcpy and simplify_builtin_strncpy respectively.

* expr.h (simplify_builtin_fputs, simplify_builtin_strcpy,
simplify_builtin_strncpy): Delete function prototypes.
* tree.h (fold_builtin_fputs, fold_builtin_strcpy,
fold_builtin_strncpy): Add function prototypes here.
(fold_builtin): Update function prototype with new "bool ignore".

* tree-ssa-ccp.c (ccp_fold): Update call to fold_builtin.
(ccp_fold_builtin):  Update call to fold_builtin.  Call
fold_builtin_fputs, fold_builtin_strcpy and fold_builtin_strncpy
instead of simplify_builtin_fputs, simplify_builtin_strcpy and
simplify_builtin_strncpy respectively.
* fold-const.c (fold): Update call to fold_builtin.

From-SVN: r84302

gcc/ChangeLog
gcc/builtins.c
gcc/expr.h
gcc/fold-const.c
gcc/tree-ssa-ccp.c
gcc/tree.h

index 1456ae9..3ca80b4 100644 (file)
@@ -1,3 +1,37 @@
+2004-07-08  Roger Sayle  <roger@eyesopen.com>
+
+       * builtins.c (fold_builtin_strcpy): Merge functionality from
+       simplify_builtin_strcpy.  Add additional len argument.  No longer
+       static.  Remove function prototype.
+       (fold_builtin_strncpy): Likewise integrate functionality from
+       simplify_builtin_strncpy.  Add additional slen argument.  No
+       longer static.  Remove function prototype.
+       (simplify_builtin_strcy, simplify_builtin_strncpy): Delete.
+       (simplify_builtin_fputs): Rename to fold_builtin_fputs.  Change
+       types of "ignore" and "unlocked" parameters to bool.
+       (fold_builtin_1):  Add additional ignore argument.  Call renamed
+       fold_builtin_fputs to simplify GCC "fputs" and "fputs_unlocked"
+       builtins.  Update arguments to fold_builtin_strncpy and
+       fold_builtin_strcpy.  Add function prototype.
+       (fold_builtin): Add additional Boolean ignore argument to pass
+       to fold_builtin_1.
+       (simplify_builtin): Call fold_builtin_fputs, fold_builtin_strcpy
+       and fold_builtin_strncpy instead of simplify_builtin_fputs,
+       simplify_builtin_strcpy and simplify_builtin_strncpy respectively.
+
+       * expr.h (simplify_builtin_fputs, simplify_builtin_strcpy,
+       simplify_builtin_strncpy): Delete function prototypes.
+       * tree.h (fold_builtin_fputs, fold_builtin_strcpy,
+       fold_builtin_strncpy): Add function prototypes here.
+       (fold_builtin): Update function prototype with new "bool ignore".
+
+       * tree-ssa-ccp.c (ccp_fold): Update call to fold_builtin.
+       (ccp_fold_builtin):  Update call to fold_builtin.  Call
+       fold_builtin_fputs, fold_builtin_strcpy and fold_builtin_strncpy
+       instead of simplify_builtin_fputs, simplify_builtin_strcpy and
+       simplify_builtin_strncpy respectively.
+       * fold-const.c (fold): Update call to fold_builtin.
+
 2004-07-08  Alexandre Oliva  <aoliva@redhat.com>
 
        * builtins.c (expand_builtin_stpcpy): Un-simplify decay of stpcpy
index 9bcef91..c07ff04 100644 (file)
@@ -156,8 +156,6 @@ static tree fold_builtin_bitop (tree);
 static tree fold_builtin_memcpy (tree);
 static tree fold_builtin_mempcpy (tree);
 static tree fold_builtin_memmove (tree);
-static tree fold_builtin_strcpy (tree);
-static tree fold_builtin_strncpy (tree);
 static tree fold_builtin_strchr (tree, bool);
 static tree fold_builtin_memcmp (tree);
 static tree fold_builtin_strcmp (tree);
@@ -170,6 +168,7 @@ static tree fold_builtin_isdigit (tree);
 static tree fold_builtin_fabs (tree, tree);
 static tree fold_builtin_abs (tree, tree);
 static tree fold_builtin_unordered_cmp (tree, enum tree_code, enum tree_code);
+static tree fold_builtin_1 (tree, bool);
 
 static tree simplify_builtin_memcmp (tree);
 static tree simplify_builtin_strcmp (tree);
@@ -7314,14 +7313,15 @@ fold_builtin_memmove (tree exp)
   return 0;
 }
 
-/* Fold function call to builtin strcpy.  Return
-   NULL_TREE if no simplification can be made.  */
+/* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
+   the length of the string to be copied.  Return NULL_TREE if no
+   simplification can be made.  */
 
-static tree
-fold_builtin_strcpy (tree exp)
+tree
+fold_builtin_strcpy (tree exp, tree len)
 {
   tree arglist = TREE_OPERAND (exp, 1);
-  tree dest, src;
+  tree dest, src, fn;
 
   if (!validate_arglist (arglist,
                         POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
@@ -7334,17 +7334,37 @@ fold_builtin_strcpy (tree exp)
   if (operand_equal_p (src, dest, 0))
     return fold_convert (TREE_TYPE (exp), dest);
 
-  return 0;
+  if (optimize_size)
+    return 0;
+
+  fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+  if (!fn)
+    return 0;
+
+  if (!len)
+    {
+      len = c_strlen (src, 1);
+      if (! len || TREE_SIDE_EFFECTS (len))
+       return 0;
+    }
+
+  len = size_binop (PLUS_EXPR, len, ssize_int (1));
+  arglist = build_tree_list (NULL_TREE, len);
+  arglist = tree_cons (NULL_TREE, src, arglist);
+  arglist = tree_cons (NULL_TREE, dest, arglist);
+  return fold_convert (TREE_TYPE (exp),
+                      build_function_call_expr (fn, arglist));
 }
 
-/* Fold function call to builtin strncpy.  Return
-   NULL_TREE if no simplification can be made.  */
+/* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
+   the length of the source string.  Return NULL_TREE if no simplification
+   can be made.  */
 
-static tree
-fold_builtin_strncpy (tree exp)
+tree
+fold_builtin_strncpy (tree exp, tree slen)
 {
   tree arglist = TREE_OPERAND (exp, 1);
-  tree dest, src, len;
+  tree dest, src, len, fn;
 
   if (!validate_arglist (arglist,
                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
@@ -7358,7 +7378,27 @@ fold_builtin_strncpy (tree exp)
   if (integer_zerop (len))
     return omit_one_operand (TREE_TYPE (exp), dest, src);
 
-  return 0;
+  if (!slen)
+    slen = c_strlen (src, 1);
+
+  /* Now, we must be passed a constant src ptr parameter.  */
+  if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
+    return 0;
+
+  slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
+
+  /* We do not support simplification of this case, though we do
+     support it when expanding trees into RTL.  */
+  /* FIXME: generate a call to __builtin_memset.  */
+  if (tree_int_cst_lt (slen, len))
+    return 0;
+
+  /* OK transform into builtin memcpy.  */
+  fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+  if (!fn)
+    return 0;
+  return fold_convert (TREE_TYPE (exp),
+                      build_function_call_expr (fn, arglist));
 }
 
 /* Fold function call to builtin strchr and strrchr.
@@ -7886,11 +7926,13 @@ fold_builtin_unordered_cmp (tree exp,
                       fold (build2 (code, type, arg0, arg1))));
 }
 
-/* Used by constant folding to eliminate some builtin calls early.  EXP is
-   the CALL_EXPR of a call to a builtin function.  */
+/* Used by constant folding to simplify calls to builtin functions.  EXP is
+   the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
+   result of the function call is ignored.  This function returns NULL_TREE
+   if no simplification was possible.  */
 
 static tree
-fold_builtin_1 (tree exp)
+fold_builtin_1 (tree exp, bool ignore)
 {
   tree fndecl = get_callee_fndecl (exp);
   tree arglist = TREE_OPERAND (exp, 1);
@@ -8397,10 +8439,10 @@ fold_builtin_1 (tree exp)
       return fold_builtin_memmove (exp);
 
     case BUILT_IN_STRCPY:
-      return fold_builtin_strcpy (exp);
+      return fold_builtin_strcpy (exp, NULL_TREE);
 
     case BUILT_IN_STRNCPY:
-      return fold_builtin_strncpy (exp);
+      return fold_builtin_strncpy (exp, NULL_TREE);
 
     case BUILT_IN_INDEX:
     case BUILT_IN_STRCHR:
@@ -8466,6 +8508,12 @@ fold_builtin_1 (tree exp)
     case BUILT_IN_ISUNORDERED:
       return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);
 
+    case BUILT_IN_FPUTS:
+      return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
+
+    case BUILT_IN_FPUTS_UNLOCKED:
+      return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
+
     default:
       break;
     }
@@ -8478,9 +8526,9 @@ fold_builtin_1 (tree exp)
    call node earlier than the warning is generated.  */
 
 tree
-fold_builtin (tree exp)
+fold_builtin (tree exp, bool ignore)
 {
-  exp = fold_builtin_1 (exp);
+  exp = fold_builtin_1 (exp, ignore);
   if (exp)
     {
       /* ??? Don't clobber shared nodes such as integer_zero_node.  */
@@ -8614,10 +8662,10 @@ simplify_builtin (tree exp, int ignore)
   switch (fcode)
     {
     case BUILT_IN_FPUTS:
-      val = simplify_builtin_fputs (arglist, ignore, 0, NULL_TREE);
+      val = fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
       break;
     case BUILT_IN_FPUTS_UNLOCKED:
-      val = simplify_builtin_fputs (arglist, ignore, 1, NULL_TREE);
+      val = fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
       break;
     case BUILT_IN_STRSTR:
       val = simplify_builtin_strstr (arglist);
@@ -8643,10 +8691,10 @@ simplify_builtin (tree exp, int ignore)
       val = simplify_builtin_strrchr (arglist);
       break;
     case BUILT_IN_STRCPY:
-      val = simplify_builtin_strcpy (arglist, NULL_TREE);
+      val = fold_builtin_strcpy (exp, NULL_TREE);
       break;
     case BUILT_IN_STRNCPY:
-      val = simplify_builtin_strncpy (arglist, NULL_TREE);
+      val = fold_builtin_strncpy (exp, NULL_TREE);
       break;
     case BUILT_IN_STRCMP:
       val = simplify_builtin_strcmp (arglist);
@@ -8936,115 +8984,6 @@ simplify_builtin_strpbrk (tree arglist)
     }
 }
 
-/* Simplify a call to the strcpy builtin.
-
-   Return 0 if no simplification was possible, otherwise return the
-   simplified form of the call as a tree.
-
-   The simplified form may be a constant or other expression which
-   computes the same value, but in a more efficient manner (including
-   calls to other builtin functions).
-
-   The call may contain arguments which need to be evaluated, but
-   which are not useful to determine the result of the call.  In
-   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
-   COMPOUND_EXPR will be an argument which must be evaluated.
-   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
-   COMPOUND_EXPR in the chain will contain the tree for the simplified
-   form of the builtin function call.  */
-
-tree
-simplify_builtin_strcpy (tree arglist, tree len)
-{
-  tree fn, src, dst;
-
-  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
-    return 0;
-
-  fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
-  if (!fn)
-    return 0;
-
-  src = TREE_VALUE (TREE_CHAIN (arglist));
-  dst = TREE_VALUE (arglist);
-
-  if (!len)
-    {
-      len = c_strlen (src, 1);
-      if (!len || TREE_SIDE_EFFECTS (len))
-       return 0;
-    }
-
-  len = size_binop (PLUS_EXPR, len, ssize_int (1));
-  arglist = build_tree_list (NULL_TREE, len);
-  arglist = tree_cons (NULL_TREE, src, arglist);
-  arglist = tree_cons (NULL_TREE, dst, arglist);
-  return build_function_call_expr (fn, arglist);
-}
-
-/* Simplify a call to the strncpy builtin.
-
-   Return 0 if no simplification was possible, otherwise return the
-   simplified form of the call as a tree.
-
-   The simplified form may be a constant or other expression which
-   computes the same value, but in a more efficient manner (including
-   calls to other builtin functions).
-
-   The call may contain arguments which need to be evaluated, but
-   which are not useful to determine the result of the call.  In
-   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
-   COMPOUND_EXPR will be an argument which must be evaluated.
-   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
-   COMPOUND_EXPR in the chain will contain the tree for the simplified
-   form of the builtin function call.  */
-
-tree
-simplify_builtin_strncpy (tree arglist, tree slen)
-{
-  if (!validate_arglist (arglist,
-                        POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
-    return 0;
-  else
-    {
-      tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
-      tree fn;
-
-      /* We must be passed a constant len parameter.  */
-      if (TREE_CODE (len) != INTEGER_CST)
-       return 0;
-
-      /* If the len parameter is zero, return the dst parameter.  */
-      if (integer_zerop (len))
-       /* Evaluate and ignore the src argument in case it has
-          side-effects and return the dst parameter.  */
-       return omit_one_operand (TREE_TYPE (TREE_VALUE (arglist)),
-                                TREE_VALUE (arglist),
-                                TREE_VALUE (TREE_CHAIN (arglist)));
-
-      if (!slen)
-        slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 0);
-
-      /* Now, we must be passed a constant src ptr parameter.  */
-      if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
-       return 0;
-
-      slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
-
-      /* We do not support simplification of this case, though we do
-         support it when expanding trees into RTL.  */
-      /* FIXME: generate a call to __builtin_memset.  */
-      if (tree_int_cst_lt (slen, len))
-       return 0;
-
-      /* OK transform into builtin memcpy.  */
-      fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
-      if (!fn)
-       return 0;
-      return build_function_call_expr (fn, arglist);
-    }
-}
-
 /* Simplify a call to the memcmp builtin.
 
    Return 0 if no simplification was possible, otherwise return the
@@ -9454,31 +9393,16 @@ simplify_builtin_strcspn (tree arglist)
     }
 }
 
-/* Simplify a call to the fputs builtin.
-
-   Return 0 if no simplification was possible, otherwise return the
-   simplified form of the call as a tree.
-
-   The simplified form may be a constant or other expression which
-   computes the same value, but in a more efficient manner (including
-   calls to other builtin functions).
-
-   The call may contain arguments which need to be evaluated, but
-   which are not useful to determine the result of the call.  In
-   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
-   COMPOUND_EXPR will be an argument which must be evaluated.
-   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
-   COMPOUND_EXPR in the chain will contain the tree for the simplified
-   form of the builtin function call.
-
-   If KNOWN_LEN is non-NULL, it represents the known length of the string.
-   This is determined by SSA-CCP in cases where the string itself is not
-   known to be constant but its length is always the same constant.  */
+/* Fold a call to the fputs builtin.  IGNORE is true if the value returned
+   by the builtin will be ignored.  UNLOCKED is true is true if this
+   actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
+   the known length of the string.  Return NULL_TREE if no simplification
+   was possible.  */
 
 tree
-simplify_builtin_fputs (tree arglist, int ignore, int unlocked, tree known_len)
+fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
 {
-  tree len, fn;
+  tree fn;
   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
     : implicit_built_in_decls[BUILT_IN_FPUTC];
   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
@@ -9493,7 +9417,8 @@ simplify_builtin_fputs (tree arglist, int ignore, int unlocked, tree known_len)
   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
     return 0;
 
-  len = (known_len) ? known_len : c_strlen (TREE_VALUE (arglist), 0);
+  if (! len)
+    len = c_strlen (TREE_VALUE (arglist), 0);
 
   /* Get the length of the string passed to fputs.  If the length
      can't be determined, punt.  */
@@ -9517,8 +9442,7 @@ simplify_builtin_fputs (tree arglist, int ignore, int unlocked, tree known_len)
               fputc(string[0], stream).  */
            arglist =
              build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
-           arglist =
-             tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
+           arglist = tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
            fn = fn_fputc;
            break;
          }
@@ -9534,7 +9458,8 @@ simplify_builtin_fputs (tree arglist, int ignore, int unlocked, tree known_len)
        string_arg = TREE_VALUE (arglist);
        /* New argument list transforming fputs(string, stream) to
           fwrite(string, 1, len, stream).  */
-       arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
+       arglist = build_tree_list (NULL_TREE,
+                                  TREE_VALUE (TREE_CHAIN (arglist)));
        arglist = tree_cons (NULL_TREE, len, arglist);
        arglist = tree_cons (NULL_TREE, size_one_node, arglist);
        arglist = tree_cons (NULL_TREE, string_arg, arglist);
@@ -9545,7 +9470,8 @@ simplify_builtin_fputs (tree arglist, int ignore, int unlocked, tree known_len)
       abort ();
     }
 
-  return build_function_call_expr (fn, arglist);
+  return fold_convert (integer_type_node,
+                      build_function_call_expr (fn, arglist));
 }
 
 static void
index b335db0..c7d600c 100644 (file)
@@ -389,9 +389,6 @@ extern void expand_builtin_setjmp_receiver (rtx);
 extern void expand_builtin_longjmp (rtx, rtx);
 extern rtx expand_builtin_saveregs (void);
 extern void expand_builtin_trap (void);
-extern tree simplify_builtin_fputs (tree, int, int, tree);
-extern tree simplify_builtin_strcpy (tree, tree);
-extern tree simplify_builtin_strncpy (tree, tree);
 \f
 /* Functions from expr.c:  */
 
index 05f4a21..a1efab1 100644 (file)
@@ -8937,7 +8937,7 @@ fold (tree expr)
              == FUNCTION_DECL)
          && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
        {
-         tree tmp = fold_builtin (t);
+         tree tmp = fold_builtin (t, false);
          if (tmp)
            return tmp;
        }
index 722f552..d2c503d 100644 (file)
@@ -950,7 +950,7 @@ ccp_fold (tree stmt)
 
          /* Substitute operands with their values and try to fold.  */
          replace_uses_in (stmt, NULL);
-         retval = fold_builtin (rhs);
+         retval = fold_builtin (rhs, false);
 
          /* Restore operands to their original form.  */
          for (i = 0; i < NUM_USES (uses); i++)
@@ -963,13 +963,7 @@ ccp_fold (tree stmt)
 
   /* If we got a simplified form, see if we need to convert its type.  */
   if (retval)
-    {
-      if (TREE_TYPE (retval) != TREE_TYPE (rhs))
-       retval = fold_convert (TREE_TYPE (rhs), retval);
-
-      if (TREE_TYPE (retval) == TREE_TYPE (rhs))
-       return retval;
-    }
+    return fold_convert (TREE_TYPE (rhs), retval);
 
   /* No simplification was possible.  */
   return rhs;
@@ -2307,23 +2301,31 @@ static tree
 ccp_fold_builtin (tree stmt, tree fn)
 {
   tree result, strlen_val[2];
-  tree arglist = TREE_OPERAND (fn, 1), a;
-  tree callee = get_callee_fndecl (fn);
-  bitmap visited;
+  tree callee, arglist, a;
   int strlen_arg, i;
+  bitmap visited;
+  bool ignore;
 
-  /* Ignore MD builtins.  */
-  if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_MD)
-    return NULL_TREE;
+  ignore = TREE_CODE (stmt) != MODIFY_EXPR;
 
   /* First try the generic builtin folder.  If that succeeds, return the
      result directly.  */
-  result = fold_builtin (fn);
+  result = fold_builtin (fn, ignore);
   if (result)
+  {
+    if (ignore)
+      STRIP_NOPS (result);
     return result;
+  }
+
+  /* Ignore MD builtins.  */
+  callee = get_callee_fndecl (fn);
+  if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_MD)
+    return NULL_TREE;
 
   /* If the builtin could not be folded, and it has no argument list,
      we're done.  */
+  arglist = TREE_OPERAND (fn, 1);
   if (!arglist)
     return NULL_TREE;
 
@@ -2359,16 +2361,13 @@ ccp_fold_builtin (tree stmt, tree fn)
 
   BITMAP_XFREE (visited);
 
-  /* FIXME.  All this code looks dangerous in the sense that it might
-     create non-gimple expressions.  */
+  result = NULL_TREE;
   switch (DECL_FUNCTION_CODE (callee))
     {
     case BUILT_IN_STRLEN:
-      /* Convert from the internal "sizetype" type to "size_t".  */
-      if (strlen_val[0]
-         && size_type_node)
+      if (strlen_val[0])
        {
-         tree new = convert (size_type_node, strlen_val[0]);
+         tree new = fold_convert (TREE_TYPE (fn), strlen_val[0]);
 
          /* If the result is not a valid gimple value, or not a cast
             of a valid gimple value, then we can not use the result.  */
@@ -2376,32 +2375,38 @@ ccp_fold_builtin (tree stmt, tree fn)
              || (is_gimple_cast (new)
                  && is_gimple_val (TREE_OPERAND (new, 0))))
            return new;
-         else
-           return NULL_TREE;
        }
-      return strlen_val[0];
+      break;
+
     case BUILT_IN_STRCPY:
-      if (strlen_val[1]
-         && is_gimple_val (strlen_val[1]))
-      return simplify_builtin_strcpy (arglist, strlen_val[1]);
+      if (strlen_val[1] && is_gimple_val (strlen_val[1]))
+        result = fold_builtin_strcpy (fn, strlen_val[1]);
+      break;
+
     case BUILT_IN_STRNCPY:
-      if (strlen_val[1]
-         && is_gimple_val (strlen_val[1]))
-      return simplify_builtin_strncpy (arglist, strlen_val[1]);
+      if (strlen_val[1] && is_gimple_val (strlen_val[1]))
+       result = fold_builtin_strncpy (fn, strlen_val[1]);
+      break;
+
     case BUILT_IN_FPUTS:
-      return simplify_builtin_fputs (arglist,
-                                    TREE_CODE (stmt) != MODIFY_EXPR, 0,
-                                    strlen_val[0]);
+      result = fold_builtin_fputs (arglist,
+                                  TREE_CODE (stmt) != MODIFY_EXPR, 0,
+                                  strlen_val[0]);
+      break;
+
     case BUILT_IN_FPUTS_UNLOCKED:
-      return simplify_builtin_fputs (arglist,
-                                    TREE_CODE (stmt) != MODIFY_EXPR, 1,
-                                    strlen_val[0]);
+      result = fold_builtin_fputs (arglist,
+                                  TREE_CODE (stmt) != MODIFY_EXPR, 1,
+                                  strlen_val[0]);
+      break;
 
     default:
       abort ();
     }
 
-  return NULL_TREE;
+  if (result && ignore)
+    STRIP_NOPS (result);
+  return result;
 }
 
 
index 74cf79e..4dab73f 100644 (file)
@@ -3423,7 +3423,10 @@ extern bool tree_swap_operands_p (tree, tree, bool);
 extern enum tree_code swap_tree_comparison (enum tree_code);
 
 /* In builtins.c */
-extern tree fold_builtin (tree);
+extern tree fold_builtin (tree, bool);
+extern tree fold_builtin_fputs (tree, bool, bool, tree);
+extern tree fold_builtin_strcpy (tree, tree);
+extern tree fold_builtin_strncpy (tree, tree);
 extern enum built_in_function builtin_mathfn_code (tree);
 extern tree build_function_call_expr (tree, tree);
 extern tree mathfn_built_in (tree, enum built_in_function fn);