Hi, This is a refactoring patch discussed in another thread [1]. It gets rid of CODE_FOR_nothing usage in optabs-tree.c by introducing boolean predicated in optabs-query. Bootstrapped and regtesed on x86_64-unknown-linux-gnu.
Thanks, Ilya [1] - https://gcc.gnu.org/ml/gcc-patches/2015-10/msg02973.html -- gcc/ 2015-11-19 Ilya Enkovich <enkovich....@gmail.com> * optabs-query.h (get_vec_cmp_icode): Remove 'static'. (get_vcond_mask_icode): Likewise. (get_extend_icode): New. (get_float_icode): New. (get_fix_icode): New. (can_extend_p): Return bool (can_float_p): Return bool. (can_fix_p): Return bool. (can_vec_cmp_p): New. (can_vcond_p): New. (can_vcond_mask_p): New. * optabs-query.c (get_float_icode): New. (can_extend_p): Return bool. (get_float_icode): New. (can_float_p): Return bool. (get_fix_icode): New. (can_fix_p): Return bool. (can_vec_cmp_p): New. (can_vcond_p): New. (can_vcond_mask_p): New. * expr.c (init_expr_target): Use get_extend_icode and adjust to new can_extend_p return type. (convert_move): Likewise. (compress_float_constant): Likewise. * function.c (assign_parm_setup_reg): Likewise. * optabs-tree.c: Don't include insn-codes.h. (supportable_convert_operation): Adjust to can_fix_p and can_float_p new return types. * optabs.c (gen_extend_insn): Use get_extend_icode. (expand_float): Use get_float_icode and adjust to can_float_p new return type. (expand_fix): Use get_fix_icode and adjust to can_fix_p new return type. * tree-vrp.c (simplify_float_conversion_using_ranges): Adjust to can_float_p new return type. diff --git a/gcc/expr.c b/gcc/expr.c index bd43dc4..f4c06a1 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -223,7 +223,7 @@ init_expr_target (void) { enum insn_code ic; - ic = can_extend_p (mode, srcmode, 0); + ic = get_extend_icode (mode, srcmode, 0); if (ic == CODE_FOR_nothing) continue; @@ -452,7 +452,7 @@ convert_move (rtx to, rtx from, int unsignedp) int nwords = CEIL (GET_MODE_SIZE (to_mode), UNITS_PER_WORD); /* Try converting directly if the insn is supported. */ - if ((code = can_extend_p (to_mode, from_mode, unsignedp)) + if ((code = get_extend_icode (to_mode, from_mode, unsignedp)) != CODE_FOR_nothing) { /* If FROM is a SUBREG, put it into a register. Do this @@ -466,7 +466,7 @@ convert_move (rtx to, rtx from, int unsignedp) } /* Next, try converting via full word. */ else if (GET_MODE_PRECISION (from_mode) < BITS_PER_WORD - && ((code = can_extend_p (to_mode, word_mode, unsignedp)) + && ((code = get_extend_icode (to_mode, word_mode, unsignedp)) != CODE_FOR_nothing)) { rtx word_to = gen_reg_rtx (word_mode); @@ -573,7 +573,7 @@ convert_move (rtx to, rtx from, int unsignedp) if (GET_MODE_PRECISION (to_mode) > GET_MODE_PRECISION (from_mode)) { /* Convert directly if that works. */ - if ((code = can_extend_p (to_mode, from_mode, unsignedp)) + if ((code = get_extend_icode (to_mode, from_mode, unsignedp)) != CODE_FOR_nothing) { emit_unop_insn (code, to, from, equiv_code); @@ -588,12 +588,10 @@ convert_move (rtx to, rtx from, int unsignedp) /* Search for a mode to convert via. */ for (intermediate = from_mode; intermediate != VOIDmode; intermediate = GET_MODE_WIDER_MODE (intermediate)) - if (((can_extend_p (to_mode, intermediate, unsignedp) - != CODE_FOR_nothing) + if ((can_extend_p (to_mode, intermediate, unsignedp) || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate) && TRULY_NOOP_TRUNCATION_MODES_P (to_mode, intermediate))) - && (can_extend_p (intermediate, from_mode, unsignedp) - != CODE_FOR_nothing)) + && can_extend_p (intermediate, from_mode, unsignedp)) { convert_move (to, convert_to_mode (intermediate, from, unsignedp), unsignedp); @@ -3638,7 +3636,7 @@ compress_float_constant (rtx x, rtx y) rtx_insn *last_insn; /* Skip if the target can't extend this way. */ - ic = can_extend_p (dstmode, srcmode, 0); + ic = get_extend_icode (dstmode, srcmode, 0); if (ic == CODE_FOR_nothing) continue; diff --git a/gcc/function.c b/gcc/function.c index afc2c87..1be96dc 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -3143,8 +3143,8 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, enum insn_code icode; rtx op0, op1; - icode = can_extend_p (promoted_nominal_mode, data->passed_mode, - unsignedp); + icode = get_extend_icode (promoted_nominal_mode, data->passed_mode, + unsignedp); op0 = parmreg; op1 = validated_mem; diff --git a/gcc/optabs-query.c b/gcc/optabs-query.c index c20597c..0ac841c 100644 --- a/gcc/optabs-query.c +++ b/gcc/optabs-query.c @@ -231,8 +231,8 @@ get_best_mem_extraction_insn (extraction_insn *insn, no such operation exists, CODE_FOR_nothing will be returned. */ enum insn_code -can_extend_p (machine_mode to_mode, machine_mode from_mode, - int unsignedp) +get_extend_icode (machine_mode to_mode, machine_mode from_mode, + int unsignedp) { if (unsignedp < 0 && targetm.have_ptr_extend ()) return targetm.code_for_ptr_extend; @@ -241,18 +241,40 @@ can_extend_p (machine_mode to_mode, machine_mode from_mode, return convert_optab_handler (tab, to_mode, from_mode); } +/* Return 1 if there is a valid insn code used to extend FROM_MODE + to TO_MODE. UNSIGNEDP specifies zero-extension instead of + sign-extension. */ + +bool +can_extend_p (machine_mode to_mode, machine_mode from_mode, + int unsignedp) +{ + return get_extend_icode (to_mode, from_mode, unsignedp) != CODE_FOR_nothing; +} + /* Return the insn code to convert fixed-point mode FIXMODE to floating-point mode FLTMODE, or CODE_FOR_nothing if no such instruction exists. UNSIGNEDP specifies whether FIXMODE is unsigned. */ enum insn_code -can_float_p (machine_mode fltmode, machine_mode fixmode, - int unsignedp) +get_float_icode (machine_mode fltmode, machine_mode fixmode, + int unsignedp) { convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab; return convert_optab_handler (tab, fltmode, fixmode); } +/* Return 1 id there is a valid insn code to convert fixed-point mode + FIXMODE to floating-point mode FLTMODE. + UNSIGNEDP specifies whether FIXMODE is unsigned. */ + +bool +can_float_p (machine_mode fltmode, machine_mode fixmode, + int unsignedp) +{ + return get_float_icode (fltmode, fixmode, unsignedp) != CODE_FOR_nothing; +} + /* Return the insn code to convert floating-point mode FLTMODE to fixed-point mode FIXMODE, or CODE_FOR_nothing if no such instruction exists. UNSIGNEDP specifies whether FIXMODE is unsigned. @@ -261,8 +283,8 @@ can_float_p (machine_mode fltmode, machine_mode fixmode, output an explicit FTRUNC before the instruction. */ enum insn_code -can_fix_p (machine_mode fixmode, machine_mode fltmode, - int unsignedp, bool *truncp_ptr) +get_fix_icode (machine_mode fixmode, machine_mode fltmode, + int unsignedp, bool *truncp_ptr) { convert_optab tab; enum insn_code icode; @@ -290,6 +312,21 @@ can_fix_p (machine_mode fixmode, machine_mode fltmode, return CODE_FOR_nothing; } +/* Return 1 if there a valid insn code to convert floating-point mode + FLTMODE to fixed-point mode FIXMODE. + UNSIGNEDP specifies whether FIXMODE is unsigned. + + On a successful return, set *TRUNCP_PTR to true if it is necessary to + output an explicit FTRUNC before the instruction. */ + +bool +can_fix_p (machine_mode fixmode, machine_mode fltmode, + int unsignedp, bool *truncp_ptr) +{ + return get_fix_icode (fixmode, fltmode, unsignedp, truncp_ptr) + != CODE_FOR_nothing; +} + /* Return nonzero if a conditional move of mode MODE is supported. This function is for combine so it can tell whether an insn that looks @@ -580,3 +617,31 @@ lshift_cheap_p (bool speed_p) return cheap[speed_p]; } + +/* Return 1 if there is a valid insn code for a comparison + operator with VMODE resultin MASK_MODE, unsigned if UNS is true. */ + +bool +can_vec_cmp_p (machine_mode vmode, machine_mode mask_mode, bool uns) +{ + return get_vec_cmp_icode (vmode, mask_mode, uns) != CODE_FOR_nothing; +} + +/* Return 1 if there is a valid insn code for a conditional operator + with a comparison in mode CMODE, unsigned if UNS is true, resulting + in a value of mode VMODE. */ + +bool +can_vcond_p (machine_mode vmode, machine_mode cmode, bool uns) +{ + return get_vcond_icode (vmode, cmode, uns) != CODE_FOR_nothing; +} + +/* Return 1 if there is a valid insn code for a conditional operator + with a mask mode MMODE resulting in a value of mode VMODE. */ + +bool +can_vcond_mask_p (machine_mode vmode, machine_mode mmode) +{ + return get_vcond_mask_icode (vmode, mmode) != CODE_FOR_nothing; +} diff --git a/gcc/optabs-query.h b/gcc/optabs-query.h index 48bcf7c..0604a2e 100644 --- a/gcc/optabs-query.h +++ b/gcc/optabs-query.h @@ -77,7 +77,7 @@ trapv_binoptab_p (optab binoptab) /* Return insn code for a comparison operator with VMODE resultin MASK_MODE, unsigned if UNS is true. */ -static inline enum insn_code +inline enum insn_code get_vec_cmp_icode (machine_mode vmode, machine_mode mask_mode, bool uns) { optab tab = uns ? vec_cmpu_optab : vec_cmp_optab; @@ -101,7 +101,7 @@ get_vcond_icode (machine_mode vmode, machine_mode cmode, bool uns) /* Return insn code for a conditional operator with a mask mode MMODE resulting in a value of mode VMODE. */ -static inline enum insn_code +inline enum insn_code get_vcond_mask_icode (machine_mode vmode, machine_mode mmode) { return convert_optab_handler (vcond_mask_optab, vmode, mmode); @@ -136,9 +136,12 @@ bool get_best_mem_extraction_insn (extraction_insn *, enum extraction_pattern, HOST_WIDE_INT, HOST_WIDE_INT, machine_mode); -enum insn_code can_extend_p (machine_mode, machine_mode, int); -enum insn_code can_float_p (machine_mode, machine_mode, int); -enum insn_code can_fix_p (machine_mode, machine_mode, int, bool *); +enum insn_code get_extend_icode (machine_mode, machine_mode, int); +enum insn_code get_float_icode (machine_mode, machine_mode, int); +enum insn_code get_fix_icode (machine_mode, machine_mode, int, bool *); +bool can_extend_p (machine_mode, machine_mode, int); +bool can_float_p (machine_mode, machine_mode, int); +bool 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, const unsigned char *); enum insn_code widening_optab_handler (optab, machine_mode, machine_mode); @@ -153,5 +156,8 @@ bool can_vec_mask_load_store_p (machine_mode, machine_mode, bool); bool can_compare_and_swap_p (machine_mode, bool); bool can_atomic_exchange_p (machine_mode, bool); bool lshift_cheap_p (bool); +bool can_vec_cmp_p (machine_mode, machine_mode, bool); +bool can_vcond_p (machine_mode, machine_mode, bool); +bool can_vcond_mask_p (machine_mode, machine_mode); #endif diff --git a/gcc/optabs-tree.c b/gcc/optabs-tree.c index d887619..0bb1534 100644 --- a/gcc/optabs-tree.c +++ b/gcc/optabs-tree.c @@ -22,7 +22,6 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "target.h" -#include "insn-codes.h" #include "tree.h" #include "optabs-tree.h" #include "stor-layout.h" @@ -298,11 +297,9 @@ supportable_convert_operation (enum tree_code code, /* First check if we can done conversion directly. */ if ((code == FIX_TRUNC_EXPR - && can_fix_p (m1,m2,TYPE_UNSIGNED (vectype_out), &truncp) - != CODE_FOR_nothing) + && can_fix_p (m1,m2,TYPE_UNSIGNED (vectype_out), &truncp)) || (code == FLOAT_EXPR - && can_float_p (m1,m2,TYPE_UNSIGNED (vectype_in)) - != CODE_FOR_nothing)) + && can_float_p (m1,m2,TYPE_UNSIGNED (vectype_in)))) { *code1 = code; return true; diff --git a/gcc/optabs.c b/gcc/optabs.c index 5545302..1276d5f 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -4498,7 +4498,7 @@ rtx_insn * gen_extend_insn (rtx x, rtx y, machine_mode mto, machine_mode mfrom, int unsignedp) { - enum insn_code icode = can_extend_p (mto, mfrom, unsignedp); + enum insn_code icode = get_extend_icode (mto, mfrom, unsignedp); return GEN_FCN (icode) (x, y); } @@ -4535,10 +4535,10 @@ expand_float (rtx to, rtx from, int unsignedp) && significand_size (fmode) < GET_MODE_PRECISION (GET_MODE (from))) continue; - icode = can_float_p (fmode, imode, unsignedp); + icode = get_float_icode (fmode, imode, unsignedp); if (icode == CODE_FOR_nothing && unsignedp) { - enum insn_code scode = can_float_p (fmode, imode, 0); + enum insn_code scode = get_float_icode (fmode, imode, 0); if (scode != CODE_FOR_nothing) can_do_signed = true; if (imode != GET_MODE (from)) @@ -4577,7 +4577,7 @@ expand_float (rtx to, rtx from, int unsignedp) for (fmode = GET_MODE (to); fmode != VOIDmode; fmode = GET_MODE_WIDER_MODE (fmode)) if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_BITSIZE (fmode) - && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing) + && can_float_p (fmode, GET_MODE (from), 0)) break; if (fmode == VOIDmode) @@ -4729,9 +4729,12 @@ expand_fix (rtx to, rtx from, int unsignedp) { int doing_unsigned = unsignedp; - icode = can_fix_p (imode, fmode, unsignedp, &must_trunc); + icode = get_fix_icode (imode, fmode, unsignedp, &must_trunc); if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp) - icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0; + { + icode = get_fix_icode (imode, fmode, 0, &must_trunc); + doing_unsigned = 0; + } if (icode != CODE_FOR_nothing) { @@ -4787,7 +4790,7 @@ expand_fix (rtx to, rtx from, int unsignedp) if (unsignedp && GET_MODE_PRECISION (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT) for (fmode = GET_MODE (from); fmode != VOIDmode; fmode = GET_MODE_WIDER_MODE (fmode)) - if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, &must_trunc) + if (can_fix_p (GET_MODE (to), fmode, 0, &must_trunc) && (!DECIMAL_FLOAT_MODE_P (fmode) || GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (GET_MODE (to)))) { diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 5d085b4..90f4e54 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -9712,13 +9712,12 @@ simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi, /* First check if we can use a signed type in place of an unsigned. */ if (TYPE_UNSIGNED (TREE_TYPE (rhs1)) - && (can_float_p (fltmode, TYPE_MODE (TREE_TYPE (rhs1)), 0) - != CODE_FOR_nothing) + && can_float_p (fltmode, TYPE_MODE (TREE_TYPE (rhs1)), 0) && range_fits_type_p (vr, TYPE_PRECISION (TREE_TYPE (rhs1)), SIGNED)) mode = TYPE_MODE (TREE_TYPE (rhs1)); /* If we can do the conversion in the current input mode do nothing. */ else if (can_float_p (fltmode, TYPE_MODE (TREE_TYPE (rhs1)), - TYPE_UNSIGNED (TREE_TYPE (rhs1))) != CODE_FOR_nothing) + TYPE_UNSIGNED (TREE_TYPE (rhs1)))) return false; /* Otherwise search for a mode we can use, starting from the narrowest integer mode available. */ @@ -9730,7 +9729,7 @@ simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi, /* If we cannot do a signed conversion to float from mode or if the value-range does not fit in the signed type try with a wider mode. */ - if (can_float_p (fltmode, mode, 0) != CODE_FOR_nothing + if (can_float_p (fltmode, mode, 0) && range_fits_type_p (vr, GET_MODE_PRECISION (mode), SIGNED)) break;