diff mbox series

Store VECTOR_CST_NELTS directly in tree_node

Message ID 87h8w5y1mr.fsf@linaro.org
State New
Headers show
Series Store VECTOR_CST_NELTS directly in tree_node | expand

Commit Message

Richard Sandiford Sept. 14, 2017, 11:13 a.m. UTC
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?

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.

Comments

Richard Biener Sept. 14, 2017, 1:28 p.m. UTC | #1
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);

>                 }
Richard Sandiford Sept. 14, 2017, 2:07 p.m. UTC | #2
Richard Biener <richard.guenther@gmail.com> writes:
> 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?


Not for SVE in the normal variable-length case, no.  We have different tree
codes for building braodcast and step vectors.

So it's similar in some ways to the scalar_mode stuff: the fact that we
have a VECTOR_CST is "proof" that we have a constant number of elements.

Thanks,
Richard
diff mbox series

Patch

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);
 		}