Message ID | 87h8w5y1mr.fsf@linaro.org |
---|---|
State | New |
Headers | show |
Series | Store VECTOR_CST_NELTS directly in tree_node | expand |
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 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
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); }