aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-generic.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-01-03 21:42:12 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-01-03 21:42:12 +0000
commit928686b1c6d0a8b791ec08b2588a5fb8118d191c (patch)
tree88cbf9a40cb8344238ea471bb4c046691b5a1e40 /gcc/tree-vect-generic.c
parentedab8e10e3cc127335ae4fa7a5935a28acfae0a9 (diff)
downloadgcc-928686b1c6d0a8b791ec08b2588a5fb8118d191c.zip
gcc-928686b1c6d0a8b791ec08b2588a5fb8118d191c.tar.gz
gcc-928686b1c6d0a8b791ec08b2588a5fb8118d191c.tar.bz2
poly_int: TYPE_VECTOR_SUBPARTS
This patch changes TYPE_VECTOR_SUBPARTS to a poly_uint64. The value is encoded in the 10-bit precision field and was previously always stored as a simple log2 value. The challenge was to use this 10 bits to encode the number of elements in variable-length vectors, so that we didn't need to increase the size of the tree. In practice the number of vector elements should always have the form N + N * X (where X is the runtime value), and as for constant-length vectors, N must be a power of 2 (even though X itself might not be). The patch therefore uses the low 8 bits to encode log2(N) and bit 8 to select between constant-length and variable-length vectors. Targets without variable-length vectors continue to use the old scheme. A new valid_vector_subparts_p function tests whether a given number of elements can be encoded. This is false for the vector modes that represent an LD3 or ST3 vector triple (which we want to treat as arrays of vectors rather than single vectors). Most of the patch is mechanical; previous patches handled the changes that weren't entirely straightforward. 2018-01-03 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * tree.h (TYPE_VECTOR_SUBPARTS): Turn into a function and handle polynomial numbers of units. (SET_TYPE_VECTOR_SUBPARTS): Likewise. (valid_vector_subparts_p): New function. (build_vector_type): Remove temporary shim and take the number of units as a poly_uint64 rather than an int. (build_opaque_vector_type): Take the number of units as a poly_uint64 rather than an int. * tree.c (build_vector_from_ctor): Handle polynomial TYPE_VECTOR_SUBPARTS. (type_hash_canon_hash, type_cache_hasher::equal): Likewise. (uniform_vector_p, vector_type_mode, build_vector): Likewise. (build_vector_from_val): If the number of units is variable, use build_vec_duplicate_cst for constant operands and VEC_DUPLICATE_EXPR otherwise. (make_vector_type): Remove temporary is_constant (). (build_vector_type, build_opaque_vector_type): Take the number of units as a poly_uint64 rather than an int. (check_vector_cst): Handle polynomial TYPE_VECTOR_SUBPARTS and VECTOR_CST_NELTS. * cfgexpand.c (expand_debug_expr): Likewise. * expr.c (count_type_elements, categorize_ctor_elements_1): Likewise. (store_constructor, expand_expr_real_1): Likewise. (const_scalar_mask_from_tree): Likewise. * fold-const-call.c (fold_const_reduction): Likewise. * fold-const.c (const_binop, const_unop, fold_convert_const): Likewise. (operand_equal_p, fold_vec_perm, fold_ternary_loc): Likewise. (native_encode_vector, vec_cst_ctor_to_array): Likewise. (fold_relational_const): Likewise. (native_interpret_vector): Likewise. Change the size from an int to an unsigned int. * gimple-fold.c (gimple_fold_stmt_to_constant_1): Handle polynomial TYPE_VECTOR_SUBPARTS. (gimple_fold_indirect_ref, gimple_build_vector): Likewise. (gimple_build_vector_from_val): Use VEC_DUPLICATE_EXPR when duplicating a non-constant operand into a variable-length vector. * hsa-brig.c (hsa_op_immed::emit_to_buffer): Handle polynomial TYPE_VECTOR_SUBPARTS and VECTOR_CST_NELTS. * ipa-icf.c (sem_variable::equals): Likewise. * match.pd: Likewise. * omp-simd-clone.c (simd_clone_subparts): Likewise. * print-tree.c (print_node): Likewise. * stor-layout.c (layout_type): Likewise. * targhooks.c (default_builtin_vectorization_cost): Likewise. * tree-cfg.c (verify_gimple_comparison): Likewise. (verify_gimple_assign_binary): Likewise. (verify_gimple_assign_ternary): Likewise. (verify_gimple_assign_single): Likewise. * tree-pretty-print.c (dump_generic_node): Likewise. * tree-ssa-forwprop.c (simplify_vector_constructor): Likewise. (simplify_bitfield_ref, is_combined_permutation_identity): Likewise. * tree-vect-data-refs.c (vect_permute_store_chain): Likewise. (vect_grouped_load_supported, vect_permute_load_chain): Likewise. (vect_shift_permute_load_chain): Likewise. * tree-vect-generic.c (nunits_for_known_piecewise_op): Likewise. (expand_vector_condition, optimize_vector_constructor): Likewise. (lower_vec_perm, get_compute_type): Likewise. * tree-vect-loop.c (vect_determine_vectorization_factor): Likewise. (get_initial_defs_for_reduction, vect_transform_loop): Likewise. * tree-vect-patterns.c (vect_recog_bool_pattern): Likewise. (vect_recog_mask_conversion_pattern): Likewise. * tree-vect-slp.c (vect_supported_load_permutation_p): Likewise. (vect_get_constant_vectors, vect_transform_slp_perm_load): Likewise. * tree-vect-stmts.c (perm_mask_for_reverse): Likewise. (get_group_load_store_type, vectorizable_mask_load_store): Likewise. (vectorizable_bswap, simd_clone_subparts, vectorizable_assignment) (vectorizable_shift, vectorizable_operation, vectorizable_store) (vectorizable_load, vect_is_simple_cond, vectorizable_comparison) (supportable_widening_operation): Likewise. (supportable_narrowing_operation): Likewise. * tree-vector-builder.c (tree_vector_builder::binary_encoded_nelts): Likewise. * varasm.c (output_constant): Likewise. gcc/ada/ * gcc-interface/utils.c (gnat_types_compatible_p): Handle polynomial TYPE_VECTOR_SUBPARTS. gcc/brig/ * brigfrontend/brig-to-generic.cc (get_unsigned_int_type): Handle polynomial TYPE_VECTOR_SUBPARTS. * brigfrontend/brig-util.h (gccbrig_type_vector_subparts): Likewise. gcc/c-family/ * c-common.c (vector_types_convertible_p, c_build_vec_perm_expr) (convert_vector_to_array_for_subscript): Handle polynomial TYPE_VECTOR_SUBPARTS. (c_common_type_for_mode): Check valid_vector_subparts_p. * c-pretty-print.c (pp_c_initializer_list): Handle polynomial VECTOR_CST_NELTS. gcc/c/ * c-typeck.c (comptypes_internal, build_binary_op): Handle polynomial TYPE_VECTOR_SUBPARTS. gcc/cp/ * constexpr.c (cxx_eval_array_reference): Handle polynomial VECTOR_CST_NELTS. (cxx_fold_indirect_ref): Handle polynomial TYPE_VECTOR_SUBPARTS. * call.c (build_conditional_expr_1): Likewise. * decl.c (cp_finish_decomp): Likewise. * mangle.c (write_type): Likewise. * typeck.c (structural_comptypes): Likewise. (cp_build_binary_op): Likewise. * typeck2.c (process_init_constructor_array): Likewise. gcc/fortran/ * trans-types.c (gfc_type_for_mode): Check valid_vector_subparts_p. gcc/lto/ * lto-lang.c (lto_type_for_mode): Check valid_vector_subparts_p. * lto.c (hash_canonical_type): Handle polynomial TYPE_VECTOR_SUBPARTS. gcc/go/ * go-lang.c (go_langhook_type_for_mode): Check valid_vector_subparts_p. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r256197
Diffstat (limited to 'gcc/tree-vect-generic.c')
-rw-r--r--gcc/tree-vect-generic.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index c0cc656..d7e77b6 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -50,7 +50,7 @@ static void expand_vector_operations_1 (gimple_stmt_iterator *);
static unsigned int
nunits_for_known_piecewise_op (const_tree type)
{
- return TYPE_VECTOR_SUBPARTS (type);
+ return TYPE_VECTOR_SUBPARTS (type).to_constant ();
}
/* Return true if TYPE1 has more elements than TYPE2, where either
@@ -917,9 +917,9 @@ expand_vector_condition (gimple_stmt_iterator *gsi)
Similarly for vbfld_10 instead of x_2 < y_3. */
if (VECTOR_BOOLEAN_TYPE_P (type)
&& SCALAR_INT_MODE_P (TYPE_MODE (type))
- && (GET_MODE_BITSIZE (TYPE_MODE (type))
- < (TYPE_VECTOR_SUBPARTS (type)
- * GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type)))))
+ && known_lt (GET_MODE_BITSIZE (TYPE_MODE (type)),
+ TYPE_VECTOR_SUBPARTS (type)
+ * GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (type))))
&& (a_is_comparison
? useless_type_conversion_p (type, TREE_TYPE (a))
: expand_vec_cmp_expr_p (TREE_TYPE (a1), type, TREE_CODE (a))))
@@ -1084,14 +1084,17 @@ optimize_vector_constructor (gimple_stmt_iterator *gsi)
tree lhs = gimple_assign_lhs (stmt);
tree rhs = gimple_assign_rhs1 (stmt);
tree type = TREE_TYPE (rhs);
- unsigned int i, j, nelts = TYPE_VECTOR_SUBPARTS (type);
+ unsigned int i, j;
+ unsigned HOST_WIDE_INT nelts;
bool all_same = true;
constructor_elt *elt;
gimple *g;
tree base = NULL_TREE;
optab op;
- if (nelts <= 2 || CONSTRUCTOR_NELTS (rhs) != nelts)
+ if (!TYPE_VECTOR_SUBPARTS (type).is_constant (&nelts)
+ || nelts <= 2
+ || CONSTRUCTOR_NELTS (rhs) != nelts)
return;
op = optab_for_tree_code (PLUS_EXPR, type, optab_default);
if (op == unknown_optab
@@ -1303,7 +1306,7 @@ lower_vec_perm (gimple_stmt_iterator *gsi)
tree mask_type = TREE_TYPE (mask);
tree vect_elt_type = TREE_TYPE (vect_type);
tree mask_elt_type = TREE_TYPE (mask_type);
- unsigned int elements = TYPE_VECTOR_SUBPARTS (vect_type);
+ unsigned HOST_WIDE_INT elements;
vec<constructor_elt, va_gc> *v;
tree constr, t, si, i_val;
tree vec0tmp = NULL_TREE, vec1tmp = NULL_TREE, masktmp = NULL_TREE;
@@ -1311,6 +1314,9 @@ lower_vec_perm (gimple_stmt_iterator *gsi)
location_t loc = gimple_location (gsi_stmt (*gsi));
unsigned i;
+ if (!TYPE_VECTOR_SUBPARTS (vect_type).is_constant (&elements))
+ return;
+
if (TREE_CODE (mask) == SSA_NAME)
{
gimple *def_stmt = SSA_NAME_DEF_STMT (mask);
@@ -1338,17 +1344,18 @@ lower_vec_perm (gimple_stmt_iterator *gsi)
&& TREE_CODE (vec1) == VECTOR_CST
&& initializer_zerop (vec1)
&& maybe_ne (indices[0], 0)
- && known_lt (indices[0], elements))
+ && known_lt (poly_uint64 (indices[0]), elements))
{
bool ok_p = indices.series_p (0, 1, indices[0], 1);
if (!ok_p)
{
for (i = 1; i < elements; ++i)
{
- poly_int64 expected = i + indices[0];
+ poly_uint64 actual = indices[i];
+ poly_uint64 expected = i + indices[0];
/* Indices into the second vector are all equivalent. */
- if (maybe_lt (indices[i], elements)
- ? maybe_ne (indices[i], expected)
+ if (maybe_lt (actual, elements)
+ ? maybe_ne (actual, expected)
: maybe_lt (expected, elements))
break;
}
@@ -1472,7 +1479,7 @@ get_compute_type (enum tree_code code, optab op, tree type)
= type_for_widest_vector_mode (TREE_TYPE (type), op);
if (vector_compute_type != NULL_TREE
&& subparts_gt (compute_type, vector_compute_type)
- && TYPE_VECTOR_SUBPARTS (vector_compute_type) > 1
+ && maybe_ne (TYPE_VECTOR_SUBPARTS (vector_compute_type), 1U)
&& (optab_handler (op, TYPE_MODE (vector_compute_type))
!= CODE_FOR_nothing))
compute_type = vector_compute_type;