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:; }