diff options
-rw-r--r-- | gcc/builtins.c | 4 | ||||
-rw-r--r-- | gcc/builtins.def | 20 | ||||
-rw-r--r-- | gcc/config/darwin-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/darwin.c | 3 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 2 | ||||
-rw-r--r-- | gcc/config/linux-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/linux.c | 3 | ||||
-rw-r--r-- | gcc/config/nvptx/nvptx.c | 20 | ||||
-rw-r--r-- | gcc/convert.c | 8 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 7 | ||||
-rw-r--r-- | gcc/fortran/f95-lang.c | 4 | ||||
-rw-r--r-- | gcc/match.pd | 6 | ||||
-rw-r--r-- | gcc/target.def | 7 | ||||
-rw-r--r-- | gcc/targhooks.c | 9 | ||||
-rw-r--r-- | gcc/targhooks.h | 6 | ||||
-rw-r--r-- | gcc/tree-ssa-math-opts.c | 8 |
16 files changed, 76 insertions, 35 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index cac842f..8f2662b 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -2733,7 +2733,7 @@ expand_builtin_cexpi (tree exp, rtx target) /* Compute into op1 and op2. */ expand_twoval_unop (sincos_optab, op0, op2, op1, 0); } - else if (targetm.libc_has_function (function_sincos)) + else if (targetm.libc_has_function (function_sincos, type)) { tree call, fn = NULL_TREE; tree top1, top2; @@ -9770,7 +9770,7 @@ fold_builtin_sincos (location_t loc, } if (!call) { - if (!targetm.libc_has_function (function_c99_math_complex) + if (!targetm.libc_has_function (function_c99_math_complex, type) || !builtin_decl_implicit_p (fn)) return NULL_TREE; fndecl = builtin_decl_explicit (fn); diff --git a/gcc/builtins.def b/gcc/builtins.def index 102322b..95428c0 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -138,34 +138,41 @@ along with GCC; see the file COPYING3. If not see #undef DEF_C94_BUILTIN #define DEF_C94_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ - true, true, !flag_isoc94, ATTRS, targetm.libc_has_function (function_c94), true) + true, true, !flag_isoc94, ATTRS, \ + targetm.libc_has_function (function_c94, NULL_TREE), true) /* Like DEF_LIB_BUILTIN, except that the function is only a part of the standard in C99 or above. */ #undef DEF_C99_BUILTIN #define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ - true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_misc), true) + true, true, !flag_isoc99, ATTRS, \ + targetm.libc_has_function (function_c99_misc, NULL_TREE), true) /* Like DEF_LIB_BUILTIN, except that the function is only a part of the standard in C11 or above. */ #undef DEF_C11_BUILTIN #define DEF_C11_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ - true, true, !flag_isoc11, ATTRS, targetm.libc_has_function (function_c11_misc), true) + true, true, !flag_isoc11, ATTRS, \ + targetm.libc_has_function (function_c11_misc, NULL_TREE), true) /* Like DEF_LIB_BUILTIN, except that the function is only a part of the standard in C2x or above. */ #undef DEF_C2X_BUILTIN #define DEF_C2X_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ - true, true, !flag_isoc2x, ATTRS, targetm.libc_has_function (function_c2x_misc), true) + true, true, !flag_isoc2x, ATTRS, \ + targetm.libc_has_function (function_c2x_misc, NULL_TREE), true) /* Like DEF_C99_BUILTIN, but for complex math functions. */ #undef DEF_C99_COMPL_BUILTIN #define DEF_C99_COMPL_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ - true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_math_complex), true) + true, true, !flag_isoc99, ATTRS, \ + targetm.libc_has_function (function_c99_math_complex, \ + NULL_TREE), \ + true) /* Builtin that is specified by C99 and C90 reserve the name for future use. We can still recognize the builtin in C90 mode but we can't produce it @@ -173,7 +180,8 @@ along with GCC; see the file COPYING3. If not see #undef DEF_C99_C90RES_BUILTIN #define DEF_C99_C90RES_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ - true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_misc), true) + true, true, !flag_isoc99, ATTRS, \ + targetm.libc_has_function (function_c99_misc, NULL_TREE), true) /* Builtin that C99 reserve the name for future use. We can still recognize the builtin in C99 mode but we can't produce it implicitly. */ diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h index 54cd1e4..49c540f 100644 --- a/gcc/config/darwin-protos.h +++ b/gcc/config/darwin-protos.h @@ -125,6 +125,6 @@ extern bool darwin_kextabi_p (void); extern void darwin_override_options (void); extern void darwin_patch_builtins (void); extern void darwin_rename_builtins (void); -extern bool darwin_libc_has_function (enum function_class fn_class); +extern bool darwin_libc_has_function (enum function_class fn_class, tree); #endif /* CONFIG_DARWIN_PROTOS_H */ diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index c8edfb8..b64aaa7 100644 --- a/gcc/config/darwin.c +++ b/gcc/config/darwin.c @@ -3542,7 +3542,8 @@ darwin_rename_builtins (void) } bool -darwin_libc_has_function (enum function_class fn_class) +darwin_libc_has_function (enum function_class fn_class, + tree type ATTRIBUTE_UNUSED) { if (fn_class == function_sincos) return (strverscmp (darwin_macosx_version_min, "10.9") >= 0); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index c890a73..f684954 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1484,7 +1484,7 @@ ix86_reg_parm_stack_space (const_tree fndecl) bool ix86_libc_has_function (enum function_class fn_class) { - return targetm.libc_has_function (fn_class); + return targetm.libc_has_function (fn_class, NULL_TREE); } /* Returns value SYSV_ABI, MS_ABI dependent on fntype, diff --git a/gcc/config/linux-protos.h b/gcc/config/linux-protos.h index 3759187..c52778b 100644 --- a/gcc/config/linux-protos.h +++ b/gcc/config/linux-protos.h @@ -19,4 +19,4 @@ along with GCC; see the file COPYING3. If not see extern bool linux_has_ifunc_p (void); -extern bool linux_libc_has_function (enum function_class fn_class); +extern bool linux_libc_has_function (enum function_class fn_class, tree); diff --git a/gcc/config/linux.c b/gcc/config/linux.c index 9876153..83ffff4 100644 --- a/gcc/config/linux.c +++ b/gcc/config/linux.c @@ -25,7 +25,8 @@ along with GCC; see the file COPYING3. If not see #include "linux-protos.h" bool -linux_libc_has_function (enum function_class fn_class) +linux_libc_has_function (enum function_class fn_class, + tree type ATTRIBUTE_UNUSED) { if (OPTION_GLIBC || OPTION_MUSL) return true; diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c index de82f9a..afac1bda 100644 --- a/gcc/config/nvptx/nvptx.c +++ b/gcc/config/nvptx/nvptx.c @@ -6536,6 +6536,23 @@ nvptx_set_current_function (tree fndecl) oacc_bcast_partition = 0; } +/* Implement TARGET_LIBC_HAS_FUNCTION. */ + +bool +nvptx_libc_has_function (enum function_class fn_class, tree type) +{ + if (fn_class == function_sincos) + { + if (type != NULL_TREE) + /* Currently, newlib does not support sincosl. */ + return type == float_type_node || type == double_type_node; + else + return true; + } + + return default_libc_has_function (fn_class, type); +} + #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE nvptx_option_override @@ -6681,6 +6698,9 @@ nvptx_set_current_function (tree fndecl) #undef TARGET_SET_CURRENT_FUNCTION #define TARGET_SET_CURRENT_FUNCTION nvptx_set_current_function +#undef TARGET_LIBC_HAS_FUNCTION +#define TARGET_LIBC_HAS_FUNCTION nvptx_libc_has_function + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-nvptx.h" diff --git a/gcc/convert.c b/gcc/convert.c index 292c513..7b28332 100644 --- a/gcc/convert.c +++ b/gcc/convert.c @@ -501,7 +501,7 @@ convert_to_integer_1 (tree type, tree expr, bool dofold) CASE_FLT_FN (BUILT_IN_CEIL): CASE_FLT_FN_FLOATN_NX (BUILT_IN_CEIL): /* Only convert in ISO C99 mode. */ - if (!targetm.libc_has_function (function_c99_misc)) + if (!targetm.libc_has_function (function_c99_misc, intype)) break; if (outprec < TYPE_PRECISION (integer_type_node) || (outprec == TYPE_PRECISION (integer_type_node) @@ -518,7 +518,7 @@ convert_to_integer_1 (tree type, tree expr, bool dofold) CASE_FLT_FN (BUILT_IN_FLOOR): CASE_FLT_FN_FLOATN_NX (BUILT_IN_FLOOR): /* Only convert in ISO C99 mode. */ - if (!targetm.libc_has_function (function_c99_misc)) + if (!targetm.libc_has_function (function_c99_misc, intype)) break; if (outprec < TYPE_PRECISION (integer_type_node) || (outprec == TYPE_PRECISION (integer_type_node) @@ -535,7 +535,7 @@ convert_to_integer_1 (tree type, tree expr, bool dofold) CASE_FLT_FN (BUILT_IN_ROUND): CASE_FLT_FN_FLOATN_NX (BUILT_IN_ROUND): /* Only convert in ISO C99 mode and with -fno-math-errno. */ - if (!targetm.libc_has_function (function_c99_misc) + if (!targetm.libc_has_function (function_c99_misc, intype) || flag_errno_math) break; if (outprec < TYPE_PRECISION (integer_type_node) @@ -559,7 +559,7 @@ convert_to_integer_1 (tree type, tree expr, bool dofold) CASE_FLT_FN (BUILT_IN_RINT): CASE_FLT_FN_FLOATN_NX (BUILT_IN_RINT): /* Only convert in ISO C99 mode and with -fno-math-errno. */ - if (!targetm.libc_has_function (function_c99_misc) + if (!targetm.libc_has_function (function_c99_misc, intype) || flag_errno_math) break; if (outprec < TYPE_PRECISION (integer_type_node) diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 8e9e770..97437e8 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -5602,9 +5602,12 @@ refers to the global ``variable'' @code{errno}. (On certain systems, macro, a reasonable default is used. @end defmac -@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FUNCTION (enum function_class @var{fn_class}) +@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FUNCTION (enum function_class @var{fn_class}, tree @var{type}) This hook determines whether a function from a class of functions -@var{fn_class} is present in the target C library. +@var{fn_class} is present in the target C library. If @var{type} is NULL, +the caller asks for support for all standard (float, double, long double) +types. If @var{type} is non-NULL, the caller asks for support for a +specific type. @end deftypefn @deftypefn {Target Hook} bool TARGET_LIBC_HAS_FAST_FUNCTION (int @var{fcode}) diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c index e3288d7..526b721 100644 --- a/gcc/fortran/f95-lang.c +++ b/gcc/fortran/f95-lang.c @@ -881,7 +881,7 @@ gfc_init_builtin_functions (void) BUILT_IN_POWIF, "powif", ATTR_CONST_NOTHROW_LEAF_LIST); - if (targetm.libc_has_function (function_c99_math_complex)) + if (targetm.libc_has_function (function_c99_math_complex, NULL_TREE)) { gfc_define_builtin ("__builtin_cbrtl", mfunc_longdouble[0], BUILT_IN_CBRTL, "cbrtl", @@ -903,7 +903,7 @@ gfc_init_builtin_functions (void) ATTR_CONST_NOTHROW_LEAF_LIST); } - if (targetm.libc_has_function (function_sincos)) + if (targetm.libc_has_function (function_sincos, NULL_TREE)) { gfc_define_builtin ("__builtin_sincosl", func_longdouble_longdoublep_longdoublep, diff --git a/gcc/match.pd b/gcc/match.pd index e6dcdd0..952643f 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -5185,7 +5185,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (with { const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (@0); bool use_exp2 = false; - if (targetm.libc_has_function (function_c99_misc) + if (targetm.libc_has_function (function_c99_misc, TREE_TYPE (@0)) && value->cl == rvc_normal) { REAL_VALUE_TYPE frac_rvt = *value; @@ -5484,7 +5484,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) cexpis (CEXPI) (simplify (cexps compositional_complex@0) - (if (targetm.libc_has_function (function_c99_math_complex)) + (if (targetm.libc_has_function (function_c99_math_complex, TREE_TYPE (@0))) (complex (mult (exps@1 (realpart @0)) (realpart (cexpis:type@2 (imagpart @0)))) (mult @1 (imagpart @2))))))) @@ -5536,7 +5536,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* truncl(extend(x)) and trunc(extend(x)) -> extend(truncf(x)), etc., if x is a float. */ (if (optimize && canonicalize_math_p () - && targetm.libc_has_function (function_c99_misc)) + && targetm.libc_has_function (function_c99_misc, NULL_TREE)) (simplify (froms (convert float_value_p@0)) (convert (tos @0))))) diff --git a/gcc/target.def b/gcc/target.def index fc4563d..ed2da15 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2618,8 +2618,11 @@ set via @code{__attribute__}.", DEFHOOK (libc_has_function, "This hook determines whether a function from a class of functions\n\ -@var{fn_class} is present in the target C library.", - bool, (enum function_class fn_class), +@var{fn_class} is present in the target C library. If @var{type} is NULL,\n\ +the caller asks for support for all standard (float, double, long double)\n\ +types. If @var{type} is non-NULL, the caller asks for support for a\n\ +specific type.", + bool, (enum function_class fn_class, tree type), default_libc_has_function) DEFHOOK diff --git a/gcc/targhooks.c b/gcc/targhooks.c index da4805d..5d94fce 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1641,7 +1641,8 @@ default_have_conditional_execution (void) /* By default we assume that c99 functions are present at the runtime, but sincos is not. */ bool -default_libc_has_function (enum function_class fn_class) +default_libc_has_function (enum function_class fn_class, + tree type ATTRIBUTE_UNUSED) { if (fn_class == function_c94 || fn_class == function_c99_misc @@ -1660,13 +1661,15 @@ default_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED) } bool -gnu_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED) +gnu_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED, + tree type ATTRIBUTE_UNUSED) { return true; } bool -no_c99_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED) +no_c99_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED, + tree type ATTRIBUTE_UNUSED) { return false; } diff --git a/gcc/targhooks.h b/gcc/targhooks.h index b572a36..44ab926 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -208,10 +208,10 @@ extern rtx default_addr_space_convert (rtx, tree, tree); extern unsigned int default_case_values_threshold (void); extern bool default_have_conditional_execution (void); -extern bool default_libc_has_function (enum function_class); +extern bool default_libc_has_function (enum function_class, tree); extern bool default_libc_has_fast_function (int fcode); -extern bool no_c99_libc_has_function (enum function_class); -extern bool gnu_libc_has_function (enum function_class); +extern bool no_c99_libc_has_function (enum function_class, tree); +extern bool gnu_libc_has_function (enum function_class, tree); extern tree default_builtin_tm_load_store (tree); diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index 8423caa..bdbb9d9 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -2176,12 +2176,14 @@ pass_cse_sincos::execute (function *fun) CASE_CFN_COS: CASE_CFN_SIN: CASE_CFN_CEXPI: + arg = gimple_call_arg (stmt, 0); /* Make sure we have either sincos or cexp. */ - if (!targetm.libc_has_function (function_c99_math_complex) - && !targetm.libc_has_function (function_sincos)) + if (!targetm.libc_has_function (function_c99_math_complex, + TREE_TYPE (arg)) + && !targetm.libc_has_function (function_sincos, + TREE_TYPE (arg))) break; - arg = gimple_call_arg (stmt, 0); if (TREE_CODE (arg) == SSA_NAME) cfg_changed |= execute_cse_sincos_1 (arg); break; |