diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-11-01 12:30:39 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-11-01 12:30:39 +0000 |
commit | 4b926feae10ecec6555dca641c03a8239a824eab (patch) | |
tree | 14a00e419d6b7f3b8f89dc41f37a4d056346f85c /gcc/optabs-query.h | |
parent | ef1d3b57d2d00795c6eb01fe6b8ef6f413163c67 (diff) | |
download | gcc-4b926feae10ecec6555dca641c03a8239a824eab.zip gcc-4b926feae10ecec6555dca641c03a8239a824eab.tar.gz gcc-4b926feae10ecec6555dca641c03a8239a824eab.tar.bz2 |
Widening optab cleanup
widening_optab_handler had the comment:
/* ??? Why does find_widening_optab_handler_and_mode attempt to
widen things that can't be widened? E.g. add_optab... */
if (op > LAST_CONV_OPTAB)
return CODE_FOR_nothing;
I think it comes from expand_binop using
find_widening_optab_handler_and_mode for two things: to test whether
a "normal" optab like add_optab is supported for a standard binary
operation and to test whether a "convert" optab is supported for a
widening operation like umul_widen_optab. In the former case from_mode
and to_mode must be the same, in the latter from_mode must be narrower
than to_mode.
For the former case, find_widening_optab_handler_and_mode is only really
testing the modes that are passed in. permit_non_widening must be true
here.
For the latter case, find_widening_optab_handler_and_mode should only
really consider new from_modes that are wider than the original
from_mode and narrower than the original to_mode. Logically
permit_non_widening should be false, since widening optabs aren't
supposed to take operands that are the same width as the destination.
We get away with permit_non_widening being true because no target
would/should define a widening .md pattern with matching modes.
But really, it seems better for expand_binop to handle these two
cases itself rather than pushing them down. With that change,
find_widening_optab_handler_and_mode is only ever called with
permit_non_widening set to false and is only ever called with
a "proper" convert optab. We then no longer need widening_optab_handler,
we can just use convert_optab_handler directly.
The patch also passes the instruction code down to expand_binop_directly.
This should be more efficient and removes an extra call to
find_widening_optab_handler_and_mode.
2017-11-01 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* optabs-query.h (convert_optab_p): New function, split out from...
(convert_optab_handler): ...here.
(widening_optab_handler): Delete.
(find_widening_optab_handler): Remove permit_non_widening parameter.
(find_widening_optab_handler_and_mode): Likewise. Provide an
override that operates on mode class wrappers.
* optabs-query.c (widening_optab_handler): Delete.
(find_widening_optab_handler_and_mode): Remove permit_non_widening
parameter. Assert that the two modes are the same class and that
the "from" mode is narrower than the "to" mode. Use
convert_optab_handler instead of widening_optab_handler.
* expmed.c (expmed_mult_highpart_optab): Use convert_optab_handler
instead of widening_optab_handler.
* expr.c (expand_expr_real_2): Update calls to
find_widening_optab_handler.
* optabs.c (expand_widen_pattern_expr): Likewise.
(expand_binop_directly): Take the insn_code as a parameter.
(expand_binop): Only call find_widening_optab_handler for
conversion optabs; use optab_handler otherwise. Update calls
to find_widening_optab_handler and expand_binop_directly.
Use convert_optab_handler instead of widening_optab_handler.
* tree-ssa-math-opts.c (convert_mult_to_widen): Update calls to
find_widening_optab_handler and use scalar_mode rather than
machine_mode.
(convert_plusminus_to_widen): Likewise.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r254302
Diffstat (limited to 'gcc/optabs-query.h')
-rw-r--r-- | gcc/optabs-query.h | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/gcc/optabs-query.h b/gcc/optabs-query.h index 9c2d574..2701e25 100644 --- a/gcc/optabs-query.h +++ b/gcc/optabs-query.h @@ -23,6 +23,14 @@ along with GCC; see the file COPYING3. If not see #include "insn-opinit.h" #include "target.h" +/* Return true if OP is a conversion optab. */ + +inline bool +convert_optab_p (optab op) +{ + return op > unknown_optab && op <= LAST_CONV_OPTAB; +} + /* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing if the target does not have such an insn. */ @@ -43,7 +51,7 @@ convert_optab_handler (convert_optab op, machine_mode to_mode, machine_mode from_mode) { unsigned scode = (op << 16) | (from_mode << 8) | to_mode; - gcc_assert (op > unknown_optab && op <= LAST_CONV_OPTAB); + gcc_assert (convert_optab_p (op)); return raw_optab_handler (scode); } @@ -167,12 +175,11 @@ enum insn_code can_float_p (machine_mode, machine_mode, int); enum insn_code can_fix_p (machine_mode, machine_mode, int, bool *); bool can_conditionally_move_p (machine_mode mode); bool can_vec_perm_p (machine_mode, bool, vec_perm_indices *); -enum insn_code widening_optab_handler (optab, machine_mode, machine_mode); /* Find a widening optab even if it doesn't widen as much as we want. */ -#define find_widening_optab_handler(A,B,C,D) \ - find_widening_optab_handler_and_mode (A, B, C, D, NULL) +#define find_widening_optab_handler(A, B, C) \ + find_widening_optab_handler_and_mode (A, B, C, NULL) enum insn_code find_widening_optab_handler_and_mode (optab, machine_mode, - machine_mode, int, + machine_mode, machine_mode *); int can_mult_highpart_p (machine_mode, bool); bool can_vec_mask_load_store_p (machine_mode, machine_mode, bool); @@ -181,4 +188,20 @@ bool can_atomic_exchange_p (machine_mode, bool); bool can_atomic_load_p (machine_mode); bool lshift_cheap_p (bool); +/* Version of find_widening_optab_handler_and_mode that operates on + specific mode types. */ + +template<typename T> +inline enum insn_code +find_widening_optab_handler_and_mode (optab op, const T &to_mode, + const T &from_mode, T *found_mode) +{ + machine_mode tmp; + enum insn_code icode = find_widening_optab_handler_and_mode + (op, machine_mode (to_mode), machine_mode (from_mode), &tmp); + if (icode != CODE_FOR_nothing && found_mode) + *found_mode = as_a <T> (tmp); + return icode; +} + #endif |