From a6a0570f151b9a4fd42dec96182439e53c19241a Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 3 Dec 2014 13:10:39 +0000 Subject: [PATCH] builtins.c (fold_builtin_fpclassify): Change to take array of arguments instead of CALL_EXPR tree. 2014-12-03 Richard Biener * 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 --- gcc/ChangeLog | 19 +++++++ gcc/builtins.c | 131 ++++++++++++++++++--------------------------- gcc/cp/ChangeLog | 5 ++ gcc/cp/constexpr.c | 4 +- gcc/fold-const.c | 2 + gcc/gimple-fold.c | 5 +- gcc/tree.c | 2 +- 7 files changed, 84 insertions(+), 84 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b688d82b2a8..5e3920e0d9a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2014-12-03 Richard Biener + + * 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 * config/aarch64/aarch64-simd.md (aarch64_simd_dup, orn3, diff --git a/gcc/builtins.c b/gcc/builtins.c index b9dd664c9c2..236f9207ede 100644 --- a/gcc/builtins.c +++ b/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) - { - 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; + if (TREE_CODE (fn) != ADDR_EXPR) + return NULL_TREE; - 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; - } - } + 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); + 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 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f6ea911b747..24fbdd56012 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2014-12-03 Richard Biener + + * constexpr.c (cxx_eval_builtin_function_call): Use + fold_build_call_array_loc. + 2014-12-02 Marek Polacek * constexpr.c (cxx_eval_check_shift_p): New function. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 48bc8f19442..d18025f457c 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -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; } diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 29975e438c7..17eb5bb9f0f 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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); diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 4374c1d7ef1..bdc6088ec0e 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -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. */ diff --git a/gcc/tree.c b/gcc/tree.c index 009f34275b2..3a857c00734 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -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 -- 2.30.2