aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs-query.h
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-11-01 12:30:39 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-11-01 12:30:39 +0000
commit4b926feae10ecec6555dca641c03a8239a824eab (patch)
tree14a00e419d6b7f3b8f89dc41f37a4d056346f85c /gcc/optabs-query.h
parentef1d3b57d2d00795c6eb01fe6b8ef6f413163c67 (diff)
downloadgcc-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.h33
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