Commit dcb7fae2 by Richard Biener Committed by Richard Biener

gimple-fold.c (get_maxval_strlen): Add overload wrapping get_maxval_strlen…

gimple-fold.c (get_maxval_strlen): Add overload wrapping get_maxval_strlen inside a more useful API.

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.

From-SVN: r214574
parent 14562eb9
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.
2014-08-27 Yvan Roux <yvan.roux@linaro.org> 2014-08-27 Yvan Roux <yvan.roux@linaro.org>
PR other/62248 PR other/62248
......
...@@ -1285,7 +1285,7 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len) ...@@ -1285,7 +1285,7 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len)
length and 2 for maximum value ARG can have. */ length and 2 for maximum value ARG can have. */
static bool static bool
get_maxval_strlen (tree arg, tree *length, bitmap visited, int type) get_maxval_strlen (tree arg, tree *length, bitmap *visited, int type)
{ {
tree var, val; tree var, val;
gimple def_stmt; gimple def_stmt;
...@@ -1342,7 +1342,9 @@ get_maxval_strlen (tree arg, tree *length, bitmap visited, int type) ...@@ -1342,7 +1342,9 @@ get_maxval_strlen (tree arg, tree *length, bitmap visited, int type)
return false; return false;
/* If we were already here, break the infinite cycle. */ /* If we were already here, break the infinite cycle. */
if (!bitmap_set_bit (visited, SSA_NAME_VERSION (arg))) if (!*visited)
*visited = BITMAP_ALLOC (NULL);
if (!bitmap_set_bit (*visited, SSA_NAME_VERSION (arg)))
return true; return true;
var = arg; var = arg;
...@@ -1399,6 +1401,19 @@ get_maxval_strlen (tree arg, tree *length, bitmap visited, int type) ...@@ -1399,6 +1401,19 @@ get_maxval_strlen (tree arg, tree *length, bitmap visited, int type)
} }
} }
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. /* 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 If LEN is not NULL, it represents the length of the string to be
...@@ -1406,8 +1421,9 @@ get_maxval_strlen (tree arg, tree *length, bitmap visited, int type) ...@@ -1406,8 +1421,9 @@ get_maxval_strlen (tree arg, tree *length, bitmap visited, int type)
static bool static bool
gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi, gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi,
location_t loc, tree dest, tree src, tree len) tree dest, tree src)
{ {
location_t loc = gimple_location (gsi_stmt (*gsi));
tree fn; tree fn;
/* If SRC and DEST are the same (and not volatile), return DEST. */ /* If SRC and DEST are the same (and not volatile), return DEST. */
...@@ -1424,12 +1440,9 @@ gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi, ...@@ -1424,12 +1440,9 @@ gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi,
if (!fn) if (!fn)
return false; return false;
tree len = get_maxval_strlen (src, 1);
if (!len) if (!len)
{ return false;
len = c_strlen (src, 1);
if (! len || TREE_SIDE_EFFECTS (len))
return NULL_TREE;
}
len = fold_convert_loc (loc, size_type_node, len); len = fold_convert_loc (loc, size_type_node, len);
len = size_binop_loc (loc, PLUS_EXPR, len, build_int_cst (size_type_node, 1)); len = size_binop_loc (loc, PLUS_EXPR, len, build_int_cst (size_type_node, 1));
...@@ -1445,9 +1458,10 @@ gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi, ...@@ -1445,9 +1458,10 @@ gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi,
Return NULL_TREE if no simplification can be made. */ Return NULL_TREE if no simplification can be made. */
static bool static bool
gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi, location_t loc, gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi,
tree dest, tree src, tree len, tree slen) tree dest, tree src, tree len)
{ {
location_t loc = gimple_location (gsi_stmt (*gsi));
tree fn; tree fn;
/* If the LEN parameter is zero, return DEST. */ /* If the LEN parameter is zero, return DEST. */
...@@ -1459,14 +1473,12 @@ gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi, location_t loc, ...@@ -1459,14 +1473,12 @@ gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi, location_t loc,
/* We can't compare slen with len as constants below if len is not a /* We can't compare slen with len as constants below if len is not a
constant. */ constant. */
if (len == 0 || TREE_CODE (len) != INTEGER_CST) if (TREE_CODE (len) != INTEGER_CST)
return false; return false;
if (!slen)
slen = c_strlen (src, 1);
/* Now, we must be passed a constant src ptr parameter. */ /* Now, we must be passed a constant src ptr parameter. */
if (slen == 0 || TREE_CODE (slen) != INTEGER_CST) tree slen = get_maxval_strlen (src, 1);
if (!slen || TREE_CODE (slen) != INTEGER_CST)
return false; return false;
slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1)); slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
...@@ -1509,11 +1521,10 @@ gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi, location_t loc, ...@@ -1509,11 +1521,10 @@ gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi, location_t loc,
form of the builtin function call. */ form of the builtin function call. */
static bool static bool
gimple_fold_builtin_strcat (gimple_stmt_iterator *gsi, gimple_fold_builtin_strcat (gimple_stmt_iterator *gsi, tree dst, tree src)
location_t loc ATTRIBUTE_UNUSED, tree dst, tree src,
tree len)
{ {
gimple stmt = gsi_stmt (*gsi); gimple stmt = gsi_stmt (*gsi);
location_t loc = gimple_location (stmt);
const char *p = c_getstr (src); const char *p = c_getstr (src);
...@@ -1537,9 +1548,8 @@ gimple_fold_builtin_strcat (gimple_stmt_iterator *gsi, ...@@ -1537,9 +1548,8 @@ gimple_fold_builtin_strcat (gimple_stmt_iterator *gsi,
/* If the length of the source string isn't computable don't /* If the length of the source string isn't computable don't
split strcat into strlen and memcpy. */ split strcat into strlen and memcpy. */
tree len = get_maxval_strlen (src, 0);
if (! len) if (! len)
len = c_strlen (src, 1);
if (! len || TREE_SIDE_EFFECTS (len))
return false; return false;
/* Create strlen (dst). */ /* Create strlen (dst). */
...@@ -1631,10 +1641,11 @@ gimple_fold_builtin_strcat_chk (gimple_stmt_iterator *gsi) ...@@ -1631,10 +1641,11 @@ gimple_fold_builtin_strcat_chk (gimple_stmt_iterator *gsi)
static bool static bool
gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi, gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi,
location_t loc ATTRIBUTE_UNUSED,
tree arg0, tree arg1, tree arg0, tree arg1,
bool ignore, bool unlocked, tree len) bool unlocked)
{ {
gimple stmt = gsi_stmt (*gsi);
/* If we're using an unlocked function, assume the other unlocked /* If we're using an unlocked function, assume the other unlocked
functions exist explicitly. */ functions exist explicitly. */
tree const fn_fputc = (unlocked tree const fn_fputc = (unlocked
...@@ -1645,14 +1656,12 @@ gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi, ...@@ -1645,14 +1656,12 @@ gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi,
: builtin_decl_implicit (BUILT_IN_FWRITE)); : builtin_decl_implicit (BUILT_IN_FWRITE));
/* If the return value is used, don't do the transformation. */ /* If the return value is used, don't do the transformation. */
if (!ignore) if (gimple_call_lhs (stmt))
return false; return false;
if (! len)
len = c_strlen (arg0, 0);
/* Get the length of the string passed to fputs. If the length /* Get the length of the string passed to fputs. If the length
can't be determined, punt. */ can't be determined, punt. */
tree len = get_maxval_strlen (arg0, 0);
if (!len if (!len
|| TREE_CODE (len) != INTEGER_CST) || TREE_CODE (len) != INTEGER_CST)
return false; return false;
...@@ -1708,11 +1717,12 @@ gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi, ...@@ -1708,11 +1717,12 @@ gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi,
static bool static bool
gimple_fold_builtin_memory_chk (gimple_stmt_iterator *gsi, gimple_fold_builtin_memory_chk (gimple_stmt_iterator *gsi,
location_t loc,
tree dest, tree src, tree len, tree size, tree dest, tree src, tree len, tree size,
tree maxlen, bool ignore,
enum built_in_function fcode) 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; tree fn;
/* If SRC and DEST are the same (and not volatile), return DEST /* If SRC and DEST are the same (and not volatile), return DEST
...@@ -1738,6 +1748,7 @@ gimple_fold_builtin_memory_chk (gimple_stmt_iterator *gsi, ...@@ -1738,6 +1748,7 @@ gimple_fold_builtin_memory_chk (gimple_stmt_iterator *gsi,
if (! tree_fits_uhwi_p (size)) if (! tree_fits_uhwi_p (size))
return false; return false;
tree maxlen = get_maxval_strlen (len, 2);
if (! integer_all_onesp (size)) if (! integer_all_onesp (size))
{ {
if (! tree_fits_uhwi_p (len)) if (! tree_fits_uhwi_p (len))
...@@ -1806,11 +1817,13 @@ gimple_fold_builtin_memory_chk (gimple_stmt_iterator *gsi, ...@@ -1806,11 +1817,13 @@ gimple_fold_builtin_memory_chk (gimple_stmt_iterator *gsi,
static bool static bool
gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi, gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi,
location_t loc, tree dest, tree dest,
tree src, tree size, tree src, tree size,
tree maxlen, bool ignore,
enum built_in_function fcode) 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; tree len, fn;
/* If SRC and DEST are the same (and not volatile), return DEST. */ /* If SRC and DEST are the same (and not volatile), return DEST. */
...@@ -1823,6 +1836,7 @@ gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi, ...@@ -1823,6 +1836,7 @@ gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi,
if (! tree_fits_uhwi_p (size)) if (! tree_fits_uhwi_p (size))
return false; return false;
tree maxlen = get_maxval_strlen (src, 1);
if (! integer_all_onesp (size)) if (! integer_all_onesp (size))
{ {
len = c_strlen (src, 1); len = c_strlen (src, 1);
...@@ -1894,9 +1908,11 @@ gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi, ...@@ -1894,9 +1908,11 @@ gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi,
static bool static bool
gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi, gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi,
tree dest, tree src, tree dest, tree src,
tree len, tree size, tree maxlen, bool ignore, tree len, tree size,
enum built_in_function fcode) enum built_in_function fcode)
{ {
gimple stmt = gsi_stmt (*gsi);
bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
tree fn; tree fn;
if (fcode == BUILT_IN_STPNCPY_CHK && ignore) if (fcode == BUILT_IN_STPNCPY_CHK && ignore)
...@@ -1915,6 +1931,7 @@ gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi, ...@@ -1915,6 +1931,7 @@ gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi,
if (! tree_fits_uhwi_p (size)) if (! tree_fits_uhwi_p (size))
return false; return false;
tree maxlen = get_maxval_strlen (len, 2);
if (! integer_all_onesp (size)) if (! integer_all_onesp (size))
{ {
if (! tree_fits_uhwi_p (len)) if (! tree_fits_uhwi_p (len))
...@@ -1951,7 +1968,7 @@ gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi, ...@@ -1951,7 +1968,7 @@ gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi,
static bool static bool
gimple_fold_builtin_snprintf_chk (gimple_stmt_iterator *gsi, gimple_fold_builtin_snprintf_chk (gimple_stmt_iterator *gsi,
tree maxlen, enum built_in_function fcode) enum built_in_function fcode)
{ {
gimple stmt = gsi_stmt (*gsi); gimple stmt = gsi_stmt (*gsi);
tree dest, size, len, fn, fmt, flag; tree dest, size, len, fn, fmt, flag;
...@@ -1972,6 +1989,7 @@ gimple_fold_builtin_snprintf_chk (gimple_stmt_iterator *gsi, ...@@ -1972,6 +1989,7 @@ gimple_fold_builtin_snprintf_chk (gimple_stmt_iterator *gsi,
if (! integer_all_onesp (size)) if (! integer_all_onesp (size))
{ {
tree maxlen = get_maxval_strlen (len, 2);
if (! tree_fits_uhwi_p (len)) if (! tree_fits_uhwi_p (len))
{ {
/* If LEN is not constant, try MAXLEN too. /* If LEN is not constant, try MAXLEN too.
...@@ -2128,7 +2146,7 @@ gimple_fold_builtin_sprintf_chk (gimple_stmt_iterator *gsi, ...@@ -2128,7 +2146,7 @@ gimple_fold_builtin_sprintf_chk (gimple_stmt_iterator *gsi,
the caller does not use the returned value of the function. */ the caller does not use the returned value of the function. */
static bool static bool
gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi, tree orig_len) gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi)
{ {
gimple stmt = gsi_stmt (*gsi); gimple stmt = gsi_stmt (*gsi);
tree dest = gimple_call_arg (stmt, 0); tree dest = gimple_call_arg (stmt, 0);
...@@ -2206,10 +2224,10 @@ gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi, tree orig_len) ...@@ -2206,10 +2224,10 @@ gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi, tree orig_len)
if (!orig) if (!orig)
return false; return false;
if (gimple_call_lhs (stmt) tree orig_len = NULL_TREE;
&& !orig_len) if (gimple_call_lhs (stmt))
{ {
orig_len = c_strlen (orig, 1); orig_len = get_maxval_strlen (orig, 0);
if (!orig_len) if (!orig_len)
return false; return false;
} }
...@@ -2253,7 +2271,7 @@ gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi, tree orig_len) ...@@ -2253,7 +2271,7 @@ gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi, tree orig_len)
the caller does not use the returned value of the function. */ the caller does not use the returned value of the function. */
static bool static bool
gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi, tree orig_len) gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi)
{ {
gimple stmt = gsi_stmt (*gsi); gimple stmt = gsi_stmt (*gsi);
tree dest = gimple_call_arg (stmt, 0); tree dest = gimple_call_arg (stmt, 0);
...@@ -2338,12 +2356,9 @@ gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi, tree orig_len) ...@@ -2338,12 +2356,9 @@ gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi, tree orig_len)
if (!orig) if (!orig)
return false; return false;
tree orig_len = get_maxval_strlen (orig, 0);
if (!orig_len) if (!orig_len)
{ return false;
orig_len = c_strlen (orig, 1);
if (!orig_len)
return false;
}
/* We could expand this as /* We could expand this as
memcpy (str1, str2, cst - 1); str1[cst - 1] = '\0'; memcpy (str1, str2, cst - 1); str1[cst - 1] = '\0';
...@@ -2390,13 +2405,10 @@ gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi, tree orig_len) ...@@ -2390,13 +2405,10 @@ gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi, tree orig_len)
/* Fold a call to __builtin_strlen with known length LEN. */ /* Fold a call to __builtin_strlen with known length LEN. */
static bool static bool
gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi, tree len) gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi)
{ {
if (!len) gimple stmt = gsi_stmt (*gsi);
{ tree len = get_maxval_strlen (gimple_call_arg (stmt, 0), 0);
gimple stmt = gsi_stmt (*gsi);
len = c_strlen (gimple_call_arg (stmt, 0), 0);
}
if (!len) if (!len)
return false; return false;
replace_call_with_value (gsi, len); replace_call_with_value (gsi, len);
...@@ -2404,139 +2416,83 @@ gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi, tree len) ...@@ -2404,139 +2416,83 @@ gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi, tree len)
} }
/* Fold builtins at *GSI with knowledge about a length argument. */ /* Fold the non-target builtin at *GSI and return whether any simplification
was made. */
static bool static bool
gimple_fold_builtin_with_strlen (gimple_stmt_iterator *gsi) gimple_fold_builtin (gimple_stmt_iterator *gsi)
{ {
gimple stmt = gsi_stmt (*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); 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); /* Give up for always_inline inline builtins until they are
inlined. */
if (avoid_folding_inline_builtin (callee))
return false;
switch (DECL_FUNCTION_CODE (callee)) 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: case BUILT_IN_STRLEN:
return gimple_fold_builtin_strlen (gsi, val[0]); return gimple_fold_builtin_strlen (gsi);
case BUILT_IN_STRCPY: case BUILT_IN_STRCPY:
return gimple_fold_builtin_strcpy (gsi, loc, return gimple_fold_builtin_strcpy (gsi,
gimple_call_arg (stmt, 0), gimple_call_arg (stmt, 0),
gimple_call_arg (stmt, 1), gimple_call_arg (stmt, 1));
val[1]);
case BUILT_IN_STRNCPY: case BUILT_IN_STRNCPY:
return gimple_fold_builtin_strncpy (gsi, loc, return gimple_fold_builtin_strncpy (gsi,
gimple_call_arg (stmt, 0), gimple_call_arg (stmt, 0),
gimple_call_arg (stmt, 1), gimple_call_arg (stmt, 1),
gimple_call_arg (stmt, 2), gimple_call_arg (stmt, 2));
val[1]);
case BUILT_IN_STRCAT: case BUILT_IN_STRCAT:
return gimple_fold_builtin_strcat (gsi, loc, gimple_call_arg (stmt, 0), return gimple_fold_builtin_strcat (gsi, gimple_call_arg (stmt, 0),
gimple_call_arg (stmt, 1), gimple_call_arg (stmt, 1));
val[1]);
case BUILT_IN_FPUTS: case BUILT_IN_FPUTS:
return gimple_fold_builtin_fputs (gsi, loc, gimple_call_arg (stmt, 0), return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
gimple_call_arg (stmt, 1), gimple_call_arg (stmt, 1), false);
ignore, false, val[0]);
case BUILT_IN_FPUTS_UNLOCKED: case BUILT_IN_FPUTS_UNLOCKED:
return gimple_fold_builtin_fputs (gsi, loc, gimple_call_arg (stmt, 0), return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
gimple_call_arg (stmt, 1), gimple_call_arg (stmt, 1), true);
ignore, true, val[0]);
case BUILT_IN_MEMCPY_CHK: case BUILT_IN_MEMCPY_CHK:
case BUILT_IN_MEMPCPY_CHK: case BUILT_IN_MEMPCPY_CHK:
case BUILT_IN_MEMMOVE_CHK: case BUILT_IN_MEMMOVE_CHK:
case BUILT_IN_MEMSET_CHK: case BUILT_IN_MEMSET_CHK:
return gimple_fold_builtin_memory_chk (gsi, loc, return gimple_fold_builtin_memory_chk (gsi,
gimple_call_arg (stmt, 0), gimple_call_arg (stmt, 0),
gimple_call_arg (stmt, 1), gimple_call_arg (stmt, 1),
gimple_call_arg (stmt, 2), gimple_call_arg (stmt, 2),
gimple_call_arg (stmt, 3), gimple_call_arg (stmt, 3),
val[2], ignore,
DECL_FUNCTION_CODE (callee)); DECL_FUNCTION_CODE (callee));
case BUILT_IN_STRCPY_CHK: case BUILT_IN_STRCPY_CHK:
case BUILT_IN_STPCPY_CHK: case BUILT_IN_STPCPY_CHK:
return gimple_fold_builtin_stxcpy_chk (gsi, loc, return gimple_fold_builtin_stxcpy_chk (gsi,
gimple_call_arg (stmt, 0), gimple_call_arg (stmt, 0),
gimple_call_arg (stmt, 1), gimple_call_arg (stmt, 1),
gimple_call_arg (stmt, 2), gimple_call_arg (stmt, 2),
val[1], ignore,
DECL_FUNCTION_CODE (callee)); DECL_FUNCTION_CODE (callee));
case BUILT_IN_STRNCPY_CHK: case BUILT_IN_STRNCPY_CHK:
case BUILT_IN_STPNCPY_CHK: case BUILT_IN_STPNCPY_CHK:
return gimple_fold_builtin_stxncpy_chk (gsi, return gimple_fold_builtin_stxncpy_chk (gsi,
...@@ -2544,68 +2500,15 @@ gimple_fold_builtin_with_strlen (gimple_stmt_iterator *gsi) ...@@ -2544,68 +2500,15 @@ gimple_fold_builtin_with_strlen (gimple_stmt_iterator *gsi)
gimple_call_arg (stmt, 1), gimple_call_arg (stmt, 1),
gimple_call_arg (stmt, 2), gimple_call_arg (stmt, 2),
gimple_call_arg (stmt, 3), gimple_call_arg (stmt, 3),
val[2], ignore,
DECL_FUNCTION_CODE (callee)); DECL_FUNCTION_CODE (callee));
case BUILT_IN_SNPRINTF_CHK: case BUILT_IN_SNPRINTF_CHK:
case BUILT_IN_VSNPRINTF_CHK: case BUILT_IN_VSNPRINTF_CHK:
return gimple_fold_builtin_snprintf_chk (gsi, val[1], return gimple_fold_builtin_snprintf_chk (gsi,
DECL_FUNCTION_CODE (callee)); DECL_FUNCTION_CODE (callee));
case BUILT_IN_SNPRINTF: case BUILT_IN_SNPRINTF:
return gimple_fold_builtin_snprintf (gsi, val[3]); return gimple_fold_builtin_snprintf (gsi);
case BUILT_IN_SPRINTF: case BUILT_IN_SPRINTF:
return gimple_fold_builtin_sprintf (gsi, val[2]); return gimple_fold_builtin_sprintf (gsi);
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:; default:;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment