This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Refactor get_maxval_strlen and gimple_fold_builtin_with_strlen
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 27 Aug 2014 12:32:42 +0200 (CEST)
- Subject: [PATCH] Refactor get_maxval_strlen and gimple_fold_builtin_with_strlen
- Authentication-results: sourceware.org; auth=none
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 <rguenther@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:;
}