builtins.c (fold_builtin_fpclassify): Change to take array of arguments instead of CALL_EXPR tree.
2014-12-03 Richard Biener <rguenther@suse.de> * builtins.c (fold_builtin_fpclassify): Change to take array of arguments instead of CALL_EXPR tree. (MAX_ARGS_TO_FOLD_BUILTIN): Remove. (fold_builtin_n): Dispatch to fold_builtin_varargs. (fold_call_expr): Always use fold_builtin_n. (fold_builtin_call_array): Change to not build the unfolded call, always use fold_builtin_n. (fold_builtin_varargs): Change to take array of arguments instead of CALL_EXPR tree. (fold_call_stmt): Always use fold_builtin_n. * tree.c (build_call_expr_loc_array): Use fold_build_call_array_loc. * fold-const.c (fold_build_call_array_loc): Build the call if fold_builtin_call_array returned NULL_TREE. * gimple-fold.c (gimple_fold_stmt_to_constant_1): Do not build a CALL_EXPR and use fold_builtin_call_array instead of fold_call_expr. cp/ * constexpr.c (cxx_eval_builtin_function_call): Use fold_build_call_array_loc. From-SVN: r218311
This commit is contained in:
parent
a844a69583
commit
a6a0570f15
|
@ -1,3 +1,22 @@
|
|||
2014-12-03 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* builtins.c (fold_builtin_fpclassify): Change to take
|
||||
array of arguments instead of CALL_EXPR tree.
|
||||
(MAX_ARGS_TO_FOLD_BUILTIN): Remove.
|
||||
(fold_builtin_n): Dispatch to fold_builtin_varargs.
|
||||
(fold_call_expr): Always use fold_builtin_n.
|
||||
(fold_builtin_call_array): Change to not build the unfolded call,
|
||||
always use fold_builtin_n.
|
||||
(fold_builtin_varargs): Change to take array of arguments instead
|
||||
of CALL_EXPR tree.
|
||||
(fold_call_stmt): Always use fold_builtin_n.
|
||||
* tree.c (build_call_expr_loc_array): Use fold_build_call_array_loc.
|
||||
* fold-const.c (fold_build_call_array_loc): Build the call
|
||||
if fold_builtin_call_array returned NULL_TREE.
|
||||
* gimple-fold.c (gimple_fold_stmt_to_constant_1): Do not build
|
||||
a CALL_EXPR and use fold_builtin_call_array instead of
|
||||
fold_call_expr.
|
||||
|
||||
2014-12-03 Alan Lawrence <alan.lawrence@arm.com>
|
||||
|
||||
* config/aarch64/aarch64-simd.md (aarch64_simd_dup<mode>, orn<mode>3,
|
||||
|
|
131
gcc/builtins.c
131
gcc/builtins.c
|
@ -196,7 +196,7 @@ 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_4 (location_t, tree, tree, tree, tree, tree, bool);
|
||||
static tree fold_builtin_varargs (location_t, tree, tree, bool);
|
||||
static tree fold_builtin_varargs (location_t, tree, tree*, int, bool);
|
||||
|
||||
static tree fold_builtin_strpbrk (location_t, tree, tree, tree);
|
||||
static tree fold_builtin_strstr (location_t, tree, tree, tree);
|
||||
|
@ -9692,7 +9692,7 @@ fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
|
|||
one floating point argument which is "type generic". */
|
||||
|
||||
static tree
|
||||
fold_builtin_fpclassify (location_t loc, tree exp)
|
||||
fold_builtin_fpclassify (location_t loc, tree *args, int nargs)
|
||||
{
|
||||
tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero,
|
||||
arg, type, res, tmp;
|
||||
|
@ -9701,17 +9701,21 @@ fold_builtin_fpclassify (location_t loc, tree exp)
|
|||
char buf[128];
|
||||
|
||||
/* Verify the required arguments in the original call. */
|
||||
if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
|
||||
INTEGER_TYPE, INTEGER_TYPE,
|
||||
INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
|
||||
if (nargs != 6
|
||||
|| !validate_arg (args[0], INTEGER_TYPE)
|
||||
|| !validate_arg (args[1], INTEGER_TYPE)
|
||||
|| !validate_arg (args[2], INTEGER_TYPE)
|
||||
|| !validate_arg (args[3], INTEGER_TYPE)
|
||||
|| !validate_arg (args[4], INTEGER_TYPE)
|
||||
|| !validate_arg (args[5], REAL_TYPE))
|
||||
return NULL_TREE;
|
||||
|
||||
fp_nan = CALL_EXPR_ARG (exp, 0);
|
||||
fp_infinite = CALL_EXPR_ARG (exp, 1);
|
||||
fp_normal = CALL_EXPR_ARG (exp, 2);
|
||||
fp_subnormal = CALL_EXPR_ARG (exp, 3);
|
||||
fp_zero = CALL_EXPR_ARG (exp, 4);
|
||||
arg = CALL_EXPR_ARG (exp, 5);
|
||||
fp_nan = args[0];
|
||||
fp_infinite = args[1];
|
||||
fp_normal = args[2];
|
||||
fp_subnormal = args[3];
|
||||
fp_zero = args[4];
|
||||
arg = args[5];
|
||||
type = TREE_TYPE (arg);
|
||||
mode = TYPE_MODE (type);
|
||||
arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
|
||||
|
@ -10621,14 +10625,9 @@ fold_builtin_4 (location_t loc, tree fndecl,
|
|||
}
|
||||
|
||||
/* Fold a call to built-in function FNDECL. ARGS is an array of NARGS
|
||||
arguments, where NARGS <= 4. IGNORE is true if the result of the
|
||||
function call is ignored. This function returns NULL_TREE if no
|
||||
simplification was possible. Note that this only folds builtins with
|
||||
fixed argument patterns. Foldings that do varargs-to-varargs
|
||||
transformations, or that match calls with more than 4 arguments,
|
||||
need to be handled with fold_builtin_varargs instead. */
|
||||
|
||||
#define MAX_ARGS_TO_FOLD_BUILTIN 4
|
||||
arguments. IGNORE is true if the result of the
|
||||
function call is ignored. This function returns NULL_TREE if no
|
||||
simplification was possible. */
|
||||
|
||||
tree
|
||||
fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore)
|
||||
|
@ -10654,6 +10653,7 @@ fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore)
|
|||
ignore);
|
||||
break;
|
||||
default:
|
||||
ret = fold_builtin_varargs (loc, fndecl, args, nargs, ignore);
|
||||
break;
|
||||
}
|
||||
if (ret)
|
||||
|
@ -10750,13 +10750,8 @@ fold_call_expr (location_t loc, tree exp, bool ignore)
|
|||
CALL_EXPR_ARGP (exp), ignore);
|
||||
else
|
||||
{
|
||||
if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
|
||||
{
|
||||
tree *args = CALL_EXPR_ARGP (exp);
|
||||
ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
|
||||
}
|
||||
if (!ret)
|
||||
ret = fold_builtin_varargs (loc, fndecl, exp, ignore);
|
||||
tree *args = CALL_EXPR_ARGP (exp);
|
||||
ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -10764,62 +10759,43 @@ fold_call_expr (location_t loc, tree exp, bool ignore)
|
|||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Construct a CALL_EXPR with type TYPE with FN as the function expression.
|
||||
N arguments are passed in the array ARGARRAY. */
|
||||
/* Fold a CALL_EXPR with type TYPE with FN as the function expression.
|
||||
N arguments are passed in the array ARGARRAY. Return a folded
|
||||
expression or NULL_TREE if no simplification was possible. */
|
||||
|
||||
tree
|
||||
fold_builtin_call_array (location_t loc, tree type,
|
||||
fold_builtin_call_array (location_t loc, tree,
|
||||
tree fn,
|
||||
int n,
|
||||
tree *argarray)
|
||||
{
|
||||
tree ret = NULL_TREE;
|
||||
tree exp;
|
||||
if (TREE_CODE (fn) != ADDR_EXPR)
|
||||
return NULL_TREE;
|
||||
|
||||
if (TREE_CODE (fn) == ADDR_EXPR)
|
||||
{
|
||||
tree fndecl = TREE_OPERAND (fn, 0);
|
||||
if (TREE_CODE (fndecl) == FUNCTION_DECL
|
||||
&& DECL_BUILT_IN (fndecl))
|
||||
{
|
||||
/* If last argument is __builtin_va_arg_pack (), arguments to this
|
||||
function are not finalized yet. Defer folding until they are. */
|
||||
if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
|
||||
{
|
||||
tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
|
||||
if (fndecl2
|
||||
&& TREE_CODE (fndecl2) == FUNCTION_DECL
|
||||
&& DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
|
||||
&& DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
|
||||
return build_call_array_loc (loc, type, fn, n, argarray);
|
||||
}
|
||||
if (avoid_folding_inline_builtin (fndecl))
|
||||
return build_call_array_loc (loc, type, fn, n, argarray);
|
||||
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
|
||||
{
|
||||
ret = targetm.fold_builtin (fndecl, n, argarray, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
tree fndecl = TREE_OPERAND (fn, 0);
|
||||
if (TREE_CODE (fndecl) == FUNCTION_DECL
|
||||
&& DECL_BUILT_IN (fndecl))
|
||||
{
|
||||
/* If last argument is __builtin_va_arg_pack (), arguments to this
|
||||
function are not finalized yet. Defer folding until they are. */
|
||||
if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
|
||||
{
|
||||
tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
|
||||
if (fndecl2
|
||||
&& TREE_CODE (fndecl2) == FUNCTION_DECL
|
||||
&& DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
|
||||
&& DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
|
||||
return NULL_TREE;
|
||||
}
|
||||
if (avoid_folding_inline_builtin (fndecl))
|
||||
return NULL_TREE;
|
||||
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
|
||||
return targetm.fold_builtin (fndecl, n, argarray, false);
|
||||
else
|
||||
return fold_builtin_n (loc, fndecl, argarray, n, false);
|
||||
}
|
||||
|
||||
return build_call_array_loc (loc, type, fn, n, argarray);
|
||||
}
|
||||
else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
|
||||
{
|
||||
/* First try the transformations that don't require consing up
|
||||
an exp. */
|
||||
ret = fold_builtin_n (loc, fndecl, argarray, n, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If we got this far, we need to build an exp. */
|
||||
exp = build_call_array_loc (loc, type, fn, n, argarray);
|
||||
ret = fold_builtin_varargs (loc, fndecl, exp, false);
|
||||
return ret ? ret : exp;
|
||||
}
|
||||
}
|
||||
|
||||
return build_call_array_loc (loc, type, fn, n, argarray);
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Construct a new CALL_EXPR using the tail of the argument list of EXP
|
||||
|
@ -11827,7 +11803,7 @@ fold_builtin_object_size (tree ptr, tree ost)
|
|||
result of the function call is ignored. */
|
||||
|
||||
static tree
|
||||
fold_builtin_varargs (location_t loc, tree fndecl, tree exp,
|
||||
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);
|
||||
|
@ -11836,7 +11812,7 @@ fold_builtin_varargs (location_t loc, tree fndecl, tree exp,
|
|||
switch (fcode)
|
||||
{
|
||||
case BUILT_IN_FPCLASSIFY:
|
||||
ret = fold_builtin_fpclassify (loc, exp);
|
||||
ret = fold_builtin_fpclassify (loc, args, nargs);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -12747,8 +12723,7 @@ fold_call_stmt (gcall *stmt, bool ignore)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
|
||||
ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
|
||||
ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
|
||||
if (ret)
|
||||
{
|
||||
/* Propagate location information from original call to
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2014-12-03 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* constexpr.c (cxx_eval_builtin_function_call): Use
|
||||
fold_build_call_array_loc.
|
||||
|
||||
2014-12-02 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
* constexpr.c (cxx_eval_check_shift_p): New function.
|
||||
|
|
|
@ -1008,8 +1008,8 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t,
|
|||
}
|
||||
if (*non_constant_p)
|
||||
return t;
|
||||
new_call = fold_builtin_call_array (EXPR_LOCATION (t), TREE_TYPE (t),
|
||||
CALL_EXPR_FN (t), nargs, args);
|
||||
new_call = fold_build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t),
|
||||
CALL_EXPR_FN (t), nargs, args);
|
||||
VERIFY_CONSTANT (new_call);
|
||||
return new_call;
|
||||
}
|
||||
|
|
|
@ -14405,6 +14405,8 @@ fold_build_call_array_loc (location_t loc, tree type, tree fn,
|
|||
#endif
|
||||
|
||||
tem = fold_builtin_call_array (loc, type, fn, nargs, argarray);
|
||||
if (!tem)
|
||||
tem = build_call_array_loc (loc, type, fn, nargs, argarray);
|
||||
|
||||
#ifdef ENABLE_FOLD_CHECKING
|
||||
md5_init_ctx (&ctx);
|
||||
|
|
|
@ -4744,14 +4744,13 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree),
|
|||
TREE_OPERAND (fn, 0)))
|
||||
{
|
||||
tree *args = XALLOCAVEC (tree, gimple_call_num_args (stmt));
|
||||
tree call, retval;
|
||||
tree retval;
|
||||
unsigned i;
|
||||
for (i = 0; i < gimple_call_num_args (stmt); ++i)
|
||||
args[i] = (*valueize) (gimple_call_arg (stmt, i));
|
||||
call = build_call_array_loc (loc,
|
||||
retval = fold_builtin_call_array (loc,
|
||||
gimple_call_return_type (call_stmt),
|
||||
fn, gimple_call_num_args (stmt), args);
|
||||
retval = fold_call_expr (EXPR_LOCATION (call), call, false);
|
||||
if (retval)
|
||||
{
|
||||
/* fold_call_expr wraps the result inside a NOP_EXPR. */
|
||||
|
|
|
@ -10591,7 +10591,7 @@ build_call_expr_loc_array (location_t loc, tree fndecl, int n, tree *argarray)
|
|||
tree fntype = TREE_TYPE (fndecl);
|
||||
tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
|
||||
|
||||
return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
|
||||
return fold_build_call_array_loc (loc, TREE_TYPE (fntype), fn, n, argarray);
|
||||
}
|
||||
|
||||
/* Conveniently construct a function call expression. FNDECL names the
|
||||
|
|
Loading…
Reference in New Issue