builtins.c (fold_builtin_0): Remove unused ignore parameter.

2014-12-08  Richard Biener  <rguenther@suse.de>

	* builtins.c (fold_builtin_0): Remove unused ignore parameter.
	(fold_builtin_1): Likewise.
	(fold_builtin_3): Likewise.
	(fold_builtin_varargs): Likewise.
	(fold_builtin_2): Likewise.  Do not fold stpcpy here.
	(fold_builtin_n): Adjust.
	(fold_builtin_stpcpy): Move to gimple-fold.c.
	(gimple_fold_builtin_stpcpy): Moved and gimplified from builtins.c.
	(gimple_fold_builtin): Fold stpcpy here.

From-SVN: r218477
This commit is contained in:
Richard Biener 2014-12-08 09:20:35 +00:00 committed by Richard Biener
parent b0122457bc
commit 2625bb5df5
3 changed files with 99 additions and 80 deletions

View File

@ -1,3 +1,15 @@
2014-12-08 Richard Biener <rguenther@suse.de>
* builtins.c (fold_builtin_0): Remove unused ignore parameter.
(fold_builtin_1): Likewise.
(fold_builtin_3): Likewise.
(fold_builtin_varargs): Likewise.
(fold_builtin_2): Likewise. Do not fold stpcpy here.
(fold_builtin_n): Adjust.
(fold_builtin_stpcpy): Move to gimple-fold.c.
(gimple_fold_builtin_stpcpy): Moved and gimplified from builtins.c.
(gimple_fold_builtin): Fold stpcpy here.
2014-12-07 Trevor Saunders <tsaunders@mozilla.com>
* symtab.c (symtab_node::verify): Check for section attribute before

View File

