diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2015-11-17 18:51:55 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2015-11-17 18:51:55 +0000 |
commit | 883cabdecdb052865f68bb910aef86fbb75cc925 (patch) | |
tree | 6dcadb07c42281f307350b2580b0ef025f6a79a7 /gcc/internal-fn.c | |
parent | 4cfe7a6c3569019e33dc86a54ec03aef87ad5d83 (diff) | |
download | gcc-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.c | 30 |
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) \ |