aboutsummaryrefslogtreecommitdiff
path: root/gcc/internal-fn.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2015-11-17 18:51:55 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2015-11-17 18:51:55 +0000
commit883cabdecdb052865f68bb910aef86fbb75cc925 (patch)
tree6dcadb07c42281f307350b2580b0ef025f6a79a7 /gcc/internal-fn.c
parent4cfe7a6c3569019e33dc86a54ec03aef87ad5d83 (diff)
downloadgcc-883cabdecdb052865f68bb910aef86fbb75cc925.zip
gcc-883cabdecdb052865f68bb910aef86fbb75cc925.tar.gz
gcc-883cabdecdb052865f68bb910aef86fbb75cc925.tar.bz2
Extend tree-call-cdce to calls whose result is used
For -fmath-errno, builtins.c currently expands calls to sqrt to: y = sqrt_optab (x); if (y != y) [ sqrt (x); or errno = EDOM; ] The drawbacks of this are: - the call to sqrt is protected by the result of the optab rather than the input. It would be better to check __builtin_isless (x, 0), like tree-call-cdce.c does. - the branch isn't exposed at the gimple level and so gets little high-level optimisation. - we do this for log too, but for log a zero input produces -inf rather than a NaN, and sets errno to ERANGE rather than EDOM. This patch moves the code to tree-call-cdce.c instead, with the optab operation being represented as an internal function. This means that we can use the existing argument-based range checks rather than the result-based checks and that we get more gimple optimisation of the branch. Previously the pass was only enabled by default at -O2 or above, but the old builtins.c code was enabled at -O. The patch therefore enables the pass at -O as well. The previous patch to cfgexpand.c handled cases where functions don't (or are assumed not to) set errno, so this patch makes the builtins.c code dead. Tested on x86_64-linux-gnu, aarch64-linux-gnu, arm-linux-gnueabi and visium-elf (for the EDOM stuff). gcc/ * builtins.c (expand_errno_check, expand_builtin_mathfn) (expand_builtin_mathfn_2): Delete. (expand_builtin): Remove handling of functions with internal function equivalents. * internal-fn.def (SET_EDOM): New internal function. * internal-fn.h (set_edom_supported_p): Declare. * internal-fn.c (expand_SET_EDOM): New function. (set_edom_supported_p): Likewise. * tree-call-cdce.c: Include builtins.h and internal-fn.h. Rewrite comment at head of file. (is_call_dce_candidate): Rename to... (can_test_argument_range): ...this. Don't check gimple_call_lhs or gimple_call_builtin_p here. (edom_only_function): New function. (shrink_wrap_one_built_in_call_with_conds): New function, split out from... (shrink_wrap_one_built_in_call): ...here. (can_use_internal_fn, use_internal_fn): New functions. (shrink_wrap_conditional_dead_built_in_calls): Call use_internal_fn for calls that have an lhs. (pass_call_cdce::gate): Remove optimize_function_for_speed_p check. (pass_call_cdce::execute): Skip blocks that are optimized for size. Check gimple_call_builtin_p here. Use can_use_internal_fn for calls with an lhs. * opts.c (default_options_table): Enable -ftree-builtin-call-cdce at -O and above. From-SVN: r230488
Diffstat (limited to 'gcc/internal-fn.c')
-rw-r--r--gcc/internal-fn.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index f23d799..06c5d9e 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -2073,6 +2073,24 @@ expand_GOACC_REDUCTION (internal_fn, gcall *)
gcc_unreachable ();
}
+/* Set errno to EDOM. */
+
+static void
+expand_SET_EDOM (internal_fn, gcall *)
+{
+#ifdef TARGET_EDOM
+#ifdef GEN_ERRNO_RTX
+ rtx errno_rtx = GEN_ERRNO_RTX;
+#else
+ rtx errno_rtx = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
+#endif
+ emit_move_insn (errno_rtx,
+ gen_int_mode (TARGET_EDOM, GET_MODE (errno_rtx)));
+#else
+ gcc_unreachable ();
+#endif
+}
+
/* Expand a call to FN using the operands in STMT. FN has a single
output operand and NARGS input operands. */
@@ -2217,6 +2235,18 @@ direct_internal_fn_supported_p (internal_fn fn, tree type)
return direct_internal_fn_supported_p (fn, tree_pair (type, type));
}
+/* Return true if IFN_SET_EDOM is supported. */
+
+bool
+set_edom_supported_p (void)
+{
+#ifdef TARGET_EDOM
+ return true;
+#else
+ return false;
+#endif
+}
+
#define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
static void \
expand_##CODE (internal_fn fn, gcall *stmt) \