@ -191,11 +191,11 @@ static tree fold_builtin_fabs (location_t, tree, tree);
static tree fold_builtin_abs (location_t, tree, tree);
static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code,
enum tree_code);
static tree fold_builtin_0 (location_t, tree, bool);
static tree fold_builtin_1 (location_t, tree, tree, bool);
static tree fold_builtin_2 (location_t, tree, tree, tree, bool);
static tree fold_builtin_3 (location_t, tree, tree, tree, tree, bool);
static tree fold_builtin_varargs (location_t, tree, tree*, int, bool);
static tree fold_builtin_0 (location_t, tree);
static tree fold_builtin_1 (location_t, tree, tree);
static tree fold_builtin_2 (location_t, tree, tree, tree);
static tree fold_builtin_3 (location_t, tree, tree, tree, tree);
static tree fold_builtin_varargs (location_t, tree, tree*, int);
static tree fold_builtin_strpbrk (location_t, tree, tree, tree);
static tree fold_builtin_strstr (location_t, tree, tree, tree);
@ -8657,47 +8657,6 @@ fold_builtin_exponent (location_t loc, tree fndecl, tree arg,
return NULL_TREE;
}
/* Fold function call to builtin stpcpy with arguments DEST and SRC.
Return NULL_TREE if no simplification can be made. */
static tree
fold_builtin_stpcpy (location_t loc, tree fndecl, tree dest, tree src)
{
tree fn, len, lenp1, call, type;
if (!validate_arg (dest, POINTER_TYPE)
|| !validate_arg (src, POINTER_TYPE))
return NULL_TREE;
len = c_strlen (src, 1);
if (!len
|| TREE_CODE (len) != INTEGER_CST)
return NULL_TREE;
if (optimize_function_for_size_p (cfun)
/* If length is zero it's small enough. */
&& !integer_zerop (len))
return NULL_TREE;
fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
if (!fn)
return NULL_TREE;
lenp1 = size_binop_loc (loc, PLUS_EXPR,
fold_convert_loc (loc, size_type_node, len),
build_int_cst (size_type_node, 1));
/* We use dest twice in building our expression. Save it from
multiple expansions. */
dest = builtin_save_expr (dest);
call = build_call_expr_loc (loc, fn, 3, dest, src, lenp1);
type = TREE_TYPE (TREE_TYPE (fndecl));
dest = fold_build_pointer_plus_loc (loc, dest, len);
dest = fold_convert_loc (loc, type, dest);
dest = omit_one_operand_loc (loc, type, dest, call);
return dest;
}
/* Fold function call to builtin memchr. ARG1, ARG2 and LEN are the
arguments to the call, and TYPE is its return type.
Return NULL_TREE if no simplification can be made. */
@ -9857,11 +9816,10 @@ fold_builtin_arith_overflow (location_t loc, enum built_in_function fcode,
}
/* Fold a call to built-in function FNDECL with 0 arguments.
IGNORE is true if the result of the function call is ignored. This
function returns NULL_TREE if no simplification was possible. */
This function returns NULL_TREE if no simplification was possible. */
static tree
fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
fold_builtin_0 (location_t loc, tree fndecl)
{
tree type = TREE_TYPE (TREE_TYPE (fndecl));
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
@ -9886,11 +9844,10 @@ fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
}
/* Fold a call to built-in function FNDECL with 1 argument, ARG0.
IGNORE is true if the result of the function call is ignored. This
function returns NULL_TREE if no simplification was possible. */
This function returns NULL_TREE if no simplification was possible. */
static tree
fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool)
fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
{
tree type = TREE_TYPE (TREE_TYPE (fndecl));
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
@ -10301,11 +10258,10 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool)
}
/* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
IGNORE is true if the result of the function call is ignored. This
function returns NULL_TREE if no simplification was possible. */
This function returns NULL_TREE if no simplification was possible. */
static tree
fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1)
{
tree type = TREE_TYPE (TREE_TYPE (fndecl));
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
@ -10392,19 +10348,6 @@ fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
case BUILT_IN_RINDEX:
return fold_builtin_strrchr (loc, arg0, arg1, type);
case BUILT_IN_STPCPY:
if (ignore)
{
tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
if (!fn)
break;
return build_call_expr_loc (loc, fn, 2, arg0, arg1);
}
else
return fold_builtin_stpcpy (loc, fndecl, arg0, arg1);
break;
case BUILT_IN_STRCMP:
return fold_builtin_strcmp (loc, arg0, arg1);
@ -10469,12 +10412,12 @@ fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
}
/* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
and ARG2. IGNORE is true if the result of the function call is ignored.
and ARG2.
This function returns NULL_TREE if no simplification was possible. */
static tree
fold_builtin_3 (location_t loc, tree fndecl,
tree arg0, tree arg1, tree arg2, bool)
tree arg0, tree arg1, tree arg2)
{
tree type = TREE_TYPE (TREE_TYPE (fndecl));
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
@ -10543,26 +10486,26 @@ fold_builtin_3 (location_t loc, tree fndecl,
simplification was possible. */
tree
fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore)
fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool)
{
tree ret = NULL_TREE;
switch (nargs)
{
case 0:
ret = fold_builtin_0 (loc, fndecl, ignore);
ret = fold_builtin_0 (loc, fndecl);
break;
case 1:
ret = fold_builtin_1 (loc, fndecl, args[0], ignore);
ret = fold_builtin_1 (loc, fndecl, args[0]);
break;
case 2:
ret = fold_builtin_2 (loc, fndecl, args[0], args[1], ignore);
ret = fold_builtin_2 (loc, fndecl, args[0], args[1]);
break;
case 3:
ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2], ignore);
ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2]);
break;
default:
ret = fold_builtin_varargs (loc, fndecl, args, nargs, ignore);
ret = fold_builtin_varargs (loc, fndecl, args, nargs);
break;
}
if (ret)
@ -11656,12 +11599,10 @@ fold_builtin_object_size (tree ptr, tree ost)
need special handling; we need to store the arguments in a convenient
data structure before attempting any folding. Fortunately there are
only a few builtins that fall into this category. FNDECL is the
function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
result of the function call is ignored. */
function, EXP is the CALL_EXPR for the call. */
static tree
fold_builtin_varargs (location_t loc, tree fndecl, tree *args, int nargs,
bool ignore ATTRIBUTE_UNUSED)
fold_builtin_varargs (location_t loc, tree fndecl, tree *args, int nargs)
{
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
tree ret = NULL_TREE;

View File

@ -2052,6 +2052,70 @@ gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi,
return true;
}
/* Fold function call to builtin stpcpy with arguments DEST and SRC.
Return NULL_TREE if no simplification can be made. */
static bool
gimple_fold_builtin_stpcpy (gimple_stmt_iterator *gsi)
{
gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
location_t loc = gimple_location (stmt);
tree dest = gimple_call_arg (stmt, 0);
tree src = gimple_call_arg (stmt, 1);
tree fn, len, lenp1;
/* If the result is unused, replace stpcpy with strcpy. */
if (gimple_call_lhs (stmt) == NULL_TREE)
{
tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
if (!fn)
return false;
gimple_call_set_fndecl (stmt, fn);
fold_stmt (gsi);
return true;
}
len = c_strlen (src, 1);
if (!len
|| TREE_CODE (len) != INTEGER_CST)
return false;
if (optimize_function_for_size_p (cfun)
/* If length is zero it's small enough. */
&& !integer_zerop (len))
return false;
/* If the source has a known length replace stpcpy with memcpy. */
fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
if (!fn)
return false;
gimple_seq stmts = NULL;
tree tem = gimple_convert (&stmts, loc, size_type_node, len);
lenp1 = gimple_build (&stmts, loc, PLUS_EXPR, size_type_node,
tem, build_int_cst (size_type_node, 1));
gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
gcall *repl = gimple_build_call (fn, 3, dest, src, lenp1);
gimple_set_vuse (repl, gimple_vuse (stmt));
gimple_set_vdef (repl, gimple_vdef (stmt));
if (gimple_vdef (repl)
&& TREE_CODE (gimple_vdef (repl)) == SSA_NAME)
SSA_NAME_DEF_STMT (gimple_vdef (repl)) = repl;
gsi_insert_before (gsi, repl, GSI_SAME_STMT);
/* Replace the result with dest + len. */
stmts = NULL;
tem = gimple_convert (&stmts, loc, sizetype, len);
gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
gassign *ret = gimple_build_assign (gimple_call_lhs (stmt),
POINTER_PLUS_EXPR, dest, tem);
gsi_replace (gsi, ret, true);
/* Finally fold the memcpy call. */
gimple_stmt_iterator gsi2 = *gsi;
gsi_prev (&gsi2);
fold_stmt (&gsi2);
return true;
}
/* Fold a call EXP to {,v}snprintf having NARGS passed as ARGS. Return
NULL_TREE if a normal call should be emitted rather than expanding
the function inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
@ -2849,6 +2913,8 @@ gimple_fold_builtin (gimple_stmt_iterator *gsi)
gimple_call_arg (stmt, 2),
gimple_call_arg (stmt, 3),
fcode);
case BUILT_IN_STPCPY:
return gimple_fold_builtin_stpcpy (gsi);
case BUILT_IN_STRCPY_CHK:
case BUILT_IN_STPCPY_CHK:
return gimple_fold_builtin_stxcpy_chk (gsi,