summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-ccp.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r--gcc/tree-ssa-ccp.c96
1 files changed, 58 insertions, 38 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 459894b24f0..673415c1ca0 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -939,15 +939,13 @@ ccp_fold (tree stmt)
/* We may be able to fold away calls to builtin functions if their
arguments are constants. */
else if (code == CALL_EXPR
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == ADDR_EXPR
- && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0))
- == FUNCTION_DECL)
- && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0)))
+ && TREE_CODE (CALL_EXPR_FN (rhs)) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (CALL_EXPR_FN (rhs), 0)) == FUNCTION_DECL
+ && DECL_BUILT_IN (TREE_OPERAND (CALL_EXPR_FN (rhs), 0)))
{
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_USE))
{
tree *orig, var;
- tree fndecl, arglist;
size_t i = 0;
ssa_op_iter iter;
use_operand_p var_p;
@@ -959,9 +957,7 @@ ccp_fold (tree stmt)
/* Substitute operands with their values and try to fold. */
replace_uses_in (stmt, NULL, const_val);
- fndecl = get_callee_fndecl (rhs);
- arglist = TREE_OPERAND (rhs, 1);
- retval = fold_builtin (fndecl, arglist, false);
+ retval = fold_call_expr (rhs, false);
/* Restore operands to their original form. */
i = 0;
@@ -2219,18 +2215,18 @@ static tree
ccp_fold_builtin (tree stmt, tree fn)
{
tree result, val[3];
- tree callee, arglist, a;
+ tree callee, a;
int arg_mask, i, type;
bitmap visited;
bool ignore;
+ call_expr_arg_iterator iter;
+ int nargs;
ignore = TREE_CODE (stmt) != GIMPLE_MODIFY_STMT;
/* First try the generic builtin folder. If that succeeds, return the
result directly. */
- callee = get_callee_fndecl (fn);
- arglist = TREE_OPERAND (fn, 1);
- result = fold_builtin (callee, arglist, ignore);
+ result = fold_call_expr (fn, ignore);
if (result)
{
if (ignore)
@@ -2239,12 +2235,14 @@ ccp_fold_builtin (tree stmt, tree fn)
}
/* Ignore MD builtins. */
+ callee = get_callee_fndecl (fn);
if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_MD)
return NULL_TREE;
/* If the builtin could not be folded, and it has no argument list,
we're done. */
- if (!arglist)
+ nargs = call_expr_nargs (fn);
+ if (nargs == 0)
return NULL_TREE;
/* Limit the work only for builtins we know how to simplify. */
@@ -2287,15 +2285,17 @@ ccp_fold_builtin (tree stmt, tree fn)
visited = BITMAP_ALLOC (NULL);
memset (val, 0, sizeof (val));
- for (i = 0, a = arglist;
- arg_mask;
- i++, arg_mask >>= 1, a = TREE_CHAIN (a))
- if (arg_mask & 1)
- {
- bitmap_clear (visited);
- if (!get_maxval_strlen (TREE_VALUE (a), &val[i], visited, type))
- val[i] = NULL_TREE;
- }
+ init_call_expr_arg_iterator (fn, &iter);
+ for (i = 0; arg_mask; i++, arg_mask >>= 1)
+ {
+ a = next_call_expr_arg (&iter);
+ if (arg_mask & 1)
+ {
+ bitmap_clear (visited);
+ if (!get_maxval_strlen (a, &val[i], visited, type))
+ val[i] = NULL_TREE;
+ }
+ }
BITMAP_FREE (visited);
@@ -2317,23 +2317,32 @@ ccp_fold_builtin (tree stmt, tree fn)
break;
case BUILT_IN_STRCPY:
- if (val[1] && is_gimple_val (val[1]))
- result = fold_builtin_strcpy (callee, arglist, val[1]);
+ if (val[1] && is_gimple_val (val[1]) && nargs == 2)
+ result = fold_builtin_strcpy (callee,
+ CALL_EXPR_ARG (fn, 0),
+ CALL_EXPR_ARG (fn, 1),
+ val[1]);
break;
case BUILT_IN_STRNCPY:
- if (val[1] && is_gimple_val (val[1]))
- result = fold_builtin_strncpy (callee, arglist, val[1]);
+ if (val[1] && is_gimple_val (val[1]) && nargs == 3)
+ result = fold_builtin_strncpy (callee,
+ CALL_EXPR_ARG (fn, 0),
+ CALL_EXPR_ARG (fn, 1),
+ CALL_EXPR_ARG (fn, 2),
+ val[1]);
break;
case BUILT_IN_FPUTS:
- result = fold_builtin_fputs (arglist,
+ result = fold_builtin_fputs (CALL_EXPR_ARG (fn, 0),
+ CALL_EXPR_ARG (fn, 1),
TREE_CODE (stmt) != GIMPLE_MODIFY_STMT, 0,
val[0]);
break;
case BUILT_IN_FPUTS_UNLOCKED:
- result = fold_builtin_fputs (arglist,
+ result = fold_builtin_fputs (CALL_EXPR_ARG (fn, 0),
+ CALL_EXPR_ARG (fn, 1),
TREE_CODE (stmt) != GIMPLE_MODIFY_STMT, 1,
val[0]);
break;
@@ -2343,26 +2352,39 @@ ccp_fold_builtin (tree stmt, tree fn)
case BUILT_IN_MEMMOVE_CHK:
case BUILT_IN_MEMSET_CHK:
if (val[2] && is_gimple_val (val[2]))
- result = fold_builtin_memory_chk (callee, arglist, val[2], ignore,
+ result = fold_builtin_memory_chk (callee,
+ CALL_EXPR_ARG (fn, 0),
+ CALL_EXPR_ARG (fn, 1),
+ CALL_EXPR_ARG (fn, 2),
+ CALL_EXPR_ARG (fn, 3),
+ val[2], ignore,
DECL_FUNCTION_CODE (callee));
break;
case BUILT_IN_STRCPY_CHK:
case BUILT_IN_STPCPY_CHK:
if (val[1] && is_gimple_val (val[1]))
- result = fold_builtin_stxcpy_chk (callee, arglist, val[1], ignore,
+ result = fold_builtin_stxcpy_chk (callee,
+ CALL_EXPR_ARG (fn, 0),
+ CALL_EXPR_ARG (fn, 1),
+ CALL_EXPR_ARG (fn, 2),
+ val[1], ignore,
DECL_FUNCTION_CODE (callee));
break;
case BUILT_IN_STRNCPY_CHK:
if (val[2] && is_gimple_val (val[2]))
- result = fold_builtin_strncpy_chk (arglist, val[2]);
+ result = fold_builtin_strncpy_chk (CALL_EXPR_ARG (fn, 0),
+ CALL_EXPR_ARG (fn, 1),
+ CALL_EXPR_ARG (fn, 2),
+ CALL_EXPR_ARG (fn, 3),
+ val[2]);
break;
case BUILT_IN_SNPRINTF_CHK:
case BUILT_IN_VSNPRINTF_CHK:
if (val[1] && is_gimple_val (val[1]))
- result = fold_builtin_snprintf_chk (arglist, val[1],
+ result = fold_builtin_snprintf_chk (fn, val[1],
DECL_FUNCTION_CODE (callee));
break;
@@ -2398,9 +2420,7 @@ fold_stmt (tree *stmt_p)
then we may need to fold instances of *&VAR into VAR, etc. */
if (walk_tree (stmt_p, fold_stmt_r, &fold_stmt_r_data, NULL))
{
- *stmt_p
- = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
- NULL);
+ *stmt_p = build_call_expr (implicit_built_in_decls[BUILT_IN_TRAP], 0);
return true;
}
@@ -2428,8 +2448,8 @@ fold_stmt (tree *stmt_p)
copying EH region info to the new node. Easier to just do it
here where we can just smash the call operand. Also
CALL_EXPR_RETURN_SLOT_OPT needs to be handled correctly and
- copied, fold_ternary does not have not information. */
- callee = TREE_OPERAND (rhs, 0);
+ copied, fold_call_expr does not have not information. */
+ callee = CALL_EXPR_FN (rhs);
if (TREE_CODE (callee) == OBJ_TYPE_REF
&& lang_hooks.fold_obj_type_ref
&& TREE_CODE (OBJ_TYPE_REF_OBJECT (callee)) == ADDR_EXPR
@@ -2447,7 +2467,7 @@ fold_stmt (tree *stmt_p)
t = lang_hooks.fold_obj_type_ref (callee, t);
if (t)
{
- TREE_OPERAND (rhs, 0) = t;
+ CALL_EXPR_FN (rhs) = t;
changed = true;
}
}