From 0a0ef2387cc1561d537d8d949aef9479ef17ba35 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 14 Nov 2019 14:45:49 +0000 Subject: [PATCH] Add build_truth_vector_type_for_mode Callers of vect_halve_mask_nunits and vect_double_mask_nunits already know what mode the resulting vector type should have, so we might as well create the vector type directly with that mode, just like build_vector_type_for_mode lets us build normal vectors with a known mode. This avoids the current awkwardness of having to recompute the mode starting from vec_info::vector_size, which hard-codes the assumption that all vectors have to be the same size. A later patch gets rid of build_truth_vector_type and build_same_sized_truth_vector_type, so the net effect of the series is to reduce the number of type functions by one. 2019-11-14 Richard Sandiford gcc/ * tree.h (build_truth_vector_type_for_mode): Declare. * tree.c (build_truth_vector_type_for_mode): New function, split out from... (build_truth_vector_type): ...here. (build_opaque_vector_type): Fix head comment. * tree-vectorizer.h (supportable_narrowing_operation): Remove vec_info parameter. (vect_halve_mask_nunits): Replace vec_info parameter with the mode of the new vector. (vect_double_mask_nunits): Likewise. * tree-vect-loop.c (vect_halve_mask_nunits): Likewise. (vect_double_mask_nunits): Likewise. * tree-vect-loop-manip.c: Include insn-config.h, rtl.h and recog.h. (vect_maybe_permute_loop_masks): Remove vinfo parameter. Update call to vect_halve_mask_nunits, getting the required mode from the unpack patterns. (vect_set_loop_condition_masked): Update call accordingly. * tree-vect-stmts.c (supportable_narrowing_operation): Remove vec_info parameter and update call to vect_double_mask_nunits. (vectorizable_conversion): Update call accordingly. (simple_integer_narrowing): Likewise. Remove vec_info parameter. (vectorizable_call): Update call accordingly. (supportable_widening_operation): Update call to vect_halve_mask_nunits. * config/aarch64/aarch64-sve-builtins.cc (register_builtin_types): Use build_truth_vector_type_mode instead of build_truth_vector_type. From-SVN: r278231 --- gcc/ChangeLog | 29 ++++++++++++++++++ gcc/config/aarch64/aarch64-sve-builtins.cc | 4 +-- gcc/tree-vect-loop-manip.c | 20 ++++++++----- gcc/tree-vect-loop.c | 18 +++++++----- gcc/tree-vect-stmts.c | 34 +++++++++------------- gcc/tree-vectorizer.h | 10 +++---- gcc/tree.c | 33 ++++++++++++++------- gcc/tree.h | 1 + 8 files changed, 95 insertions(+), 54 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3131af715c9..79c8042b46e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,32 @@ +2019-11-14 Richard Sandiford + + * tree.h (build_truth_vector_type_for_mode): Declare. + * tree.c (build_truth_vector_type_for_mode): New function, + split out from... + (build_truth_vector_type): ...here. + (build_opaque_vector_type): Fix head comment. + * tree-vectorizer.h (supportable_narrowing_operation): Remove + vec_info parameter. + (vect_halve_mask_nunits): Replace vec_info parameter with the + mode of the new vector. + (vect_double_mask_nunits): Likewise. + * tree-vect-loop.c (vect_halve_mask_nunits): Likewise. + (vect_double_mask_nunits): Likewise. + * tree-vect-loop-manip.c: Include insn-config.h, rtl.h and recog.h. + (vect_maybe_permute_loop_masks): Remove vinfo parameter. Update call + to vect_halve_mask_nunits, getting the required mode from the unpack + patterns. + (vect_set_loop_condition_masked): Update call accordingly. + * tree-vect-stmts.c (supportable_narrowing_operation): Remove vec_info + parameter and update call to vect_double_mask_nunits. + (vectorizable_conversion): Update call accordingly. + (simple_integer_narrowing): Likewise. Remove vec_info parameter. + (vectorizable_call): Update call accordingly. + (supportable_widening_operation): Update call to + vect_halve_mask_nunits. + * config/aarch64/aarch64-sve-builtins.cc (register_builtin_types): + Use build_truth_vector_type_mode instead of build_truth_vector_type. + 2019-11-14 Richard Sandiford * machmode.h (mode_for_int_vector): Delete. diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc index bb5aadab782..2dc2cea875b 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc @@ -2973,8 +2973,8 @@ register_builtin_types () tree vectype; if (eltype == boolean_type_node) { - vectype = build_truth_vector_type (BYTES_PER_SVE_VECTOR, - BYTES_PER_SVE_VECTOR); + vectype = build_truth_vector_type_for_mode (BYTES_PER_SVE_VECTOR, + VNx16BImode); gcc_assert (TYPE_MODE (vectype) == VNx16BImode && TYPE_MODE (vectype) == TYPE_MODE_RAW (vectype) && TYPE_ALIGN (vectype) == 16 diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index beee5fe088e..f49d9803223 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -47,6 +47,9 @@ along with GCC; see the file COPYING3. If not see #include "stor-layout.h" #include "optabs-query.h" #include "vec-perm-indices.h" +#include "insn-config.h" +#include "rtl.h" +#include "recog.h" /************************************************************************* Simple Loop Peeling Utilities @@ -317,20 +320,24 @@ interleave_supported_p (vec_perm_indices *indices, tree vectype, latter. Return true on success, adding any new statements to SEQ. */ static bool -vect_maybe_permute_loop_masks (loop_vec_info loop_vinfo, gimple_seq *seq, - rgroup_masks *dest_rgm, +vect_maybe_permute_loop_masks (gimple_seq *seq, rgroup_masks *dest_rgm, rgroup_masks *src_rgm) { tree src_masktype = src_rgm->mask_type; tree dest_masktype = dest_rgm->mask_type; machine_mode src_mode = TYPE_MODE (src_masktype); + insn_code icode1, icode2; if (dest_rgm->max_nscalars_per_iter <= src_rgm->max_nscalars_per_iter - && optab_handler (vec_unpacku_hi_optab, src_mode) != CODE_FOR_nothing - && optab_handler (vec_unpacku_lo_optab, src_mode) != CODE_FOR_nothing) + && (icode1 = optab_handler (vec_unpacku_hi_optab, + src_mode)) != CODE_FOR_nothing + && (icode2 = optab_handler (vec_unpacku_lo_optab, + src_mode)) != CODE_FOR_nothing) { /* Unpacking the source masks gives at least as many mask bits as we need. We can then VIEW_CONVERT any excess bits away. */ - tree unpack_masktype = vect_halve_mask_nunits (loop_vinfo, src_masktype); + machine_mode dest_mode = insn_data[icode1].operand[0].mode; + gcc_assert (dest_mode == insn_data[icode2].operand[0].mode); + tree unpack_masktype = vect_halve_mask_nunits (src_masktype, dest_mode); for (unsigned int i = 0; i < dest_rgm->masks.length (); ++i) { tree src = src_rgm->masks[i / 2]; @@ -690,8 +697,7 @@ vect_set_loop_condition_masked (class loop *loop, loop_vec_info loop_vinfo, { rgroup_masks *half_rgm = &(*masks)[nmasks / 2 - 1]; if (!half_rgm->masks.is_empty () - && vect_maybe_permute_loop_masks (loop_vinfo, &header_seq, - rgm, half_rgm)) + && vect_maybe_permute_loop_masks (&header_seq, rgm, half_rgm)) continue; } diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 005fa308911..5cc2f8a240e 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -7900,22 +7900,24 @@ loop_niters_no_overflow (loop_vec_info loop_vinfo) return false; } -/* Return a mask type with half the number of elements as TYPE. */ +/* Return a mask type with half the number of elements as OLD_TYPE, + given that it should have mode NEW_MODE. */ tree -vect_halve_mask_nunits (vec_info *vinfo, tree type) +vect_halve_mask_nunits (tree old_type, machine_mode new_mode) { - poly_uint64 nunits = exact_div (TYPE_VECTOR_SUBPARTS (type), 2); - return build_truth_vector_type (nunits, vinfo->vector_size); + poly_uint64 nunits = exact_div (TYPE_VECTOR_SUBPARTS (old_type), 2); + return build_truth_vector_type_for_mode (nunits, new_mode); } -/* Return a mask type with twice as many elements as TYPE. */ +/* Return a mask type with twice as many elements as OLD_TYPE, + given that it should have mode NEW_MODE. */ tree -vect_double_mask_nunits (vec_info *vinfo, tree type) +vect_double_mask_nunits (tree old_type, machine_mode new_mode) { - poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (type) * 2; - return build_truth_vector_type (nunits, vinfo->vector_size); + poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (old_type) * 2; + return build_truth_vector_type_for_mode (nunits, new_mode); } /* Record that a fully-masked version of LOOP_VINFO would need MASKS to diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 73fe573ea3e..9668643d20b 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -3153,7 +3153,7 @@ vectorizable_bswap (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, *CONVERT_CODE. */ static bool -simple_integer_narrowing (vec_info *vinfo, tree vectype_out, tree vectype_in, +simple_integer_narrowing (tree vectype_out, tree vectype_in, tree_code *convert_code) { if (!INTEGRAL_TYPE_P (TREE_TYPE (vectype_out)) @@ -3163,9 +3163,8 @@ simple_integer_narrowing (vec_info *vinfo, tree vectype_out, tree vectype_in, tree_code code; int multi_step_cvt = 0; auto_vec interm_types; - if (!supportable_narrowing_operation (vinfo, NOP_EXPR, vectype_out, - vectype_in, &code, &multi_step_cvt, - &interm_types) + if (!supportable_narrowing_operation (NOP_EXPR, vectype_out, vectype_in, + &code, &multi_step_cvt, &interm_types) || multi_step_cvt) return false; @@ -3347,7 +3346,7 @@ vectorizable_call (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, if (cfn != CFN_LAST && (modifier == NONE || (modifier == NARROW - && simple_integer_narrowing (vinfo, vectype_out, vectype_in, + && simple_integer_narrowing (vectype_out, vectype_in, &convert_code)))) ifn = vectorizable_internal_function (cfn, callee, vectype_out, vectype_in); @@ -4931,8 +4930,8 @@ vectorizable_conversion (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, case NARROW: gcc_assert (op_type == unary_op); - if (supportable_narrowing_operation (vinfo, code, vectype_out, - vectype_in, &code1, &multi_step_cvt, + if (supportable_narrowing_operation (code, vectype_out, vectype_in, + &code1, &multi_step_cvt, &interm_types)) break; @@ -4948,8 +4947,8 @@ vectorizable_conversion (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, if (!supportable_convert_operation (code, cvt_type, vectype_in, &decl1, &codecvt1)) goto unsupported; - if (supportable_narrowing_operation (vinfo, NOP_EXPR, vectype_out, - cvt_type, &code1, &multi_step_cvt, + if (supportable_narrowing_operation (NOP_EXPR, vectype_out, cvt_type, + &code1, &multi_step_cvt, &interm_types)) break; goto unsupported; @@ -11454,7 +11453,6 @@ supportable_widening_operation (enum tree_code code, stmt_vec_info stmt_info, int *multi_step_cvt, vec *interm_types) { - vec_info *vinfo = stmt_info->vinfo; loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_info); class loop *vect_loop = NULL; machine_mode vec_mode; @@ -11639,11 +11637,8 @@ supportable_widening_operation (enum tree_code code, stmt_vec_info stmt_info, { intermediate_mode = insn_data[icode1].operand[0].mode; if (VECTOR_BOOLEAN_TYPE_P (prev_type)) - { - intermediate_type = vect_halve_mask_nunits (vinfo, prev_type); - if (intermediate_mode != TYPE_MODE (intermediate_type)) - return false; - } + intermediate_type + = vect_halve_mask_nunits (prev_type, intermediate_mode); else intermediate_type = lang_hooks.types.type_for_mode (intermediate_mode, @@ -11719,7 +11714,7 @@ supportable_widening_operation (enum tree_code code, stmt_vec_info stmt_info, narrowing operation (short in the above example). */ bool -supportable_narrowing_operation (vec_info *vinfo, enum tree_code code, +supportable_narrowing_operation (enum tree_code code, tree vectype_out, tree vectype_in, enum tree_code *code1, int *multi_step_cvt, vec *interm_types) @@ -11827,11 +11822,8 @@ supportable_narrowing_operation (vec_info *vinfo, enum tree_code code, { intermediate_mode = insn_data[icode1].operand[0].mode; if (VECTOR_BOOLEAN_TYPE_P (prev_type)) - { - intermediate_type = vect_double_mask_nunits (vinfo, prev_type); - if (intermediate_mode != TYPE_MODE (intermediate_type)) - return false; - } + intermediate_type + = vect_double_mask_nunits (prev_type, intermediate_mode); else intermediate_type = lang_hooks.types.type_for_mode (intermediate_mode, uns); diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 56a9a156993..a6ddaafd38c 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -1638,9 +1638,9 @@ extern bool supportable_widening_operation (enum tree_code, stmt_vec_info, tree, tree, enum tree_code *, enum tree_code *, int *, vec *); -extern bool supportable_narrowing_operation (vec_info *, enum tree_code, tree, - tree, enum tree_code *, - int *, vec *); +extern bool supportable_narrowing_operation (enum tree_code, tree, tree, + enum tree_code *, int *, + vec *); extern unsigned record_stmt_cost (stmt_vector_for_cost *, int, enum vect_cost_for_stmt, stmt_vec_info, int, enum vect_cost_model_location); @@ -1741,8 +1741,8 @@ extern opt_loop_vec_info vect_analyze_loop (class loop *, vec_info_shared *); extern tree vect_build_loop_niters (loop_vec_info, bool * = NULL); extern void vect_gen_vector_loop_niters (loop_vec_info, tree, tree *, tree *, bool); -extern tree vect_halve_mask_nunits (vec_info *, tree); -extern tree vect_double_mask_nunits (vec_info *, tree); +extern tree vect_halve_mask_nunits (tree, machine_mode); +extern tree vect_double_mask_nunits (tree, machine_mode); extern void vect_record_loop_mask (loop_vec_info, vec_loop_masks *, unsigned int, tree, tree); extern tree vect_get_loop_mask (gimple_stmt_iterator *, vec_loop_masks *, diff --git a/gcc/tree.c b/gcc/tree.c index 78c2815028b..2375bf85c2d 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -10873,25 +10873,35 @@ build_vector_type (tree innertype, poly_int64 nunits) return make_vector_type (innertype, nunits, VOIDmode); } +/* Build a truth vector with NUNITS units, giving it mode MASK_MODE. */ + +tree +build_truth_vector_type_for_mode (poly_uint64 nunits, machine_mode mask_mode) +{ + gcc_assert (mask_mode != BLKmode); + + poly_uint64 vsize = GET_MODE_BITSIZE (mask_mode); + unsigned HOST_WIDE_INT esize = vector_element_size (vsize, nunits); + tree bool_type = build_nonstandard_boolean_type (esize); + + return make_vector_type (bool_type, nunits, mask_mode); +} + /* Build truth vector with specified length and number of units. */ tree build_truth_vector_type (poly_uint64 nunits, poly_uint64 vector_size) { - machine_mode mask_mode - = targetm.vectorize.get_mask_mode (nunits, vector_size).else_blk (); - - poly_uint64 vsize; - if (mask_mode == BLKmode) - vsize = vector_size * BITS_PER_UNIT; - else - vsize = GET_MODE_BITSIZE (mask_mode); + machine_mode mask_mode; + if (targetm.vectorize.get_mask_mode (nunits, + vector_size).exists (&mask_mode)) + return build_truth_vector_type_for_mode (nunits, mask_mode); + poly_uint64 vsize = vector_size * BITS_PER_UNIT; unsigned HOST_WIDE_INT esize = vector_element_size (vsize, nunits); - tree bool_type = build_nonstandard_boolean_type (esize); - return make_vector_type (bool_type, nunits, mask_mode); + return make_vector_type (bool_type, nunits, BLKmode); } /* Returns a vector type corresponding to a comparison of VECTYPE. */ @@ -10910,7 +10920,8 @@ build_same_sized_truth_vector_type (tree vectype) return build_truth_vector_type (TYPE_VECTOR_SUBPARTS (vectype), size); } -/* Similarly, but builds a variant type with TYPE_VECTOR_OPAQUE set. */ +/* Like build_vector_type, but builds a variant type with TYPE_VECTOR_OPAQUE + set. */ tree build_opaque_vector_type (tree innertype, poly_int64 nunits) diff --git a/gcc/tree.h b/gcc/tree.h index 4bec90d9a72..93ccbf7fa86 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -4443,6 +4443,7 @@ extern tree build_reference_type_for_mode (tree, machine_mode, bool); extern tree build_reference_type (tree); extern tree build_vector_type_for_mode (tree, machine_mode); extern tree build_vector_type (tree, poly_int64); +extern tree build_truth_vector_type_for_mode (poly_uint64, machine_mode); extern tree build_truth_vector_type (poly_uint64, poly_uint64); extern tree build_same_sized_truth_vector_type (tree vectype); extern tree build_opaque_vector_type (tree, poly_int64); -- 2.30.2