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:
parent
b0122457bc
commit
2625bb5df5
|
@ -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
|
||||
|
|
101
gcc/builtins.c
101
gcc/builtins.c
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue