aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.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.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.c')
-rw-r--r--gcc/tree.c51
1 files changed, 28 insertions, 23 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index c9ca760..d263129 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1851,16 +1851,21 @@ make_vector (unsigned log2_npatterns,
tree
build_vector_from_ctor (tree type, vec<constructor_elt, va_gc> *v)
{
- unsigned int nelts = TYPE_VECTOR_SUBPARTS (type);
- unsigned HOST_WIDE_INT idx;
+ unsigned HOST_WIDE_INT idx, nelts;
tree value;
+ /* We can't construct a VECTOR_CST for a variable number of elements. */
+ nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
tree_vector_builder vec (type, nelts, 1);
FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
{
if (TREE_CODE (value) == VECTOR_CST)
- for (unsigned i = 0; i < VECTOR_CST_NELTS (value); ++i)
- vec.quick_push (VECTOR_CST_ELT (value, i));
+ {
+ /* If NELTS is constant then this must be too. */
+ unsigned int sub_nelts = VECTOR_CST_NELTS (value).to_constant ();
+ for (unsigned i = 0; i < sub_nelts; ++i)
+ vec.quick_push (VECTOR_CST_ELT (value, i));
+ }
else
vec.quick_push (value);
}
@@ -1872,9 +1877,9 @@ build_vector_from_ctor (tree type, vec<constructor_elt, va_gc> *v)
/* Build a vector of type VECTYPE where all the elements are SCs. */
tree
-build_vector_from_val (tree vectype, tree sc)
+build_vector_from_val (tree vectype, tree sc)
{
- int i, nunits = TYPE_VECTOR_SUBPARTS (vectype);
+ unsigned HOST_WIDE_INT i, nunits;
if (sc == error_mark_node)
return sc;
@@ -1894,7 +1899,7 @@ build_vector_from_val (tree vectype, tree sc)
v.quick_push (sc);
return v.build ();
}
- else if (0)
+ else if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant (&nunits))
return fold_build1 (VEC_DUPLICATE_EXPR, vectype, sc);
else
{
@@ -6497,11 +6502,8 @@ type_hash_canon_hash (tree type)
}
case VECTOR_TYPE:
- {
- unsigned nunits = TYPE_VECTOR_SUBPARTS (type);
- hstate.add_object (nunits);
- break;
- }
+ hstate.add_poly_int (TYPE_VECTOR_SUBPARTS (type));
+ break;
default:
break;
@@ -6545,7 +6547,8 @@ type_cache_hasher::equal (type_hash *a, type_hash *b)
return 1;
case VECTOR_TYPE:
- return TYPE_VECTOR_SUBPARTS (a->type) == TYPE_VECTOR_SUBPARTS (b->type);
+ return known_eq (TYPE_VECTOR_SUBPARTS (a->type),
+ TYPE_VECTOR_SUBPARTS (b->type));
case ENUMERAL_TYPE:
if (TYPE_VALUES (a->type) != TYPE_VALUES (b->type)
@@ -9610,7 +9613,7 @@ make_vector_type (tree innertype, poly_int64 nunits, machine_mode mode)
t = make_node (VECTOR_TYPE);
TREE_TYPE (t) = mv_innertype;
- SET_TYPE_VECTOR_SUBPARTS (t, nunits.to_constant ()); /* Temporary */
+ SET_TYPE_VECTOR_SUBPARTS (t, nunits);
SET_TYPE_MODE (t, mode);
if (TYPE_STRUCTURAL_EQUALITY_P (mv_innertype) || in_lto_p)
@@ -10533,7 +10536,7 @@ build_vector_type_for_mode (tree innertype, machine_mode mode)
a power of two. */
tree
-build_vector_type (tree innertype, int nunits)
+build_vector_type (tree innertype, poly_int64 nunits)
{
return make_vector_type (innertype, nunits, VOIDmode);
}
@@ -10578,7 +10581,7 @@ build_same_sized_truth_vector_type (tree vectype)
/* Similarly, but builds a variant type with TYPE_VECTOR_OPAQUE set. */
tree
-build_opaque_vector_type (tree innertype, int nunits)
+build_opaque_vector_type (tree innertype, poly_int64 nunits)
{
tree t = make_vector_type (innertype, nunits, VOIDmode);
tree cand;
@@ -10727,7 +10730,7 @@ tree
uniform_vector_p (const_tree vec)
{
tree first, t;
- unsigned i;
+ unsigned HOST_WIDE_INT i, nelts;
if (vec == NULL_TREE)
return NULL_TREE;
@@ -10744,7 +10747,8 @@ uniform_vector_p (const_tree vec)
return NULL_TREE;
}
- else if (TREE_CODE (vec) == CONSTRUCTOR)
+ else if (TREE_CODE (vec) == CONSTRUCTOR
+ && TYPE_VECTOR_SUBPARTS (TREE_TYPE (vec)).is_constant (&nelts))
{
first = error_mark_node;
@@ -10758,7 +10762,7 @@ uniform_vector_p (const_tree vec)
if (!operand_equal_p (first, t, 0))
return NULL_TREE;
}
- if (i != TYPE_VECTOR_SUBPARTS (TREE_TYPE (vec)))
+ if (i != nelts)
return NULL_TREE;
return first;
@@ -13034,8 +13038,8 @@ vector_type_mode (const_tree t)
/* For integers, try mapping it to a same-sized scalar mode. */
if (is_int_mode (TREE_TYPE (t)->type_common.mode, &innermode))
{
- unsigned int size = (TYPE_VECTOR_SUBPARTS (t)
- * GET_MODE_BITSIZE (innermode));
+ poly_int64 size = (TYPE_VECTOR_SUBPARTS (t)
+ * GET_MODE_BITSIZE (innermode));
scalar_int_mode mode;
if (int_mode_for_size (size, 0).exists (&mode)
&& have_regs_of_mode[mode])
@@ -14319,7 +14323,7 @@ test_labels ()
static tree
build_vector (tree type, vec<tree> vals MEM_STAT_DECL)
{
- gcc_assert (vals.length () == TYPE_VECTOR_SUBPARTS (type));
+ gcc_assert (known_eq (vals.length (), TYPE_VECTOR_SUBPARTS (type)));
tree_vector_builder builder (type, vals.length (), 1);
builder.splice (vals);
return builder.build ();
@@ -14330,7 +14334,8 @@ build_vector (tree type, vec<tree> vals MEM_STAT_DECL)
static void
check_vector_cst (vec<tree> expected, tree actual)
{
- ASSERT_EQ (expected.length (), TYPE_VECTOR_SUBPARTS (TREE_TYPE (actual)));
+ ASSERT_KNOWN_EQ (expected.length (),
+ TYPE_VECTOR_SUBPARTS (TREE_TYPE (actual)));
for (unsigned int i = 0; i < expected.length (); ++i)
ASSERT_EQ (wi::to_wide (expected[i]),
wi::to_wide (vector_cst_elt (actual, i)));