Commit 2625bb5d by Richard Biener Committed by Richard Biener

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
parent b0122457
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> 2014-12-07 Trevor Saunders <tsaunders@mozilla.com>
* symtab.c (symtab_node::verify): Check for section attribute before * symtab.c (symtab_node::verify): Check for section attribute before
...@@ -191,11 +191,11 @@ static tree fold_builtin_fabs (location_t, tree, tree); ...@@ -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_abs (location_t, tree, tree);
static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code, static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code,
enum tree_code); enum tree_code);
static tree fold_builtin_0 (location_t, tree, bool); static tree fold_builtin_0 (location_t, tree);
static tree fold_builtin_1 (location_t, tree, tree, bool); static tree fold_builtin_1 (location_t, tree, tree);
static tree fold_builtin_2 (location_t, tree, tree, tree, bool); static tree fold_builtin_2 (location_t, tree, tree, tree);
static tree fold_builtin_3 (location_t, tree, tree, tree, tree, bool); static tree fold_builtin_3 (location_t, tree, tree, tree, tree);
static tree fold_builtin_varargs (location_t, tree, tree*, int, bool); static tree fold_builtin_varargs (location_t, tree, tree*, int);
static tree fold_builtin_strpbrk (location_t, tree, tree, tree); static tree fold_builtin_strpbrk (location_t, tree, tree, tree);
static tree fold_builtin_strstr (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, ...@@ -8657,47 +8657,6 @@ fold_builtin_exponent (location_t loc, tree fndecl, tree arg,
return NULL_TREE; 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 /* Fold function call to builtin memchr. ARG1, ARG2 and LEN are the
arguments to the call, and TYPE is its return type. arguments to the call, and TYPE is its return type.
Return NULL_TREE if no simplification can be made. */ 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, ...@@ -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. /* Fold a call to built-in function FNDECL with 0 arguments.
IGNORE is true if the result of the function call is ignored. This This function returns NULL_TREE if no simplification was possible. */
function returns NULL_TREE if no simplification was possible. */
static tree 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)); tree type = TREE_TYPE (TREE_TYPE (fndecl));
enum built_in_function fcode = DECL_FUNCTION_CODE (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) ...@@ -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. /* 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 This function returns NULL_TREE if no simplification was possible. */
function returns NULL_TREE if no simplification was possible. */
static tree 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)); tree type = TREE_TYPE (TREE_TYPE (fndecl));
enum built_in_function fcode = DECL_FUNCTION_CODE (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) ...@@ -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. /* 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 This function returns NULL_TREE if no simplification was possible. */
function returns NULL_TREE if no simplification was possible. */
static tree 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)); tree type = TREE_TYPE (TREE_TYPE (fndecl));
enum built_in_function fcode = DECL_FUNCTION_CODE (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) ...@@ -10392,19 +10348,6 @@ fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
case BUILT_IN_RINDEX: case BUILT_IN_RINDEX:
return fold_builtin_strrchr (loc, arg0, arg1, type); 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: case BUILT_IN_STRCMP:
return fold_builtin_strcmp (loc, arg0, arg1); 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) ...@@ -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, /* 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. */ This function returns NULL_TREE if no simplification was possible. */
static tree static tree
fold_builtin_3 (location_t loc, tree fndecl, 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)); tree type = TREE_TYPE (TREE_TYPE (fndecl));
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
...@@ -10543,26 +10486,26 @@ fold_builtin_3 (location_t loc, tree fndecl, ...@@ -10543,26 +10486,26 @@ fold_builtin_3 (location_t loc, tree fndecl,
simplification was possible. */ simplification was possible. */
tree 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; tree ret = NULL_TREE;
switch (nargs) switch (nargs)
{ {
case 0: case 0:
ret = fold_builtin_0 (loc, fndecl, ignore); ret = fold_builtin_0 (loc, fndecl);
break; break;
case 1: case 1:
ret = fold_builtin_1 (loc, fndecl, args[0], ignore); ret = fold_builtin_1 (loc, fndecl, args[0]);
break; break;
case 2: case 2:
ret = fold_builtin_2 (loc, fndecl, args[0], args[1], ignore); ret = fold_builtin_2 (loc, fndecl, args[0], args[1]);
break; break;
case 3: 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; break;
default: default:
ret = fold_builtin_varargs (loc, fndecl, args, nargs, ignore); ret = fold_builtin_varargs (loc, fndecl, args, nargs);
break; break;
} }
if (ret) if (ret)
...@@ -11656,12 +11599,10 @@ fold_builtin_object_size (tree ptr, tree ost) ...@@ -11656,12 +11599,10 @@ fold_builtin_object_size (tree ptr, tree ost)
need special handling; we need to store the arguments in a convenient need special handling; we need to store the arguments in a convenient
data structure before attempting any folding. Fortunately there are data structure before attempting any folding. Fortunately there are
only a few builtins that fall into this category. FNDECL is the 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 function, EXP is the CALL_EXPR for the call. */
result of the function call is ignored. */
static tree static tree
fold_builtin_varargs (location_t loc, tree fndecl, tree *args, int nargs, fold_builtin_varargs (location_t loc, tree fndecl, tree *args, int nargs)
bool ignore ATTRIBUTE_UNUSED)
{ {
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
tree ret = NULL_TREE; tree ret = NULL_TREE;
......
...@@ -2052,6 +2052,70 @@ gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi, ...@@ -2052,6 +2052,70 @@ gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi,
return true; 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 /* 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 NULL_TREE if a normal call should be emitted rather than expanding
the function inline. FCODE is either BUILT_IN_SNPRINTF_CHK or the function inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
...@@ -2849,6 +2913,8 @@ gimple_fold_builtin (gimple_stmt_iterator *gsi) ...@@ -2849,6 +2913,8 @@ gimple_fold_builtin (gimple_stmt_iterator *gsi)
gimple_call_arg (stmt, 2), gimple_call_arg (stmt, 2),
gimple_call_arg (stmt, 3), gimple_call_arg (stmt, 3),
fcode); fcode);
case BUILT_IN_STPCPY:
return gimple_fold_builtin_stpcpy (gsi);
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, return gimple_fold_builtin_stxcpy_chk (gsi,
......
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