This removes gimple_fold_builtin_with_strlen and makes get_maxval_strlen
get an overload with an API that is convenient to use from the actual
folders.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2014-08-27  Richard Biener  <rguent...@suse.de>

        * gimple-fold.c (get_maxval_strlen): Add overload wrapping
        get_maxval_strlen inside a more useful API.
        (gimple_fold_builtin_with_strlen): Remove and fold into ...
        (gimple_fold_builtin): ... caller.
        (gimple_fold_builtin_strlen, gimple_fold_builtin_strcpy,
        gimple_fold_builtin_strncpy, gimple_fold_builtin_strcat,
        gimple_fold_builtin_fputs, gimple_fold_builtin_memory_chk,
        gimple_fold_builtin_stxcpy_chk, gimple_fold_builtin_stxncpy_chk,
        gimple_fold_builtin_snprintf_chk, gimple_fold_builtin_snprintf,
        gimple_fold_builtin_sprintf): Adjust to compute maxval
        themselves.

Index: gcc/gimple-fold.c
===================================================================
*** gcc/gimple-fold.c   (revision 214564)
--- gcc/gimple-fold.c   (working copy)
*************** gimple_fold_builtin_memset (gimple_stmt_
*** 1285,1291 ****
     length and 2 for maximum value ARG can have.  */
  
  static bool
! get_maxval_strlen (tree arg, tree *length, bitmap visited, int type)
  {
    tree var, val;
    gimple def_stmt;
--- 1285,1291 ----
     length and 2 for maximum value ARG can have.  */
  
  static bool
! get_maxval_strlen (tree arg, tree *length, bitmap *visited, int type)
  {
    tree var, val;
    gimple def_stmt;
*************** get_maxval_strlen (tree arg, tree *lengt
*** 1342,1348 ****
      return false;
  
    /* If we were already here, break the infinite cycle.  */
!   if (!bitmap_set_bit (visited, SSA_NAME_VERSION (arg)))
      return true;
  
    var = arg;
--- 1342,1350 ----
      return false;
  
    /* If we were already here, break the infinite cycle.  */
!   if (!*visited)
!     *visited = BITMAP_ALLOC (NULL);
!   if (!bitmap_set_bit (*visited, SSA_NAME_VERSION (arg)))
      return true;
  
    var = arg;
*************** get_maxval_strlen (tree arg, tree *lengt
*** 1399,1404 ****
--- 1401,1419 ----
      }
  }
  
+ tree
+ get_maxval_strlen (tree arg, int type)
+ {
+   bitmap visited = NULL;
+   tree len = NULL_TREE;
+   if (!get_maxval_strlen (arg, &len, &visited, type))
+     len = NULL_TREE;
+   if (visited)
+     BITMAP_FREE (visited);
+ 
+   return len;
+ }
+ 
  
  /* Fold function call to builtin strcpy with arguments DEST and SRC.
     If LEN is not NULL, it represents the length of the string to be
*************** get_maxval_strlen (tree arg, tree *lengt
*** 1406,1413 ****
  
  static bool
  gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi,
!                           location_t loc, tree dest, tree src, tree len)
  {
    tree fn;
  
    /* If SRC and DEST are the same (and not volatile), return DEST.  */
--- 1421,1429 ----
  
  static bool
  gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi,
!                           tree dest, tree src)
  {
+   location_t loc = gimple_location (gsi_stmt (*gsi));
    tree fn;
  
    /* If SRC and DEST are the same (and not volatile), return DEST.  */
*************** gimple_fold_builtin_strcpy (gimple_stmt_
*** 1424,1435 ****
    if (!fn)
      return false;
  
    if (!len)
!     {
!       len = c_strlen (src, 1);
!       if (! len || TREE_SIDE_EFFECTS (len))
!       return NULL_TREE;
!     }
  
    len = fold_convert_loc (loc, size_type_node, len);
    len = size_binop_loc (loc, PLUS_EXPR, len, build_int_cst (size_type_node, 
1));
--- 1440,1448 ----
    if (!fn)
      return false;
  
+   tree len = get_maxval_strlen (src, 1);
    if (!len)
!     return false;
  
    len = fold_convert_loc (loc, size_type_node, len);
    len = size_binop_loc (loc, PLUS_EXPR, len, build_int_cst (size_type_node, 
1));
*************** gimple_fold_builtin_strcpy (gimple_stmt_
*** 1445,1453 ****
     Return NULL_TREE if no simplification can be made.  */
  
  static bool
! gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi, location_t loc,
!                            tree dest, tree src, tree len, tree slen)
  {
    tree fn;
  
    /* If the LEN parameter is zero, return DEST.  */
--- 1458,1467 ----
     Return NULL_TREE if no simplification can be made.  */
  
  static bool
! gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi,
!                            tree dest, tree src, tree len)
  {
+   location_t loc = gimple_location (gsi_stmt (*gsi));
    tree fn;
  
    /* If the LEN parameter is zero, return DEST.  */
*************** gimple_fold_builtin_strncpy (gimple_stmt
*** 1459,1472 ****
  
    /* We can't compare slen with len as constants below if len is not a
       constant.  */
!   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
      return false;
  
-   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 false;
  
    slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
--- 1473,1484 ----
  
    /* We can't compare slen with len as constants below if len is not a
       constant.  */
!   if (TREE_CODE (len) != INTEGER_CST)
      return false;
  
    /* Now, we must be passed a constant src ptr parameter.  */
!   tree slen = get_maxval_strlen (src, 1);
!   if (!slen || TREE_CODE (slen) != INTEGER_CST)
      return false;
  
    slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
*************** gimple_fold_builtin_strncpy (gimple_stmt
*** 1509,1519 ****
     form of the builtin function call.  */
  
  static bool
! gimple_fold_builtin_strcat (gimple_stmt_iterator *gsi,
!                           location_t loc ATTRIBUTE_UNUSED, tree dst, tree src,
!                           tree len)
  {
    gimple stmt = gsi_stmt (*gsi);
  
    const char *p = c_getstr (src);
  
--- 1521,1530 ----
     form of the builtin function call.  */
  
  static bool
! gimple_fold_builtin_strcat (gimple_stmt_iterator *gsi, tree dst, tree src)
  {
    gimple stmt = gsi_stmt (*gsi);
+   location_t loc = gimple_location (stmt);
  
    const char *p = c_getstr (src);
  
*************** gimple_fold_builtin_strcat (gimple_stmt_
*** 1537,1545 ****
  
    /* If the length of the source string isn't computable don't
       split strcat into strlen and memcpy.  */
    if (! len)
-     len = c_strlen (src, 1);
-   if (! len || TREE_SIDE_EFFECTS (len))
      return false;
  
    /* Create strlen (dst).  */
--- 1548,1555 ----
  
    /* If the length of the source string isn't computable don't
       split strcat into strlen and memcpy.  */
+   tree len = get_maxval_strlen (src, 0);
    if (! len)
      return false;
  
    /* Create strlen (dst).  */
*************** gimple_fold_builtin_strcat_chk (gimple_s
*** 1631,1640 ****
  
  static bool
  gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi,
-                          location_t loc ATTRIBUTE_UNUSED,
                           tree arg0, tree arg1,
!                          bool ignore, bool unlocked, tree len)
  {
    /* If we're using an unlocked function, assume the other unlocked
       functions exist explicitly.  */
    tree const fn_fputc = (unlocked
--- 1641,1651 ----
  
  static bool
  gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi,
                           tree arg0, tree arg1,
!                          bool unlocked)
  {
+   gimple stmt = gsi_stmt (*gsi);
+ 
    /* If we're using an unlocked function, assume the other unlocked
       functions exist explicitly.  */
    tree const fn_fputc = (unlocked
*************** gimple_fold_builtin_fputs (gimple_stmt_i
*** 1645,1658 ****
                          : builtin_decl_implicit (BUILT_IN_FWRITE));
  
    /* If the return value is used, don't do the transformation.  */
!   if (!ignore)
      return false;
  
-   if (! len)
-     len = c_strlen (arg0, 0);
- 
    /* Get the length of the string passed to fputs.  If the length
       can't be determined, punt.  */
    if (!len
        || TREE_CODE (len) != INTEGER_CST)
      return false;
--- 1656,1667 ----
                          : builtin_decl_implicit (BUILT_IN_FWRITE));
  
    /* If the return value is used, don't do the transformation.  */
!   if (gimple_call_lhs (stmt))
      return false;
  
    /* Get the length of the string passed to fputs.  If the length
       can't be determined, punt.  */
+   tree len = get_maxval_strlen (arg0, 0);
    if (!len
        || TREE_CODE (len) != INTEGER_CST)
      return false;
*************** gimple_fold_builtin_fputs (gimple_stmt_i
*** 1708,1718 ****
  
  static bool
  gimple_fold_builtin_memory_chk (gimple_stmt_iterator *gsi,
-                               location_t loc,
                                tree dest, tree src, tree len, tree size,
-                               tree maxlen, bool ignore,
                                enum built_in_function fcode)
  {
    tree fn;
  
    /* If SRC and DEST are the same (and not volatile), return DEST
--- 1717,1728 ----
  
  static bool
  gimple_fold_builtin_memory_chk (gimple_stmt_iterator *gsi,
                                tree dest, tree src, tree len, tree size,
                                enum built_in_function fcode)
  {
+   gimple stmt = gsi_stmt (*gsi);
+   location_t loc = gimple_location (stmt);
+   bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
    tree fn;
  
    /* If SRC and DEST are the same (and not volatile), return DEST
*************** gimple_fold_builtin_memory_chk (gimple_s
*** 1738,1743 ****
--- 1748,1754 ----
    if (! tree_fits_uhwi_p (size))
      return false;
  
+   tree maxlen = get_maxval_strlen (len, 2);
    if (! integer_all_onesp (size))
      {
        if (! tree_fits_uhwi_p (len))
*************** gimple_fold_builtin_memory_chk (gimple_s
*** 1806,1816 ****
  
  static bool
  gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi,
!                               location_t loc, tree dest,
                                tree src, tree size,
-                               tree maxlen, bool ignore,
                                enum built_in_function fcode)
  {
    tree len, fn;
  
    /* If SRC and DEST are the same (and not volatile), return DEST.  */
--- 1817,1829 ----
  
  static bool
  gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi,
!                               tree dest,
                                tree src, tree size,
                                enum built_in_function fcode)
  {
+   gimple stmt = gsi_stmt (*gsi);
+   location_t loc = gimple_location (stmt);
+   bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
    tree len, fn;
  
    /* If SRC and DEST are the same (and not volatile), return DEST.  */
*************** gimple_fold_builtin_stxcpy_chk (gimple_s
*** 1823,1828 ****
--- 1836,1842 ----
    if (! tree_fits_uhwi_p (size))
      return false;
  
+   tree maxlen = get_maxval_strlen (src, 1);
    if (! integer_all_onesp (size))
      {
        len = c_strlen (src, 1);
*************** gimple_fold_builtin_stxcpy_chk (gimple_s
*** 1894,1902 ****
  static bool
  gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi,
                                 tree dest, tree src,
!                                tree len, tree size, tree maxlen, bool ignore,
                                 enum built_in_function fcode)
  {
    tree fn;
  
    if (fcode == BUILT_IN_STPNCPY_CHK && ignore)
--- 1908,1918 ----
  static bool
  gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi,
                                 tree dest, tree src,
!                                tree len, tree size,
                                 enum built_in_function fcode)
  {
+   gimple stmt = gsi_stmt (*gsi);
+   bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
    tree fn;
  
    if (fcode == BUILT_IN_STPNCPY_CHK && ignore)
*************** gimple_fold_builtin_stxncpy_chk (gimple_
*** 1915,1920 ****
--- 1931,1937 ----
    if (! tree_fits_uhwi_p (size))
      return false;
  
+   tree maxlen = get_maxval_strlen (len, 2);
    if (! integer_all_onesp (size))
      {
        if (! tree_fits_uhwi_p (len))
*************** gimple_fold_builtin_stxncpy_chk (gimple_
*** 1951,1957 ****
  
  static bool
  gimple_fold_builtin_snprintf_chk (gimple_stmt_iterator *gsi,
!                                 tree maxlen, enum built_in_function fcode)
  {
    gimple stmt = gsi_stmt (*gsi);
    tree dest, size, len, fn, fmt, flag;
--- 1968,1974 ----
  
  static bool
  gimple_fold_builtin_snprintf_chk (gimple_stmt_iterator *gsi,
!                                 enum built_in_function fcode)
  {
    gimple stmt = gsi_stmt (*gsi);
    tree dest, size, len, fn, fmt, flag;
*************** gimple_fold_builtin_snprintf_chk (gimple
*** 1972,1977 ****
--- 1989,1995 ----
  
    if (! integer_all_onesp (size))
      {
+       tree maxlen = get_maxval_strlen (len, 2);
        if (! tree_fits_uhwi_p (len))
        {
          /* If LEN is not constant, try MAXLEN too.
*************** gimple_fold_builtin_sprintf_chk (gimple_
*** 2128,2134 ****
     the caller does not use the returned value of the function.  */
  
  static bool
! gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi, tree orig_len)
  {
    gimple stmt = gsi_stmt (*gsi);
    tree dest = gimple_call_arg (stmt, 0);
--- 2146,2152 ----
     the caller does not use the returned value of the function.  */
  
  static bool
! gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi)
  {
    gimple stmt = gsi_stmt (*gsi);
    tree dest = gimple_call_arg (stmt, 0);
*************** gimple_fold_builtin_sprintf (gimple_stmt
*** 2206,2215 ****
        if (!orig)
        return false;
  
!       if (gimple_call_lhs (stmt)
!         && !orig_len)
        {
!         orig_len = c_strlen (orig, 1);
          if (!orig_len)
            return false;
        }
--- 2224,2233 ----
        if (!orig)
        return false;
  
!       tree orig_len = NULL_TREE;
!       if (gimple_call_lhs (stmt))
        {
!         orig_len = get_maxval_strlen (orig, 0);
          if (!orig_len)
            return false;
        }
*************** gimple_fold_builtin_sprintf (gimple_stmt
*** 2253,2259 ****
     the caller does not use the returned value of the function.  */
  
  static bool
! gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi, tree orig_len)
  {
    gimple stmt = gsi_stmt (*gsi);
    tree dest = gimple_call_arg (stmt, 0);
--- 2271,2277 ----
     the caller does not use the returned value of the function.  */
  
  static bool
! gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi)
  {
    gimple stmt = gsi_stmt (*gsi);
    tree dest = gimple_call_arg (stmt, 0);
*************** gimple_fold_builtin_snprintf (gimple_stm
*** 2338,2349 ****
        if (!orig)
        return false;
  
        if (!orig_len)
!       {
!         orig_len = c_strlen (orig, 1);
!         if (!orig_len)
!           return false;
!       }
  
        /* We could expand this as
         memcpy (str1, str2, cst - 1); str1[cst - 1] = '\0';
--- 2356,2364 ----
        if (!orig)
        return false;
  
+       tree orig_len = get_maxval_strlen (orig, 0);
        if (!orig_len)
!       return false;
  
        /* We could expand this as
         memcpy (str1, str2, cst - 1); str1[cst - 1] = '\0';
*************** gimple_fold_builtin_snprintf (gimple_stm
*** 2390,2402 ****
  /* Fold a call to __builtin_strlen with known length LEN.  */
  
  static bool
! gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi, tree len)
  {
!   if (!len)
!     {
!       gimple stmt = gsi_stmt (*gsi);
!       len = c_strlen (gimple_call_arg (stmt, 0), 0);
!     }
    if (!len)
      return false;
    replace_call_with_value (gsi, len);
--- 2405,2414 ----
  /* Fold a call to __builtin_strlen with known length LEN.  */
  
  static bool
! gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi)
  {
!   gimple stmt = gsi_stmt (*gsi);
!   tree len = get_maxval_strlen (gimple_call_arg (stmt, 0), 0);
    if (!len)
      return false;
    replace_call_with_value (gsi, len);
*************** gimple_fold_builtin_strlen (gimple_stmt_
*** 2404,2542 ****
  }
  
  
! /* Fold builtins at *GSI with knowledge about a length argument.  */
  
  static bool
! gimple_fold_builtin_with_strlen (gimple_stmt_iterator *gsi)
  {
    gimple stmt = gsi_stmt (*gsi);
-   tree val[4];
-   tree a;
-   int arg_idx, type;
-   bitmap visited;
-   bool ignore;
-   location_t loc = gimple_location (stmt);
- 
-   ignore = (gimple_call_lhs (stmt) == NULL);
- 
-   /* Limit the work only for builtins we know how to simplify.  */
    tree callee = gimple_call_fndecl (stmt);
-   switch (DECL_FUNCTION_CODE (callee))
-     {
-     case BUILT_IN_STRLEN:
-     case BUILT_IN_FPUTS:
-     case BUILT_IN_FPUTS_UNLOCKED:
-       arg_idx = 0;
-       type = 0;
-       break;
-     case BUILT_IN_STRCPY:
-     case BUILT_IN_STRNCPY:
-     case BUILT_IN_STRCAT:
-       arg_idx = 1;
-       type = 0;
-       break;
-     case BUILT_IN_MEMCPY_CHK:
-     case BUILT_IN_MEMPCPY_CHK:
-     case BUILT_IN_MEMMOVE_CHK:
-     case BUILT_IN_MEMSET_CHK:
-     case BUILT_IN_STRNCPY_CHK:
-     case BUILT_IN_STPNCPY_CHK:
-       arg_idx = 2;
-       type = 2;
-       break;
-     case BUILT_IN_STRCPY_CHK:
-     case BUILT_IN_STPCPY_CHK:
-       arg_idx = 1;
-       type = 1;
-       break;
-     case BUILT_IN_SNPRINTF_CHK:
-     case BUILT_IN_VSNPRINTF_CHK:
-       arg_idx = 1;
-       type = 2;
-       break;
-     case BUILT_IN_SPRINTF:
-       arg_idx = 2;
-       type = 0;
-       break;
-     case BUILT_IN_SNPRINTF:
-       arg_idx = 3;
-       type = 0;
-       break;
-     default:
-       return false;
-     }
- 
-   int nargs = gimple_call_num_args (stmt);
  
!   /* Try to use the dataflow information gathered by the CCP process.  */
!   visited = BITMAP_ALLOC (NULL);
!   bitmap_clear (visited);
! 
!   memset (val, 0, sizeof (val));
!   if (arg_idx < nargs)
!     {
!       a = gimple_call_arg (stmt, arg_idx);
!       if (!get_maxval_strlen (a, &val[arg_idx], visited, type)
!         || !is_gimple_val (val[arg_idx]))
!       val[arg_idx] = NULL_TREE;
!     }
! 
!   BITMAP_FREE (visited);
  
    switch (DECL_FUNCTION_CODE (callee))
      {
      case BUILT_IN_STRLEN:
!       return gimple_fold_builtin_strlen (gsi, val[0]);
! 
      case BUILT_IN_STRCPY:
!       return gimple_fold_builtin_strcpy (gsi, loc,
                                         gimple_call_arg (stmt, 0),
!                                        gimple_call_arg (stmt, 1),
!                                        val[1]);
! 
      case BUILT_IN_STRNCPY:
!       return gimple_fold_builtin_strncpy (gsi, loc,
                                          gimple_call_arg (stmt, 0),
                                          gimple_call_arg (stmt, 1),
!                                         gimple_call_arg (stmt, 2),
!                                         val[1]);
! 
      case BUILT_IN_STRCAT:
!       return gimple_fold_builtin_strcat (gsi, loc, gimple_call_arg (stmt, 0),
!                                        gimple_call_arg (stmt, 1),
!                                        val[1]);
! 
      case BUILT_IN_FPUTS:
!       return gimple_fold_builtin_fputs (gsi, loc, gimple_call_arg (stmt, 0),
!                                       gimple_call_arg (stmt, 1),
!                                       ignore, false, val[0]);
! 
      case BUILT_IN_FPUTS_UNLOCKED:
!       return gimple_fold_builtin_fputs (gsi, loc, gimple_call_arg (stmt, 0),
!                                       gimple_call_arg (stmt, 1),
!                                       ignore, true, val[0]);
! 
      case BUILT_IN_MEMCPY_CHK:
      case BUILT_IN_MEMPCPY_CHK:
      case BUILT_IN_MEMMOVE_CHK:
      case BUILT_IN_MEMSET_CHK:
!       return gimple_fold_builtin_memory_chk (gsi, loc,
                                             gimple_call_arg (stmt, 0),
                                             gimple_call_arg (stmt, 1),
                                             gimple_call_arg (stmt, 2),
                                             gimple_call_arg (stmt, 3),
-                                            val[2], ignore,
                                             DECL_FUNCTION_CODE (callee));
- 
      case BUILT_IN_STRCPY_CHK:
      case BUILT_IN_STPCPY_CHK:
!       return gimple_fold_builtin_stxcpy_chk (gsi, loc,
                                             gimple_call_arg (stmt, 0),
                                             gimple_call_arg (stmt, 1),
                                             gimple_call_arg (stmt, 2),
-                                            val[1], ignore,
                                             DECL_FUNCTION_CODE (callee));
- 
      case BUILT_IN_STRNCPY_CHK:
      case BUILT_IN_STPNCPY_CHK:
        return gimple_fold_builtin_stxncpy_chk (gsi,
--- 2416,2498 ----
  }
  
  
! /* Fold the non-target builtin at *GSI and return whether any simplification
!    was made.  */
  
  static bool
! gimple_fold_builtin (gimple_stmt_iterator *gsi)
  {
    gimple stmt = gsi_stmt (*gsi);
    tree callee = gimple_call_fndecl (stmt);
  
!   /* Give up for always_inline inline builtins until they are
!      inlined.  */
!   if (avoid_folding_inline_builtin (callee))
!     return false;
  
    switch (DECL_FUNCTION_CODE (callee))
      {
+     case BUILT_IN_BZERO:
+       return gimple_fold_builtin_memset (gsi, integer_zero_node,
+                                        gimple_call_arg (stmt, 1));
+     case BUILT_IN_MEMSET:
+       return gimple_fold_builtin_memset (gsi,
+                                        gimple_call_arg (stmt, 1),
+                                        gimple_call_arg (stmt, 2));
+     case BUILT_IN_BCOPY:
+       return gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 1),
+                                           gimple_call_arg (stmt, 0), 3);
+     case BUILT_IN_MEMCPY:
+       return gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 0),
+                                           gimple_call_arg (stmt, 1), 0);
+     case BUILT_IN_MEMPCPY:
+       return gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 0),
+                                           gimple_call_arg (stmt, 1), 1);
+     case BUILT_IN_MEMMOVE:
+       return gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 0),
+                                           gimple_call_arg (stmt, 1), 3);
+     case BUILT_IN_SPRINTF_CHK:
+     case BUILT_IN_VSPRINTF_CHK:
+       return gimple_fold_builtin_sprintf_chk (gsi, DECL_FUNCTION_CODE 
(callee));
+     case BUILT_IN_STRCAT_CHK:
+       return gimple_fold_builtin_strcat_chk (gsi);
      case BUILT_IN_STRLEN:
!       return gimple_fold_builtin_strlen (gsi);
      case BUILT_IN_STRCPY:
!       return gimple_fold_builtin_strcpy (gsi,
                                         gimple_call_arg (stmt, 0),
!                                        gimple_call_arg (stmt, 1));
      case BUILT_IN_STRNCPY:
!       return gimple_fold_builtin_strncpy (gsi,
                                          gimple_call_arg (stmt, 0),
                                          gimple_call_arg (stmt, 1),
!                                         gimple_call_arg (stmt, 2));
      case BUILT_IN_STRCAT:
!       return gimple_fold_builtin_strcat (gsi, gimple_call_arg (stmt, 0),
!                                        gimple_call_arg (stmt, 1));
      case BUILT_IN_FPUTS:
!       return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
!                                       gimple_call_arg (stmt, 1), false);
      case BUILT_IN_FPUTS_UNLOCKED:
!       return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
!                                       gimple_call_arg (stmt, 1), true);
      case BUILT_IN_MEMCPY_CHK:
      case BUILT_IN_MEMPCPY_CHK:
      case BUILT_IN_MEMMOVE_CHK:
      case BUILT_IN_MEMSET_CHK:
!       return gimple_fold_builtin_memory_chk (gsi,
                                             gimple_call_arg (stmt, 0),
                                             gimple_call_arg (stmt, 1),
                                             gimple_call_arg (stmt, 2),
                                             gimple_call_arg (stmt, 3),
                                             DECL_FUNCTION_CODE (callee));
      case BUILT_IN_STRCPY_CHK:
      case BUILT_IN_STPCPY_CHK:
!       return gimple_fold_builtin_stxcpy_chk (gsi,
                                             gimple_call_arg (stmt, 0),
                                             gimple_call_arg (stmt, 1),
                                             gimple_call_arg (stmt, 2),
                                             DECL_FUNCTION_CODE (callee));
      case BUILT_IN_STRNCPY_CHK:
      case BUILT_IN_STPNCPY_CHK:
        return gimple_fold_builtin_stxncpy_chk (gsi,
*************** gimple_fold_builtin_with_strlen (gimple_
*** 2544,2611 ****
                                              gimple_call_arg (stmt, 1),
                                              gimple_call_arg (stmt, 2),
                                              gimple_call_arg (stmt, 3),
-                                             val[2], ignore,
                                              DECL_FUNCTION_CODE (callee));
- 
      case BUILT_IN_SNPRINTF_CHK:
      case BUILT_IN_VSNPRINTF_CHK:
!       return gimple_fold_builtin_snprintf_chk (gsi, val[1],
                                               DECL_FUNCTION_CODE (callee));
      case BUILT_IN_SNPRINTF:
!       return gimple_fold_builtin_snprintf (gsi, val[3]);
      case BUILT_IN_SPRINTF:
!       return gimple_fold_builtin_sprintf (gsi, val[2]);
!     default:
!       gcc_unreachable ();
!     }
! 
!   return false;
! }
! 
! 
! /* Fold the non-target builtin at *GSI and return whether any simplification
!    was made.  */
! 
! static bool
! gimple_fold_builtin (gimple_stmt_iterator *gsi)
! {
!   gimple stmt = gsi_stmt (*gsi);
!   tree callee = gimple_call_fndecl (stmt);
! 
!   /* Give up for always_inline inline builtins until they are
!      inlined.  */
!   if (avoid_folding_inline_builtin (callee))
!     return false;
! 
!   if (gimple_fold_builtin_with_strlen (gsi))
!     return true;
! 
!   switch (DECL_FUNCTION_CODE (callee))
!     {
!     case BUILT_IN_BZERO:
!       return gimple_fold_builtin_memset (gsi, integer_zero_node,
!                                        gimple_call_arg (stmt, 1));
!     case BUILT_IN_MEMSET:
!       return gimple_fold_builtin_memset (gsi,
!                                        gimple_call_arg (stmt, 1),
!                                        gimple_call_arg (stmt, 2));
!     case BUILT_IN_BCOPY:
!       return gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 1),
!                                           gimple_call_arg (stmt, 0), 3);
!     case BUILT_IN_MEMCPY:
!       return gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 0),
!                                           gimple_call_arg (stmt, 1), 0);
!     case BUILT_IN_MEMPCPY:
!       return gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 0),
!                                           gimple_call_arg (stmt, 1), 1);
!     case BUILT_IN_MEMMOVE:
!       return gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 0),
!                                           gimple_call_arg (stmt, 1), 3);
!     case BUILT_IN_SPRINTF_CHK:
!     case BUILT_IN_VSPRINTF_CHK:
!       return gimple_fold_builtin_sprintf_chk (gsi, DECL_FUNCTION_CODE 
(callee));
!     case BUILT_IN_STRCAT_CHK:
!       return gimple_fold_builtin_strcat_chk (gsi);
      default:;
      }
  
--- 2500,2514 ----
                                              gimple_call_arg (stmt, 1),
                                              gimple_call_arg (stmt, 2),
                                              gimple_call_arg (stmt, 3),
                                              DECL_FUNCTION_CODE (callee));
      case BUILT_IN_SNPRINTF_CHK:
      case BUILT_IN_VSNPRINTF_CHK:
!       return gimple_fold_builtin_snprintf_chk (gsi,
                                               DECL_FUNCTION_CODE (callee));
      case BUILT_IN_SNPRINTF:
!       return gimple_fold_builtin_snprintf (gsi);
      case BUILT_IN_SPRINTF:
!       return gimple_fold_builtin_sprintf (gsi);
      default:;
      }
  

Reply via email to