diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-09-14 15:46:08 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-09-14 15:46:08 +0000 |
commit | 794e31808f1554d51f0f0357c3a74a6365f0a274 (patch) | |
tree | d491aa520d3a8de4b35dbdde63439716c15b6f8d /gcc/fold-const.c | |
parent | 9e822269364f5268b2bdc82530fd6c871f47b1bc (diff) | |
download | gcc-794e31808f1554d51f0f0357c3a74a6365f0a274.zip gcc-794e31808f1554d51f0f0357c3a74a6365f0a274.tar.gz gcc-794e31808f1554d51f0f0357c3a74a6365f0a274.tar.bz2 |
Use vec<> in build_vector
This patch makes build_vector take the elements as a vec<> rather
than a tree *. This is useful for SVE because it bundles the number
of elements with the elements themselves, and enforces the fact that
the number is constant. Also, I think things like the folds can be used
with any generic GNU vector, not just those that match machine vectors,
so the arguments to XALLOCAVEC had no clear limit.
2017-09-14 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* tree.h (build_vector): Take a vec<tree> instead of a tree *.
* tree.c (build_vector): Likewise.
(build_vector_from_ctor): Update accordingly.
(build_vector_from_val): Likewise.
* gimple-fold.c (gimple_fold_stmt_to_constant_1): Likewise.
* tree-ssa-forwprop.c (simplify_vector_constructor): Likewise.
* tree-vect-generic.c (add_rshift): Likewise.
(expand_vector_divmod): Likewise.
(optimize_vector_constructor): Likewise.
* tree-vect-slp.c (vect_get_constant_vectors): Likewise.
(vect_transform_slp_perm_load): Likewise.
(vect_schedule_slp_instance): Likewise.
* tree-vect-stmts.c (vectorizable_bswap): Likewise.
(vectorizable_call): Likewise.
(vect_gen_perm_mask_any): Likewise. Add elements in order.
* expmed.c (make_tree): Likewise.
* fold-const.c (fold_negate_expr_1): Use auto_vec<tree> when building
a vector passed to build_vector.
(fold_convert_const): Likewise.
(exact_inverse): Likewise.
(fold_ternary_loc): Likewise.
(fold_relational_const): Likewise.
(const_binop): Likewise. Use VECTOR_CST_ELT directly when operating
on VECTOR_CSTs, rather than going through vec_cst_ctor_to_array.
(const_unop): Likewise. Store the reduction accumulator in a
variable rather than an array.
(vec_cst_ctor_to_array): Take the number of elements as a parameter.
(fold_vec_perm): Update calls accordingly. Use auto_vec<tree> for
the new vector, rather than constructing it after the input arrays.
(native_interpret_vector): Use auto_vec<tree> when building
a vector passed to build_vector. Add elements in order.
* tree-vect-loop.c (get_initial_defs_for_reduction): Use
auto_vec<tree> when building a vector passed to build_vector.
(vect_create_epilog_for_reduction): Likewise.
(vectorizable_induction): Likewise.
(get_initial_def_for_reduction): Likewise. Fix indentation of
case statements.
* config/sparc/sparc.c (sparc_handle_vis_mul8x16): Change n_elts
to a vec<tree> *.
(sparc_fold_builtin): Use auto_vec<tree> when building a vector
passed to build_vector.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r252760
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 177 |
1 files changed, 86 insertions, 91 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 66e7cc7..013081d 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -136,7 +136,6 @@ static tree fold_not_const (const_tree, tree); static tree fold_relational_const (enum tree_code, tree, tree, tree); static tree fold_convert_const (enum tree_code, tree, tree); static tree fold_view_convert_expr (tree, tree); -static bool vec_cst_ctor_to_array (tree, tree *); static tree fold_negate_expr (location_t, tree); @@ -565,13 +564,14 @@ fold_negate_expr_1 (location_t loc, tree t) case VECTOR_CST: { int count = VECTOR_CST_NELTS (t), i; - tree *elts = XALLOCAVEC (tree, count); + auto_vec<tree, 32> elts (count); for (i = 0; i < count; i++) { - elts[i] = fold_negate_expr (loc, VECTOR_CST_ELT (t, i)); - if (elts[i] == NULL_TREE) + tree elt = fold_negate_expr (loc, VECTOR_CST_ELT (t, i)); + if (elt == NULL_TREE) return NULL_TREE; + elts.quick_push (elt); } return build_vector (type, elts); @@ -1414,19 +1414,20 @@ const_binop (enum tree_code code, tree arg1, tree arg2) { tree type = TREE_TYPE (arg1); int count = VECTOR_CST_NELTS (arg1), i; - tree *elts = XALLOCAVEC (tree, count); + auto_vec<tree, 32> elts (count); for (i = 0; i < count; i++) { tree elem1 = VECTOR_CST_ELT (arg1, i); tree elem2 = VECTOR_CST_ELT (arg2, i); - elts[i] = const_binop (code, elem1, elem2); + tree elt = const_binop (code, elem1, elem2); /* It is possible that const_binop cannot handle the given code and return NULL_TREE */ - if (elts[i] == NULL_TREE) + if (elt == NULL_TREE) return NULL_TREE; + elts.quick_push (elt); } return build_vector (type, elts); @@ -1438,18 +1439,19 @@ const_binop (enum tree_code code, tree arg1, tree arg2) { tree type = TREE_TYPE (arg1); int count = VECTOR_CST_NELTS (arg1), i; - tree *elts = XALLOCAVEC (tree, count); + auto_vec<tree, 32> elts (count); for (i = 0; i < count; i++) { tree elem1 = VECTOR_CST_ELT (arg1, i); - elts[i] = const_binop (code, elem1, arg2); + tree elt = const_binop (code, elem1, arg2); /* It is possible that const_binop cannot handle the given code and return NULL_TREE. */ - if (elts[i] == NULL_TREE) + if (elt == NULL_TREE) return NULL_TREE; + elts.quick_push (elt); } return build_vector (type, elts); @@ -1481,7 +1483,6 @@ const_binop (enum tree_code code, tree type, tree arg1, tree arg2) case VEC_PACK_TRUNC_EXPR: case VEC_PACK_FIX_TRUNC_EXPR: { - tree *elts; unsigned int out_nelts, in_nelts, i; if (TREE_CODE (arg1) != VECTOR_CST @@ -1493,18 +1494,18 @@ const_binop (enum tree_code code, tree type, tree arg1, tree arg2) 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 + in_nelts)) - return NULL_TREE; - + auto_vec<tree, 32> elts (out_nelts); for (i = 0; i < out_nelts; i++) { - elts[i] = fold_convert_const (code == VEC_PACK_TRUNC_EXPR - ? NOP_EXPR : FIX_TRUNC_EXPR, - TREE_TYPE (type), elts[i]); - if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i])) + tree elt = (i < in_nelts + ? VECTOR_CST_ELT (arg1, i) + : VECTOR_CST_ELT (arg2, i - in_nelts)); + elt = fold_convert_const (code == VEC_PACK_TRUNC_EXPR + ? NOP_EXPR : FIX_TRUNC_EXPR, + TREE_TYPE (type), elt); + if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt)) return NULL_TREE; + elts.quick_push (elt); } return build_vector (type, elts); @@ -1516,7 +1517,6 @@ const_binop (enum tree_code code, tree type, tree arg1, tree arg2) case VEC_WIDEN_MULT_ODD_EXPR: { unsigned int out_nelts, in_nelts, out, ofs, scale; - tree *elts; if (TREE_CODE (arg1) != VECTOR_CST || TREE_CODE (arg2) != VECTOR_CST) return NULL_TREE; @@ -1526,11 +1526,6 @@ const_binop (enum tree_code code, tree type, tree arg1, tree arg2) 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 + in_nelts)) - return NULL_TREE; - if (code == VEC_WIDEN_MULT_LO_EXPR) scale = 0, ofs = BYTES_BIG_ENDIAN ? out_nelts : 0; else if (code == VEC_WIDEN_MULT_HI_EXPR) @@ -1540,20 +1535,21 @@ const_binop (enum tree_code code, tree type, tree arg1, tree arg2) else /* if (code == VEC_WIDEN_MULT_ODD_EXPR) */ scale = 1, ofs = 1; + auto_vec<tree, 32> elts (out_nelts); for (out = 0; out < out_nelts; out++) { - unsigned int in1 = (out << scale) + ofs; - unsigned int in2 = in1 + in_nelts; - tree t1, t2; - - t1 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), elts[in1]); - t2 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), elts[in2]); + unsigned int in = (out << scale) + ofs; + tree t1 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), + VECTOR_CST_ELT (arg1, in)); + tree t2 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), + VECTOR_CST_ELT (arg2, in)); if (t1 == NULL_TREE || t2 == NULL_TREE) return NULL_TREE; - elts[out] = const_binop (MULT_EXPR, t1, t2); - if (elts[out] == NULL_TREE || !CONSTANT_CLASS_P (elts[out])) + tree elt = const_binop (MULT_EXPR, t1, t2); + if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt)) return NULL_TREE; + elts.quick_push (elt); } return build_vector (type, elts); @@ -1638,18 +1634,17 @@ const_unop (enum tree_code code, tree type, tree arg0) /* Perform BIT_NOT_EXPR on each element individually. */ else if (TREE_CODE (arg0) == VECTOR_CST) { - tree *elements; tree elem; unsigned count = VECTOR_CST_NELTS (arg0), i; - elements = XALLOCAVEC (tree, count); + auto_vec<tree, 32> elements (count); for (i = 0; i < count; i++) { elem = VECTOR_CST_ELT (arg0, i); elem = const_unop (BIT_NOT_EXPR, TREE_TYPE (type), elem); if (elem == NULL_TREE) break; - elements[i] = elem; + elements.quick_push (elem); } if (i == count) return build_vector (type, elements); @@ -1677,7 +1672,6 @@ const_unop (enum tree_code code, tree type, tree arg0) case VEC_UNPACK_FLOAT_HI_EXPR: { unsigned int out_nelts, in_nelts, i; - tree *elts; enum tree_code subcode; if (TREE_CODE (arg0) != VECTOR_CST) @@ -1687,24 +1681,24 @@ const_unop (enum tree_code code, tree type, tree 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; - + unsigned int offset = 0; if ((!BYTES_BIG_ENDIAN) ^ (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_FLOAT_LO_EXPR)) - elts += out_nelts; + offset = out_nelts; if (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_HI_EXPR) subcode = NOP_EXPR; else subcode = FLOAT_EXPR; + auto_vec<tree, 32> elts (out_nelts); 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])) + tree elt = fold_convert_const (subcode, TREE_TYPE (type), + VECTOR_CST_ELT (arg0, i + offset)); + if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt)) return NULL_TREE; + elts.quick_push (elt); } return build_vector (type, elts); @@ -1715,17 +1709,12 @@ const_unop (enum tree_code code, tree type, tree arg0) case REDUC_PLUS_EXPR: { unsigned int nelts, i; - tree *elts; enum tree_code subcode; if (TREE_CODE (arg0) != VECTOR_CST) return NULL_TREE; nelts = VECTOR_CST_NELTS (arg0); - elts = XALLOCAVEC (tree, nelts); - if (!vec_cst_ctor_to_array (arg0, elts)) - return NULL_TREE; - switch (code) { case REDUC_MIN_EXPR: subcode = MIN_EXPR; break; @@ -1734,14 +1723,15 @@ const_unop (enum tree_code code, tree type, tree arg0) default: gcc_unreachable (); } + tree res = VECTOR_CST_ELT (arg0, 0); for (i = 1; i < nelts; i++) { - elts[0] = const_binop (subcode, elts[0], elts[i]); - if (elts[0] == NULL_TREE || !CONSTANT_CLASS_P (elts[0])) + res = const_binop (subcode, res, VECTOR_CST_ELT (arg0, i)); + if (res == NULL_TREE || !CONSTANT_CLASS_P (res)) return NULL_TREE; } - return elts[0]; + return res; } default: @@ -2163,14 +2153,14 @@ fold_convert_const (enum tree_code code, tree type, tree arg1) { int len = VECTOR_CST_NELTS (arg1); tree elttype = TREE_TYPE (type); - tree *v = XALLOCAVEC (tree, len); + auto_vec<tree, 32> v (len); for (int i = 0; i < len; ++i) { tree elt = VECTOR_CST_ELT (arg1, i); tree cvt = fold_convert_const (code, elttype, elt); if (cvt == NULL_TREE) return NULL_TREE; - v[i] = cvt; + v.quick_push (cvt); } return build_vector (type, v); } @@ -7392,7 +7382,6 @@ native_interpret_vector (tree type, const unsigned char *ptr, int len) { tree etype, elem; int i, size, count; - tree *elements; etype = TREE_TYPE (type); size = GET_MODE_SIZE (SCALAR_TYPE_MODE (etype)); @@ -7400,13 +7389,13 @@ native_interpret_vector (tree type, const unsigned char *ptr, int len) if (size * count > len) return NULL_TREE; - elements = XALLOCAVEC (tree, count); - for (i = count - 1; i >= 0; i--) + auto_vec<tree, 32> elements (count); + for (i = 0; i < count; ++i) { elem = native_interpret_expr (etype, ptr+(i*size), size); if (!elem) return NULL_TREE; - elements[i] = elem; + elements.quick_push (elem); } return build_vector (type, elements); } @@ -8761,12 +8750,13 @@ fold_mult_zconjz (location_t loc, tree type, tree expr) /* Helper function for fold_vec_perm. Store elements of VECTOR_CST or - CONSTRUCTOR ARG into array ELTS and return true if successful. */ + CONSTRUCTOR ARG into array ELTS, which has NELTS elements, and return + true if successful. */ static bool -vec_cst_ctor_to_array (tree arg, tree *elts) +vec_cst_ctor_to_array (tree arg, unsigned int nelts, tree *elts) { - unsigned int nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg)), i; + unsigned int i; if (TREE_CODE (arg) == VECTOR_CST) { @@ -8799,7 +8789,6 @@ static tree fold_vec_perm (tree type, tree arg0, tree arg1, const unsigned char *sel) { unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i; - tree *elts; bool need_ctor = false; gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts @@ -8808,16 +8797,17 @@ fold_vec_perm (tree type, tree arg0, tree arg1, const unsigned char *sel) || TREE_TYPE (TREE_TYPE (arg1)) != TREE_TYPE (type)) return NULL_TREE; - elts = XALLOCAVEC (tree, nelts * 3); - if (!vec_cst_ctor_to_array (arg0, elts) - || !vec_cst_ctor_to_array (arg1, elts + nelts)) + tree *in_elts = XALLOCAVEC (tree, nelts * 2); + if (!vec_cst_ctor_to_array (arg0, nelts, in_elts) + || !vec_cst_ctor_to_array (arg1, nelts, in_elts + nelts)) return NULL_TREE; + auto_vec<tree, 32> out_elts (nelts); for (i = 0; i < nelts; i++) { - if (!CONSTANT_CLASS_P (elts[sel[i]])) + if (!CONSTANT_CLASS_P (in_elts[sel[i]])) need_ctor = true; - elts[i + 2 * nelts] = unshare_expr (elts[sel[i]]); + out_elts.quick_push (unshare_expr (in_elts[sel[i]])); } if (need_ctor) @@ -8825,11 +8815,11 @@ fold_vec_perm (tree type, tree arg0, tree arg1, const unsigned char *sel) vec<constructor_elt, va_gc> *v; vec_alloc (v, nelts); for (i = 0; i < nelts; i++) - CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[2 * nelts + i]); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, out_elts[i]); return build_constructor (type, v); } else - return build_vector (type, &elts[2 * nelts]); + return build_vector (type, out_elts); } /* Try to fold a pointer difference of type TYPE two address expressions of @@ -8879,7 +8869,7 @@ tree exact_inverse (tree type, tree cst) { REAL_VALUE_TYPE r; - tree unit_type, *elts; + tree unit_type; machine_mode mode; unsigned vec_nelts, i; @@ -8894,20 +8884,22 @@ exact_inverse (tree type, tree cst) return NULL_TREE; case VECTOR_CST: - vec_nelts = VECTOR_CST_NELTS (cst); - elts = XALLOCAVEC (tree, vec_nelts); - unit_type = TREE_TYPE (type); - mode = TYPE_MODE (unit_type); + { + vec_nelts = VECTOR_CST_NELTS (cst); + unit_type = TREE_TYPE (type); + mode = TYPE_MODE (unit_type); - for (i = 0; i < vec_nelts; i++) - { - r = TREE_REAL_CST (VECTOR_CST_ELT (cst, i)); - if (!exact_real_inverse (mode, &r)) - return NULL_TREE; - elts[i] = build_real (unit_type, r); - } + auto_vec<tree, 32> elts (vec_nelts); + for (i = 0; i < vec_nelts; i++) + { + r = TREE_REAL_CST (VECTOR_CST_ELT (cst, i)); + if (!exact_real_inverse (mode, &r)) + return NULL_TREE; + elts.quick_push (build_real (unit_type, r)); + } - return build_vector (type, elts); + return build_vector (type, elts); + } default: return NULL_TREE; @@ -11596,9 +11588,9 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, if (n == 1) return VECTOR_CST_ELT (arg0, idx); - tree *vals = XALLOCAVEC (tree, n); + auto_vec<tree, 32> vals (n); for (unsigned i = 0; i < n; ++i) - vals[i] = VECTOR_CST_ELT (arg0, idx + i); + vals.quick_push (VECTOR_CST_ELT (arg0, idx + i)); return build_vector (type, vals); } } @@ -11731,10 +11723,10 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, if (need_mask_canon && arg2 == op2) { - tree *tsel = XALLOCAVEC (tree, nelts); tree eltype = TREE_TYPE (TREE_TYPE (arg2)); + auto_vec<tree, 32> tsel (nelts); for (i = 0; i < nelts; i++) - tsel[i] = build_int_cst (eltype, sel[i]); + tsel.quick_push (build_int_cst (eltype, sel[i])); op2 = build_vector (TREE_TYPE (arg2), tsel); changed = true; } @@ -11775,8 +11767,10 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, else { unsigned int nelts = VECTOR_CST_NELTS (arg0); - tree *elts = XALLOCAVEC (tree, nelts); - memcpy (elts, VECTOR_CST_ELTS (arg0), sizeof (tree) * nelts); + auto_vec<tree, 32> elts (nelts); + elts.quick_grow (nelts); + memcpy (&elts[0], VECTOR_CST_ELTS (arg0), + sizeof (tree) * nelts); elts[k] = arg1; return build_vector (type, elts); } @@ -13894,10 +13888,10 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1) return constant_boolean_node (true, type); } unsigned count = VECTOR_CST_NELTS (op0); - tree *elts = XALLOCAVEC (tree, count); gcc_assert (VECTOR_CST_NELTS (op1) == count && TYPE_VECTOR_SUBPARTS (type) == count); + auto_vec<tree, 32> elts (count); for (unsigned i = 0; i < count; i++) { tree elem_type = TREE_TYPE (type); @@ -13910,7 +13904,8 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1) if (tem == NULL_TREE) return NULL_TREE; - elts[i] = build_int_cst (elem_type, integer_zerop (tem) ? 0 : -1); + elts.quick_push (build_int_cst (elem_type, + integer_zerop (tem) ? 0 : -1)); } return build_vector (type, elts); |