Store VECTOR_CST_NELTS directly in tree_node
Richard Biener
richard.guenther@gmail.com
Thu Sep 14 13:28:00 GMT 2017
On Thu, Sep 14, 2017 at 1:13 PM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> Previously VECTOR_CST_NELTS (t) read the number of elements from
> TYPE_VECTOR_SUBPARTS (TREE_TYPE (t)). There were two ways of handling
> this with variable TYPE_VECTOR_SUBPARTS: either forcibly convert the
> number to a constant (which is doable) or store the number directly
> in the VECTOR_CST. The latter seemed better, since it involves less
> pointer chasing and since the tree_node u field is otherwise unused
> for VECTOR_CST. It would still be easy to switch to the former in
> future if we need to free up the field for someting else.
>
> The patch also changes various bits of VECTOR_CST code to use
> VECTOR_CST_NELTS instead of TYPE_VECTOR_SUBPARTS when iterating
> over VECTOR_CST_ELTs. Also, when the two are checked for equality,
> the patch prefers to read VECTOR_CST_NELTS (which must be constant)
> and check against TYPE_VECTOR_SUBPARTS, instead of the other way
> around.
>
> Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu.
> OK to install?
Ok but I don't see how this helps the variable TYPE_VECTOR_SUBPARTS case?
Are there no VECTOR_CSTs for SVE?
Thanks,
Richard.
> Richard
>
>
> 2017-09-14 Richard Sandiford <richard.sandiford@linaro.org>
> Alan Hayward <alan.hayward@arm.com>
> David Sherwood <david.sherwood@arm.com>
>
> gcc/
> * tree-core.h (tree_base::u): Add an "nelts" field.
> (tree_vector): Use VECTOR_CST_NELTS as the length.
> * tree.c (tree_size): Likewise.
> (make_vector): Initialize VECTOR_CST_NELTS.
> * tree.h (VECTOR_CST_NELTS): Use the u.nelts field.
> * cfgexpand.c (expand_debug_expr): Use VECTOR_CST_NELTS instead of
> TYPE_VECTOR_SUBPARTS.
> * expr.c (const_vector_mask_from_tree): Consistently use "units"
> as the number of units, setting it from VECTOR_CST_NELTS.
> (const_vector_from_tree): Likewise.
> * fold-const.c (negate_expr_p): Use VECTOR_CST_NELTS instead of
> TYPE_VECTOR_SUBPARTS for the number of elements in a VECTOR_CST.
> (fold_negate_expr_1): Likewise.
> (fold_convert_const): Likewise.
> (const_binop): Likewise. Differentiate the number of output and
> input elements.
> (const_unop): Likewise.
> (fold_ternary_loc): Use VECTOR_CST_NELTS for the number of elements
> in a VECTOR_CST, asserting that it is the same as TYPE_VECTOR_SUBPARTS
> in cases that did the opposite.
>
> Index: gcc/tree-core.h
> ===================================================================
> --- gcc/tree-core.h 2017-08-21 10:42:05.815630531 +0100
> +++ gcc/tree-core.h 2017-09-14 11:23:57.004041291 +0100
> @@ -975,6 +975,9 @@ struct GTY(()) tree_base {
> /* VEC length. This field is only used with TREE_VEC. */
> int length;
>
> + /* Number of elements. This field is only used with VECTOR_CST. */
> + unsigned int nelts;
> +
> /* SSA version number. This field is only used with SSA_NAME. */
> unsigned int version;
>
> @@ -1326,7 +1329,7 @@ struct GTY(()) tree_complex {
>
> struct GTY(()) tree_vector {
> struct tree_typed typed;
> - tree GTY ((length ("TYPE_VECTOR_SUBPARTS (TREE_TYPE ((tree)&%h))"))) elts[1];
> + tree GTY ((length ("VECTOR_CST_NELTS ((tree) &%h)"))) elts[1];
> };
>
> struct GTY(()) tree_identifier {
> Index: gcc/tree.c
> ===================================================================
> --- gcc/tree.c 2017-09-11 17:10:38.700973860 +0100
> +++ gcc/tree.c 2017-09-14 11:23:57.004947653 +0100
> @@ -873,7 +873,7 @@ tree_size (const_tree node)
>
> case VECTOR_CST:
> return (sizeof (struct tree_vector)
> - + (TYPE_VECTOR_SUBPARTS (TREE_TYPE (node)) - 1) * sizeof (tree));
> + + (VECTOR_CST_NELTS (node) - 1) * sizeof (tree));
>
> case STRING_CST:
> return TREE_STRING_LENGTH (node) + offsetof (struct tree_string, str) + 1;
> @@ -1696,6 +1696,7 @@ make_vector (unsigned len MEM_STAT_DECL)
>
> TREE_SET_CODE (t, VECTOR_CST);
> TREE_CONSTANT (t) = 1;
> + VECTOR_CST_NELTS (t) = len;
>
> return t;
> }
> Index: gcc/tree.h
> ===================================================================
> --- gcc/tree.h 2017-08-30 12:19:19.721220029 +0100
> +++ gcc/tree.h 2017-09-14 11:23:57.004947653 +0100
> @@ -1026,7 +1026,7 @@ #define TREE_REALPART(NODE) (COMPLEX_CST
> #define TREE_IMAGPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.imag)
>
> /* In a VECTOR_CST node. */
> -#define VECTOR_CST_NELTS(NODE) (TYPE_VECTOR_SUBPARTS (TREE_TYPE (NODE)))
> +#define VECTOR_CST_NELTS(NODE) (VECTOR_CST_CHECK (NODE)->base.u.nelts)
> #define VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elts)
> #define VECTOR_CST_ELT(NODE,IDX) (VECTOR_CST_CHECK (NODE)->vector.elts[IDX])
>
> Index: gcc/cfgexpand.c
> ===================================================================
> --- gcc/cfgexpand.c 2017-09-11 22:30:14.149035751 +0100
> +++ gcc/cfgexpand.c 2017-09-14 11:23:57.002228567 +0100
> @@ -4921,12 +4921,12 @@ expand_debug_expr (tree exp)
>
> case VECTOR_CST:
> {
> - unsigned i;
> + unsigned i, nelts;
>
> - op0 = gen_rtx_CONCATN
> - (mode, rtvec_alloc (TYPE_VECTOR_SUBPARTS (TREE_TYPE (exp))));
> + nelts = VECTOR_CST_NELTS (exp);
> + op0 = gen_rtx_CONCATN (mode, rtvec_alloc (nelts));
>
> - for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
> + for (i = 0; i < nelts; ++i)
> {
> op1 = expand_debug_expr (VECTOR_CST_ELT (exp, i));
> if (!op1)
> Index: gcc/expr.c
> ===================================================================
> --- gcc/expr.c 2017-09-12 14:27:14.527325485 +0100
> +++ gcc/expr.c 2017-09-14 11:23:57.003134929 +0100
> @@ -11700,18 +11700,17 @@ try_tablejump (tree index_type, tree ind
> const_vector_mask_from_tree (tree exp)
> {
> rtvec v;
> - unsigned i;
> - int units;
> + unsigned i, units;
> tree elt;
> machine_mode inner, mode;
>
> mode = TYPE_MODE (TREE_TYPE (exp));
> - units = GET_MODE_NUNITS (mode);
> + units = VECTOR_CST_NELTS (exp);
> inner = GET_MODE_INNER (mode);
>
> v = rtvec_alloc (units);
>
> - for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
> + for (i = 0; i < units; ++i)
> {
> elt = VECTOR_CST_ELT (exp, i);
>
> @@ -11756,8 +11755,7 @@ const_scalar_mask_from_tree (scalar_int_
> const_vector_from_tree (tree exp)
> {
> rtvec v;
> - unsigned i;
> - int units;
> + unsigned i, units;
> tree elt;
> machine_mode inner, mode;
>
> @@ -11769,12 +11767,12 @@ const_vector_from_tree (tree exp)
> if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
> return const_vector_mask_from_tree (exp);
>
> - units = GET_MODE_NUNITS (mode);
> + units = VECTOR_CST_NELTS (exp);
> inner = GET_MODE_INNER (mode);
>
> v = rtvec_alloc (units);
>
> - for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
> + for (i = 0; i < units; ++i)
> {
> elt = VECTOR_CST_ELT (exp, i);
>
> Index: gcc/fold-const.c
> ===================================================================
> --- gcc/fold-const.c 2017-09-06 20:47:38.353833985 +0100
> +++ gcc/fold-const.c 2017-09-14 11:23:57.004041291 +0100
> @@ -410,7 +410,7 @@ negate_expr_p (tree t)
> if (FLOAT_TYPE_P (TREE_TYPE (type)) || TYPE_OVERFLOW_WRAPS (type))
> return true;
>
> - int count = TYPE_VECTOR_SUBPARTS (type), i;
> + int count = VECTOR_CST_NELTS (t), i;
>
> for (i = 0; i < count; i++)
> if (!negate_expr_p (VECTOR_CST_ELT (t, i)))
> @@ -564,7 +564,7 @@ fold_negate_expr_1 (location_t loc, tree
>
> case VECTOR_CST:
> {
> - int count = TYPE_VECTOR_SUBPARTS (type), i;
> + int count = VECTOR_CST_NELTS (t), i;
> tree *elts = XALLOCAVEC (tree, count);
>
> for (i = 0; i < count; i++)
> @@ -1413,7 +1413,7 @@ const_binop (enum tree_code code, tree a
> && TREE_CODE (arg2) == VECTOR_CST)
> {
> tree type = TREE_TYPE (arg1);
> - int count = TYPE_VECTOR_SUBPARTS (type), i;
> + int count = VECTOR_CST_NELTS (arg1), i;
> tree *elts = XALLOCAVEC (tree, count);
>
> for (i = 0; i < count; i++)
> @@ -1437,7 +1437,7 @@ const_binop (enum tree_code code, tree a
> && TREE_CODE (arg2) == INTEGER_CST)
> {
> tree type = TREE_TYPE (arg1);
> - int count = TYPE_VECTOR_SUBPARTS (type), i;
> + int count = VECTOR_CST_NELTS (arg1), i;
> tree *elts = XALLOCAVEC (tree, count);
>
> for (i = 0; i < count; i++)
> @@ -1481,21 +1481,24 @@ const_binop (enum tree_code code, tree t
> case VEC_PACK_TRUNC_EXPR:
> case VEC_PACK_FIX_TRUNC_EXPR:
> {
> - unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
> tree *elts;
> + unsigned int out_nelts, in_nelts, i;
>
> - gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)) == nelts / 2
> - && TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg2)) == nelts / 2);
> if (TREE_CODE (arg1) != VECTOR_CST
> || TREE_CODE (arg2) != VECTOR_CST)
> return NULL_TREE;
>
> - elts = XALLOCAVEC (tree, nelts);
> + in_nelts = VECTOR_CST_NELTS (arg1);
> + out_nelts = in_nelts * 2;
> + gcc_assert (in_nelts == VECTOR_CST_NELTS (arg2)
> + && out_nelts == TYPE_VECTOR_SUBPARTS (type));
> +
> + elts = XALLOCAVEC (tree, out_nelts);
> if (!vec_cst_ctor_to_array (arg1, elts)
> - || !vec_cst_ctor_to_array (arg2, elts + nelts / 2))
> + || !vec_cst_ctor_to_array (arg2, elts + in_nelts))
> return NULL_TREE;
>
> - for (i = 0; i < nelts; i++)
> + for (i = 0; i < out_nelts; i++)
> {
> elts[i] = fold_convert_const (code == VEC_PACK_TRUNC_EXPR
> ? NOP_EXPR : FIX_TRUNC_EXPR,
> @@ -1512,33 +1515,35 @@ const_binop (enum tree_code code, tree t
> case VEC_WIDEN_MULT_EVEN_EXPR:
> case VEC_WIDEN_MULT_ODD_EXPR:
> {
> - unsigned int nelts = TYPE_VECTOR_SUBPARTS (type);
> - unsigned int out, ofs, scale;
> + unsigned int out_nelts, in_nelts, out, ofs, scale;
> tree *elts;
>
> - gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)) == nelts * 2
> - && TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg2)) == nelts * 2);
> if (TREE_CODE (arg1) != VECTOR_CST || TREE_CODE (arg2) != VECTOR_CST)
> return NULL_TREE;
>
> - elts = XALLOCAVEC (tree, nelts * 4);
> + in_nelts = VECTOR_CST_NELTS (arg1);
> + out_nelts = in_nelts / 2;
> + gcc_assert (in_nelts == VECTOR_CST_NELTS (arg2)
> + && out_nelts == TYPE_VECTOR_SUBPARTS (type));
> +
> + elts = XALLOCAVEC (tree, in_nelts * 2);
> if (!vec_cst_ctor_to_array (arg1, elts)
> - || !vec_cst_ctor_to_array (arg2, elts + nelts * 2))
> + || !vec_cst_ctor_to_array (arg2, elts + in_nelts))
> return NULL_TREE;
>
> if (code == VEC_WIDEN_MULT_LO_EXPR)
> - scale = 0, ofs = BYTES_BIG_ENDIAN ? nelts : 0;
> + scale = 0, ofs = BYTES_BIG_ENDIAN ? out_nelts : 0;
> else if (code == VEC_WIDEN_MULT_HI_EXPR)
> - scale = 0, ofs = BYTES_BIG_ENDIAN ? 0 : nelts;
> + scale = 0, ofs = BYTES_BIG_ENDIAN ? 0 : out_nelts;
> else if (code == VEC_WIDEN_MULT_EVEN_EXPR)
> scale = 1, ofs = 0;
> else /* if (code == VEC_WIDEN_MULT_ODD_EXPR) */
> scale = 1, ofs = 1;
>
> - for (out = 0; out < nelts; out++)
> + for (out = 0; out < out_nelts; out++)
> {
> unsigned int in1 = (out << scale) + ofs;
> - unsigned int in2 = in1 + nelts * 2;
> + unsigned int in2 = in1 + in_nelts;
> tree t1, t2;
>
> t1 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), elts[in1]);
> @@ -1671,28 +1676,31 @@ const_unop (enum tree_code code, tree ty
> case VEC_UNPACK_FLOAT_LO_EXPR:
> case VEC_UNPACK_FLOAT_HI_EXPR:
> {
> - unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
> + unsigned int out_nelts, in_nelts, i;
> tree *elts;
> enum tree_code subcode;
>
> - gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts * 2);
> if (TREE_CODE (arg0) != VECTOR_CST)
> return NULL_TREE;
>
> - elts = XALLOCAVEC (tree, nelts * 2);
> + in_nelts = VECTOR_CST_NELTS (arg0);
> + out_nelts = in_nelts / 2;
> + gcc_assert (out_nelts == TYPE_VECTOR_SUBPARTS (type));
> +
> + elts = XALLOCAVEC (tree, in_nelts);
> if (!vec_cst_ctor_to_array (arg0, elts))
> return NULL_TREE;
>
> if ((!BYTES_BIG_ENDIAN) ^ (code == VEC_UNPACK_LO_EXPR
> || code == VEC_UNPACK_FLOAT_LO_EXPR))
> - elts += nelts;
> + elts += out_nelts;
>
> if (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_HI_EXPR)
> subcode = NOP_EXPR;
> else
> subcode = FLOAT_EXPR;
>
> - for (i = 0; i < nelts; i++)
> + for (i = 0; i < out_nelts; i++)
> {
> elts[i] = fold_convert_const (subcode, TREE_TYPE (type), elts[i]);
> if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i]))
> @@ -1712,7 +1720,7 @@ const_unop (enum tree_code code, tree ty
>
> if (TREE_CODE (arg0) != VECTOR_CST)
> return NULL_TREE;
> - nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
> + nelts = VECTOR_CST_NELTS (arg0);
>
> elts = XALLOCAVEC (tree, nelts);
> if (!vec_cst_ctor_to_array (arg0, elts))
> @@ -2153,7 +2161,7 @@ fold_convert_const (enum tree_code code,
> if (TREE_CODE (arg1) == VECTOR_CST
> && TYPE_VECTOR_SUBPARTS (type) == VECTOR_CST_NELTS (arg1))
> {
> - int len = TYPE_VECTOR_SUBPARTS (type);
> + int len = VECTOR_CST_NELTS (arg1);
> tree elttype = TREE_TYPE (type);
> tree *v = XALLOCAVEC (tree, len);
> for (int i = 0; i < len; ++i)
> @@ -11311,9 +11319,9 @@ fold_ternary_loc (location_t loc, enum t
> && (TREE_CODE (arg2) == VECTOR_CST
> || TREE_CODE (arg2) == CONSTRUCTOR))
> {
> - unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
> + unsigned int nelts = VECTOR_CST_NELTS (arg0), i;
> unsigned char *sel = XALLOCAVEC (unsigned char, nelts);
> - gcc_assert (nelts == VECTOR_CST_NELTS (arg0));
> + gcc_assert (nelts == TYPE_VECTOR_SUBPARTS (type));
> for (i = 0; i < nelts; i++)
> {
> tree val = VECTOR_CST_ELT (arg0, i);
> @@ -11642,7 +11650,7 @@ fold_ternary_loc (location_t loc, enum t
> case VEC_PERM_EXPR:
> if (TREE_CODE (arg2) == VECTOR_CST)
> {
> - unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i, mask, mask2;
> + unsigned int nelts = VECTOR_CST_NELTS (arg2), i, mask, mask2;
> unsigned char *sel = XALLOCAVEC (unsigned char, 2 * nelts);
> unsigned char *sel2 = sel + nelts;
> bool need_mask_canon = false;
> @@ -11655,7 +11663,7 @@ fold_ternary_loc (location_t loc, enum t
>
> mask2 = 2 * nelts - 1;
> mask = single_arg ? (nelts - 1) : mask2;
> - gcc_assert (nelts == VECTOR_CST_NELTS (arg2));
> + gcc_assert (nelts == TYPE_VECTOR_SUBPARTS (type));
> for (i = 0; i < nelts; i++)
> {
> tree val = VECTOR_CST_ELT (arg2, i);
> @@ -11766,9 +11774,9 @@ fold_ternary_loc (location_t loc, enum t
> return arg0;
> else
> {
> - tree *elts = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type));
> - memcpy (elts, VECTOR_CST_ELTS (arg0),
> - sizeof (tree) * TYPE_VECTOR_SUBPARTS (type));
> + unsigned int nelts = VECTOR_CST_NELTS (arg0);
> + tree *elts = XALLOCAVEC (tree, nelts);
> + memcpy (elts, VECTOR_CST_ELTS (arg0), sizeof (tree) * nelts);
> elts[k] = arg1;
> return build_vector (type, elts);
> }
More information about the Gcc-patches
mailing list