diff options
-rw-r--r-- | gcc/ChangeLog | 40 | ||||
-rw-r--r-- | gcc/c-family/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/c-family/c-pretty-print.c | 10 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 19 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 6 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 108 | ||||
-rw-r--r-- | gcc/expmed.c | 8 | ||||
-rw-r--r-- | gcc/expr.c | 31 | ||||
-rw-r--r-- | gcc/fold-const.c | 188 | ||||
-rw-r--r-- | gcc/gimple-fold.c | 9 | ||||
-rw-r--r-- | gcc/print-tree.c | 11 | ||||
-rw-r--r-- | gcc/tree-pretty-print.c | 9 | ||||
-rw-r--r-- | gcc/tree-streamer-in.c | 12 | ||||
-rw-r--r-- | gcc/tree-streamer-out.c | 8 | ||||
-rw-r--r-- | gcc/tree-vect-generic.c | 26 | ||||
-rw-r--r-- | gcc/tree-vect-loop.c | 22 | ||||
-rw-r--r-- | gcc/tree-vect-slp.c | 44 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.c | 9 | ||||
-rw-r--r-- | gcc/tree.c | 69 | ||||
-rw-r--r-- | gcc/tree.h | 9 | ||||
-rw-r--r-- | gcc/varasm.c | 39 |
21 files changed, 342 insertions, 339 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8fc3e914a1e..eb696d7a733 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,43 @@ +2012-03-16 Richard Guenther <rguenther@suse.de> + + * tree.h (TREE_VECTOR_CST_ELTS): Remove. + (VECTOR_CST_NELTS, VECTOR_CST_ELTS, VECTOR_CST_ELT): New defines. + (struct tree_vector): Remove elements member, add variable size + elts array member. + (build_vector_stat): Declare. + (build_vector): Define in terms of build_vector_stat. + * tree.c (build_vector): Rename to ... + (build_vector_stat): ... this. Take array of trees as parameter. + (build_vector_from_ctor): Adjust. + (integer_zerop, integer_onep, integer_all_onesp, iterative_hash_expr, + initializer_zerop): Adjust. + * cfgexpand.c (expand_debug_expr): Likewise. + * expr.c (categorize_ctor_elements_1, expand_expr_real_1, + const_vector_from_tree): Likewise. + * fold-const.c (const_binop, operand_equal_p, native_encode_vector, + native_interpret_vector, fold_unary_loc, vec_cst_ctor_to_array, + fold_vec_perm, fold_binary_loc, fold_ternary_loc): Likewise. + * tree-streamer-in.c (streamer_alloc_tree): Handle TS_VECTOR. + (lto_input_ts_vector_tree_pointers): Adjust. + * tree-streamer-out.c (streamer_write_tree_header): Handle TS_VECTOR. + (write_ts_vector_tree_pointers): Adjust. + * varasm.c (const_hash_1, compare_constant, copy_constant, + output_constant): Adjust. + * gimple-fold.c (gimple_fold_stmt_to_constant_1): Adjust. + * print-tree.c (print_node): Adjust. + * tree-pretty-print.c (dump_generic_node): Adjust. + * tree-vect-generic.c (uniform_vector_p, vector_element, + lower_vec_perm): Adjust. + * tree-vect-loop.c (get_initial_def_for_reduction): Adjust. + * tree-vect-slp.c (vect_get_constant_vectors, + vect_transform_slp_perm_load): Adjust. + * tree-vect-stmts.c (vect_gen_perm_mask): Adjust. + * expmed.c (make_tree): Adjust. + * config/i386/i386.c (ix86_expand_builtin): Adjust. + * config/sparc/sparc.c (sparc_handle_vis_mul8x16): Adjust interface + and implementation. + (sparc_fold_builtin): Adjust. + 2012-03-16 Tristan Gingold <gingold@adacore.com> * config.gcc (*-*-*vms*): Define use_gcc_stdint and tm_file. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 274eacdc73d..dd7b77b355a 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,7 @@ +2012-03-16 Richard Guenther <rguenther@suse.de> + + * c-pretty-print.c (pp_c_initializer_list): Adjust. + 2012-03-15 Manuel López-Ibáñez <manu@gcc.gnu.org> PR c++/44783 diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c index dc63f0048de..929ad18384f 100644 --- a/gcc/c-family/c-pretty-print.c +++ b/gcc/c-family/c-pretty-print.c @@ -1372,7 +1372,15 @@ pp_c_initializer_list (c_pretty_printer *pp, tree e) case VECTOR_TYPE: if (TREE_CODE (e) == VECTOR_CST) - pp_c_expression_list (pp, TREE_VECTOR_CST_ELTS (e)); + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (e); ++i) + { + if (i > 0) + pp_separate_with (pp, ','); + pp_expression (pp, VECTOR_CST_ELT (e, i)); + } + } else break; return; diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 2f38bb4ee85..bd21169eb87 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -3354,9 +3354,22 @@ expand_debug_expr (tree exp) return op0; case VECTOR_CST: - exp = build_constructor_from_list (TREE_TYPE (exp), - TREE_VECTOR_CST_ELTS (exp)); - /* Fall through. */ + { + unsigned i; + + op0 = gen_rtx_CONCATN + (mode, rtvec_alloc (TYPE_VECTOR_SUBPARTS (TREE_TYPE (exp)))); + + for (i = 0; i < VECTOR_CST_NELTS (exp); ++i) + { + op1 = expand_debug_expr (VECTOR_CST_ELT (exp, i)); + if (!op1) + return NULL; + XVECEXP (op0, 0, i) = op1; + } + + return op0; + } case CONSTRUCTOR: if (TREE_CLOBBER_P (exp)) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 3f007a5bbdf..78a366ef7dc 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -29653,12 +29653,10 @@ rdrand_step: { if (TREE_CODE (arg3) == VECTOR_CST) { - tree elt; unsigned int negative = 0; - for (elt = TREE_VECTOR_CST_ELTS (arg3); - elt; elt = TREE_CHAIN (elt)) + for (i = 0; i < VECTOR_CST_NELTS (arg3); ++i) { - tree cst = TREE_VALUE (elt); + tree cst = VECTOR_CST_ELT (arg3, i); if (TREE_CODE (cst) == INTEGER_CST && tree_int_cst_sign_bit (cst)) negative++; diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 134843d98a3..4048db0560a 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -514,7 +514,7 @@ static void sparc_vis_init_builtins (void); static rtx sparc_expand_builtin (tree, rtx, rtx, enum machine_mode, int); static tree sparc_fold_builtin (tree, int, tree *, bool); static int sparc_vis_mul8x16 (int, int); -static tree sparc_handle_vis_mul8x16 (int, tree, tree, tree); +static void sparc_handle_vis_mul8x16 (tree *, int, tree, tree, tree); static void sparc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree); static bool sparc_can_output_mi_thunk (const_tree, HOST_WIDE_INT, @@ -9897,67 +9897,57 @@ sparc_vis_mul8x16 (int e8, int e16) return (e8 * e16 + 128) / 256; } -/* Multiply the vector elements in ELTS0 to the elements in ELTS1 as specified - by FNCODE. All of the elements in ELTS0 and ELTS1 lists must be integer - constants. A tree list with the results of the multiplications is returned, - and each element in the list is of INNER_TYPE. */ +/* Multiply the VECTOR_CSTs CST0 and CST1 as specified by FNCODE and put + the result into the array N_ELTS, whose elements are of INNER_TYPE. */ -static tree -sparc_handle_vis_mul8x16 (int fncode, tree inner_type, tree elts0, tree elts1) +static void +sparc_handle_vis_mul8x16 (tree *n_elts, int fncode, tree inner_type, + tree cst0, tree cst1) { - tree n_elts = NULL_TREE; + unsigned i, num = VECTOR_CST_NELTS (cst0); int scale; switch (fncode) { case CODE_FOR_fmul8x16_vis: - for (; elts0 && elts1; - elts0 = TREE_CHAIN (elts0), elts1 = TREE_CHAIN (elts1)) + for (i = 0; i < num; ++i) { int val - = sparc_vis_mul8x16 (TREE_INT_CST_LOW (TREE_VALUE (elts0)), - TREE_INT_CST_LOW (TREE_VALUE (elts1))); - n_elts = tree_cons (NULL_TREE, - build_int_cst (inner_type, val), - n_elts); + = sparc_vis_mul8x16 (TREE_INT_CST_LOW (VECTOR_CST_ELT (cst0, i)), + TREE_INT_CST_LOW (VECTOR_CST_ELT (cst1, i))); + n_elts[i] = build_int_cst (inner_type, val); } break; case CODE_FOR_fmul8x16au_vis: - scale = TREE_INT_CST_LOW (TREE_VALUE (elts1)); + scale = TREE_INT_CST_LOW (VECTOR_CST_ELT (cst1, 0)); - for (; elts0; elts0 = TREE_CHAIN (elts0)) + for (i = 0; i < num; ++i) { int val - = sparc_vis_mul8x16 (TREE_INT_CST_LOW (TREE_VALUE (elts0)), + = sparc_vis_mul8x16 (TREE_INT_CST_LOW (VECTOR_CST_ELT (cst0, i)), scale); - n_elts = tree_cons (NULL_TREE, - build_int_cst (inner_type, val), - n_elts); + n_elts[i] = build_int_cst (inner_type, val); } break; case CODE_FOR_fmul8x16al_vis: - scale = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (elts1))); + scale = TREE_INT_CST_LOW (VECTOR_CST_ELT (cst1, 0)); - for (; elts0; elts0 = TREE_CHAIN (elts0)) + for (i = 0; i < num; ++i) { int val - = sparc_vis_mul8x16 (TREE_INT_CST_LOW (TREE_VALUE (elts0)), + = sparc_vis_mul8x16 (TREE_INT_CST_LOW (VECTOR_CST_ELT (cst0, i)), scale); - n_elts = tree_cons (NULL_TREE, - build_int_cst (inner_type, val), - n_elts); + n_elts[i] = build_int_cst (inner_type, val); } break; default: gcc_unreachable (); } - - return nreverse (n_elts); - } + /* Handle TARGET_FOLD_BUILTIN target hook. Fold builtin functions for SPARC intrinsics. If IGNORE is true the result of the function call is ignored. NULL_TREE is returned if the @@ -10001,17 +9991,15 @@ sparc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, if (TREE_CODE (arg0) == VECTOR_CST) { tree inner_type = TREE_TYPE (rtype); - tree elts = TREE_VECTOR_CST_ELTS (arg0); - tree n_elts = NULL_TREE; - - for (; elts; elts = TREE_CHAIN (elts)) - { - unsigned int val = TREE_INT_CST_LOW (TREE_VALUE (elts)) << 4; - n_elts = tree_cons (NULL_TREE, - build_int_cst (inner_type, val), - n_elts); - } - return build_vector (rtype, nreverse (n_elts)); + tree *n_elts; + unsigned i; + + n_elts = XALLOCAVEC (tree, VECTOR_CST_NELTS (arg0)); + for (i = 0; i < VECTOR_CST_NELTS (arg0); ++i) + n_elts[i] = build_int_cst (inner_type, + TREE_INT_CST_LOW + (VECTOR_CST_ELT (arg0, i)) << 4); + return build_vector (rtype, n_elts); } break; @@ -10026,11 +10014,8 @@ sparc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, if (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST) { tree inner_type = TREE_TYPE (rtype); - tree elts0 = TREE_VECTOR_CST_ELTS (arg0); - tree elts1 = TREE_VECTOR_CST_ELTS (arg1); - tree n_elts = sparc_handle_vis_mul8x16 (icode, inner_type, elts0, - elts1); - + tree *n_elts = XALLOCAVEC (tree, VECTOR_CST_NELTS (arg0)); + sparc_handle_vis_mul8x16 (n_elts, icode, inner_type, arg0, arg1); return build_vector (rtype, n_elts); } break; @@ -10043,18 +10028,15 @@ sparc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, if (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST) { - tree elts0 = TREE_VECTOR_CST_ELTS (arg0); - tree elts1 = TREE_VECTOR_CST_ELTS (arg1); - tree n_elts = NULL_TREE; - - for (; elts0 && elts1; - elts0 = TREE_CHAIN (elts0), elts1 = TREE_CHAIN (elts1)) + tree *n_elts = XALLOCAVEC (tree, 2 * VECTOR_CST_NELTS (arg0)); + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (arg0); ++i) { - n_elts = tree_cons (NULL_TREE, TREE_VALUE (elts0), n_elts); - n_elts = tree_cons (NULL_TREE, TREE_VALUE (elts1), n_elts); + n_elts[2*i] = VECTOR_CST_ELT (arg0, i); + n_elts[2*i+1] = VECTOR_CST_ELT (arg1, i); } - return build_vector (rtype, nreverse (n_elts)); + return build_vector (rtype, n_elts); } break; @@ -10073,17 +10055,17 @@ sparc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, int overflow = 0; unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (arg2); HOST_WIDE_INT high = TREE_INT_CST_HIGH (arg2); - tree elts0 = TREE_VECTOR_CST_ELTS (arg0); - tree elts1 = TREE_VECTOR_CST_ELTS (arg1); + unsigned i; - for (; elts0 && elts1; - elts0 = TREE_CHAIN (elts0), elts1 = TREE_CHAIN (elts1)) + for (i = 0; i < VECTOR_CST_NELTS (arg0); ++i) { unsigned HOST_WIDE_INT - low0 = TREE_INT_CST_LOW (TREE_VALUE (elts0)), - low1 = TREE_INT_CST_LOW (TREE_VALUE (elts1)); - HOST_WIDE_INT high0 = TREE_INT_CST_HIGH (TREE_VALUE (elts0)); - HOST_WIDE_INT high1 = TREE_INT_CST_HIGH (TREE_VALUE (elts1)); + low0 = TREE_INT_CST_LOW (VECTOR_CST_ELT (arg0, i)), + low1 = TREE_INT_CST_LOW (VECTOR_CST_ELT (arg1, i)); + HOST_WIDE_INT + high0 = TREE_INT_CST_HIGH (VECTOR_CST_ELT (arg0, i)); + HOST_WIDE_INT + high1 = TREE_INT_CST_HIGH (VECTOR_CST_ELT (arg1, i)); unsigned HOST_WIDE_INT l; HOST_WIDE_INT h; diff --git a/gcc/expmed.c b/gcc/expmed.c index 09a933da5f5..5134b738b05 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -4970,18 +4970,18 @@ make_tree (tree type, rtx x) { int units = CONST_VECTOR_NUNITS (x); tree itype = TREE_TYPE (type); - tree t = NULL_TREE; + tree *elts; int i; - /* Build a tree with vector elements. */ + elts = XALLOCAVEC (tree, units); for (i = units - 1; i >= 0; --i) { rtx elt = CONST_VECTOR_ELT (x, i); - t = tree_cons (NULL_TREE, make_tree (itype, elt), t); + elts[i] = make_tree (itype, elt); } - return build_vector (type, t); + return build_vector (type, elts); } case PLUS: diff --git a/gcc/expr.c b/gcc/expr.c index dc4a82e92ae..df7cb03e7ef 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -5461,10 +5461,11 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts, case VECTOR_CST: { - tree v; - for (v = TREE_VECTOR_CST_ELTS (value); v; v = TREE_CHAIN (v)) + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (value); ++i) { - if (!initializer_zerop (TREE_VALUE (v))) + tree v = VECTOR_CST_ELT (value, i); + if (!initializer_zerop (v)) nz_elts += mult; init_elts += mult; } @@ -9122,8 +9123,14 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR, type_for_mode, exp); } if (!tmp) - tmp = build_constructor_from_list (type, - TREE_VECTOR_CST_ELTS (exp)); + { + VEC(constructor_elt,gc) *v; + unsigned i; + v = VEC_alloc (constructor_elt, gc, VECTOR_CST_NELTS (exp)); + for (i = 0; i < VECTOR_CST_NELTS (exp); ++i) + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, VECTOR_CST_ELT (exp, i)); + tmp = build_constructor (type, v); + } return expand_expr (tmp, ignore ? const0_rtx : target, tmode, modifier); } @@ -10767,8 +10774,9 @@ static rtx const_vector_from_tree (tree exp) { rtvec v; - int units, i; - tree link, elt; + unsigned i; + int units; + tree elt; enum machine_mode inner, mode; mode = TYPE_MODE (TREE_TYPE (exp)); @@ -10781,10 +10789,9 @@ const_vector_from_tree (tree exp) v = rtvec_alloc (units); - link = TREE_VECTOR_CST_ELTS (exp); - for (i = 0; link; link = TREE_CHAIN (link), ++i) + for (i = 0; i < VECTOR_CST_NELTS (exp); ++i) { - elt = TREE_VALUE (link); + elt = VECTOR_CST_ELT (exp, i); if (TREE_CODE (elt) == REAL_CST) RTVEC_ELT (v, i) = CONST_DOUBLE_FROM_REAL_VALUE (TREE_REAL_CST (elt), @@ -10797,10 +10804,6 @@ const_vector_from_tree (tree exp) inner); } - /* Initialize remaining elements to 0. */ - for (; i < units; ++i) - RTVEC_ELT (v, i) = CONST0_RTX (inner); - return gen_rtx_CONST_VECTOR (mode, v); } diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 9f5c0971761..0cd84285ee1 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -1351,49 +1351,27 @@ const_binop (enum tree_code code, tree arg1, tree arg2) return build_complex (type, real, imag); } - if (TREE_CODE (arg1) == VECTOR_CST) + if (TREE_CODE (arg1) == VECTOR_CST + && TREE_CODE (arg2) == VECTOR_CST) { tree type = TREE_TYPE(arg1); int count = TYPE_VECTOR_SUBPARTS (type), i; - tree elements1, elements2, list = NULL_TREE; - - if(TREE_CODE(arg2) != VECTOR_CST) - return NULL_TREE; - - elements1 = TREE_VECTOR_CST_ELTS (arg1); - elements2 = TREE_VECTOR_CST_ELTS (arg2); + tree *elts = XALLOCAVEC (tree, count); for (i = 0; i < count; i++) { - tree elem1, elem2, elem; + tree elem1 = VECTOR_CST_ELT (arg1, i); + tree elem2 = VECTOR_CST_ELT (arg2, i); - /* The trailing elements can be empty and should be treated as 0 */ - if(!elements1) - elem1 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), integer_zero_node); - else - { - elem1 = TREE_VALUE(elements1); - elements1 = TREE_CHAIN (elements1); - } - - if(!elements2) - elem2 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), integer_zero_node); - else - { - elem2 = TREE_VALUE(elements2); - elements2 = TREE_CHAIN (elements2); - } - - elem = const_binop (code, elem1, elem2); + elts[i] = const_binop (code, elem1, elem2); /* It is possible that const_binop cannot handle the given code and return NULL_TREE */ - if(elem == NULL_TREE) + if(elts[i] == NULL_TREE) return NULL_TREE; - - list = tree_cons (NULL_TREE, elem, list); } - return build_vector(type, nreverse(list)); + + return build_vector (type, elts); } return NULL_TREE; } @@ -2491,20 +2469,18 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) case VECTOR_CST: { - tree v1, v2; + unsigned i; - v1 = TREE_VECTOR_CST_ELTS (arg0); - v2 = TREE_VECTOR_CST_ELTS (arg1); - while (v1 && v2) + if (VECTOR_CST_NELTS (arg0) != VECTOR_CST_NELTS (arg1)) + return 0; + + for (i = 0; i < VECTOR_CST_NELTS (arg0); ++i) { - if (!operand_equal_p (TREE_VALUE (v1), TREE_VALUE (v2), - flags)) + if (!operand_equal_p (VECTOR_CST_ELT (arg0, i), + VECTOR_CST_ELT (arg1, i), flags)) return 0; - v1 = TREE_CHAIN (v1); - v2 = TREE_CHAIN (v2); } - - return v1 == v2; + return 1; } case COMPLEX_CST: @@ -7307,35 +7283,19 @@ native_encode_complex (const_tree expr, unsigned char *ptr, int len) static int native_encode_vector (const_tree expr, unsigned char *ptr, int len) { - int i, size, offset, count; - tree itype, elem, elements; + unsigned i, count; + int size, offset; + tree itype, elem; offset = 0; - elements = TREE_VECTOR_CST_ELTS (expr); - count = TYPE_VECTOR_SUBPARTS (TREE_TYPE (expr)); + count = VECTOR_CST_NELTS (expr); itype = TREE_TYPE (TREE_TYPE (expr)); size = GET_MODE_SIZE (TYPE_MODE (itype)); for (i = 0; i < count; i++) { - if (elements) - { - elem = TREE_VALUE (elements); - elements = TREE_CHAIN (elements); - } - else - elem = NULL_TREE; - - if (elem) - { - if (native_encode_expr (elem, ptr+offset, len-offset) != size) - return 0; - } - else - { - if (offset + size > len) - return 0; - memset (ptr+offset, 0, size); - } + elem = VECTOR_CST_ELT (expr, i); + if (native_encode_expr (elem, ptr+offset, len-offset) != size) + return 0; offset += size; } return offset; @@ -7534,8 +7494,9 @@ native_interpret_complex (tree type, const unsigned char *ptr, int len) static tree native_interpret_vector (tree type, const unsigned char *ptr, int len) { - tree etype, elem, elements; + tree etype, elem; int i, size, count; + tree *elements; etype = TREE_TYPE (type); size = GET_MODE_SIZE (TYPE_MODE (etype)); @@ -7543,13 +7504,13 @@ native_interpret_vector (tree type, const unsigned char *ptr, int len) if (size * count > len) return NULL_TREE; - elements = NULL_TREE; + elements = XALLOCAVEC (tree, count); for (i = count - 1; i >= 0; i--) { elem = native_interpret_expr (etype, ptr+(i*size), size); if (!elem) return NULL_TREE; - elements = tree_cons (NULL_TREE, elem, elements); + elements[i] = elem; } return build_vector (type, elements); } @@ -8169,25 +8130,21 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) /* Perform BIT_NOT_EXPR on each element individually. */ else if (TREE_CODE (arg0) == VECTOR_CST) { - tree elements = TREE_VECTOR_CST_ELTS (arg0), elem, list = NULL_TREE; - int count = TYPE_VECTOR_SUBPARTS (type), i; + tree *elements; + tree elem; + unsigned count = VECTOR_CST_NELTS (arg0), i; + elements = XALLOCAVEC (tree, count); for (i = 0; i < count; i++) { - if (elements) - { - elem = TREE_VALUE (elements); - elem = fold_unary_loc (loc, BIT_NOT_EXPR, TREE_TYPE (type), elem); - if (elem == NULL_TREE) - break; - elements = TREE_CHAIN (elements); - } - else - elem = build_int_cst (TREE_TYPE (type), -1); - list = tree_cons (NULL_TREE, elem, list); + elem = VECTOR_CST_ELT (arg0, i); + elem = fold_unary_loc (loc, BIT_NOT_EXPR, TREE_TYPE (type), elem); + if (elem == NULL_TREE) + break; + elements[i] = elem; } if (i == count) - return build_vector (type, nreverse (list)); + return build_vector (type, elements); } return NULL_TREE; @@ -8310,7 +8267,7 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) case VEC_UNPACK_FLOAT_HI_EXPR: { unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i; - tree *elts, vals = NULL_TREE; + tree *elts; enum tree_code subcode; gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts * 2); @@ -8337,9 +8294,7 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) return NULL_TREE; } - for (i = 0; i < nelts; i++) - vals = tree_cons (NULL_TREE, elts[nelts - i - 1], vals); - return build_vector (type, vals); + return build_vector (type, elts); } default: @@ -9608,13 +9563,8 @@ vec_cst_ctor_to_array (tree arg, tree *elts) if (TREE_CODE (arg) == VECTOR_CST) { - tree t; - - for (i = 0, t = TREE_VECTOR_CST_ELTS (arg); - i < nelts && t; i++, t = TREE_CHAIN (t)) - elts[i] = TREE_VALUE (t); - if (t) - return false; + for (i = 0; i < VECTOR_CST_NELTS (arg); ++i) + elts[i] = VECTOR_CST_ELT (arg, i); } else if (TREE_CODE (arg) == CONSTRUCTOR) { @@ -9671,12 +9621,7 @@ fold_vec_perm (tree type, tree arg0, tree arg1, const unsigned char *sel) return build_constructor (type, v); } else - { - tree vals = NULL_TREE; - for (i = 0; i < nelts; i++) - vals = tree_cons (NULL_TREE, elts[3 * nelts - i - 1], vals); - return build_vector (type, vals); - } + return build_vector (type, &elts[2 * nelts]); } /* Try to fold a pointer difference of type TYPE two address expressions of @@ -13574,7 +13519,7 @@ fold_binary_loc (location_t loc, case VEC_PACK_FIX_TRUNC_EXPR: { unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i; - tree *elts, vals = NULL_TREE; + tree *elts; gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts / 2 && TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)) == nelts / 2); @@ -13595,16 +13540,14 @@ fold_binary_loc (location_t loc, return NULL_TREE; } - for (i = 0; i < nelts; i++) - vals = tree_cons (NULL_TREE, elts[nelts - i - 1], vals); - return build_vector (type, vals); + return build_vector (type, elts); } case VEC_WIDEN_MULT_LO_EXPR: case VEC_WIDEN_MULT_HI_EXPR: { unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i; - tree *elts, vals = NULL_TREE; + tree *elts; gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts * 2 && TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)) == nelts * 2); @@ -13632,9 +13575,7 @@ fold_binary_loc (location_t loc, return NULL_TREE; } - for (i = 0; i < nelts; i++) - vals = tree_cons (NULL_TREE, elts[nelts - i - 1], vals); - return build_vector (type, vals); + return build_vector (type, elts); } default: @@ -13991,13 +13932,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, < TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0))) { if (TREE_CODE (arg0) == VECTOR_CST) - { - tree elements = TREE_VECTOR_CST_ELTS (arg0); - while (idx-- > 0 && elements) - elements = TREE_CHAIN (elements); - if (elements) - return TREE_VALUE (elements); - } + return VECTOR_CST_ELT (arg0, idx); else if (idx < CONSTRUCTOR_NELTS (arg0)) return CONSTRUCTOR_ELT (arg0, idx)->value; return build_zero_cst (type); @@ -14031,23 +13966,19 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, tree t; bool need_mask_canon = false; - gcc_assert (nelts == TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg2))); - for (i = 0, t = TREE_VECTOR_CST_ELTS (arg2); - i < nelts && t; i++, t = TREE_CHAIN (t)) + gcc_assert (nelts == VECTOR_CST_NELTS (arg2)); + for (i = 0; i < nelts; i++) { - if (TREE_CODE (TREE_VALUE (t)) != INTEGER_CST) + tree val = VECTOR_CST_ELT (arg2, i); + if (TREE_CODE (val) != INTEGER_CST) return NULL_TREE; - sel[i] = TREE_INT_CST_LOW (TREE_VALUE (t)) & (2 * nelts - 1); - if (TREE_INT_CST_HIGH (TREE_VALUE (t)) + sel[i] = TREE_INT_CST_LOW (val) & (2 * nelts - 1); + if (TREE_INT_CST_HIGH (val) || ((unsigned HOST_WIDE_INT) - TREE_INT_CST_LOW (TREE_VALUE (t)) != sel[i])) + TREE_INT_CST_LOW (val) != sel[i])) need_mask_canon = true; } - if (t) - return NULL_TREE; - for (; i < nelts; i++) - sel[i] = 0; if ((TREE_CODE (arg0) == VECTOR_CST || TREE_CODE (arg0) == CONSTRUCTOR) @@ -14061,12 +13992,11 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, if (need_mask_canon && arg2 == op2) { - tree list = NULL_TREE, eltype = TREE_TYPE (TREE_TYPE (arg2)); + tree *tsel = XALLOCAVEC (tree, nelts); + tree eltype = TREE_TYPE (TREE_TYPE (arg2)); for (i = 0; i < nelts; i++) - list = tree_cons (NULL_TREE, - build_int_cst (eltype, sel[nelts - i - 1]), - list); - t = build_vector (TREE_TYPE (arg2), list); + tsel[i] = build_int_cst (eltype, sel[nelts - i - 1]); + t = build_vector (TREE_TYPE (arg2), tsel); return build3_loc (loc, VEC_PERM_EXPR, type, op0, op1, t); } } diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index d4028398079..a1eba65e042 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -2467,21 +2467,22 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree)) == TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)))) { unsigned i; - tree val, list; + tree val, *vec; - list = NULL_TREE; + vec = XALLOCAVEC (tree, + TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))); FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val) { val = (*valueize) (val); if (TREE_CODE (val) == INTEGER_CST || TREE_CODE (val) == REAL_CST || TREE_CODE (val) == FIXED_CST) - list = tree_cons (NULL_TREE, val, list); + vec[i] = val; else return NULL_TREE; } - return build_vector (TREE_TYPE (rhs), nreverse (list)); + return build_vector (TREE_TYPE (rhs), vec); } if (kind == tcc_reference) diff --git a/gcc/print-tree.c b/gcc/print-tree.c index 7fb71d0b475..466b7db7469 100644 --- a/gcc/print-tree.c +++ b/gcc/print-tree.c @@ -821,16 +821,13 @@ print_node (FILE *file, const char *prefix, tree node, int indent) case VECTOR_CST: { - tree vals = TREE_VECTOR_CST_ELTS (node); char buf[10]; - tree link; - int i; + unsigned i; - i = 0; - for (link = vals; link; link = TREE_CHAIN (link), ++i) + for (i = 0; i < VECTOR_CST_NELTS (node); ++i) { - sprintf (buf, "elt%d: ", i); - print_node (file, buf, TREE_VALUE (link), indent + 4); + sprintf (buf, "elt%u: ", i); + print_node (file, buf, VECTOR_CST_ELT (node, i), indent + 4); } } break; diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index 227999cd0d6..6e6a5f8ae9e 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -1112,13 +1112,14 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags, case VECTOR_CST: { - tree elt; + unsigned i; pp_string (buffer, "{ "); - for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt)) + for (i = 0; i < VECTOR_CST_NELTS (node); ++i) { - dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false); - if (TREE_CHAIN (elt)) + if (i != 0) pp_string (buffer, ", "); + dump_generic_node (buffer, VECTOR_CST_ELT (node, i), + spc, flags, false); } pp_string (buffer, " }"); } diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c index cb940aa7871..50ea77d1b13 100644 --- a/gcc/tree-streamer-in.c +++ b/gcc/tree-streamer-in.c @@ -473,6 +473,14 @@ streamer_alloc_tree (struct lto_input_block *ib, struct data_in *data_in, HOST_WIDE_INT len = streamer_read_hwi (ib); result = make_tree_vec (len); } + else if (CODE_CONTAINS_STRUCT (code, TS_VECTOR)) + { + HOST_WIDE_INT len = streamer_read_hwi (ib); + result = ggc_alloc_zone_cleared_tree_node_stat (&tree_zone, + (len - 1) * sizeof (tree) + + sizeof (struct tree_vector)); + TREE_SET_CODE (result, VECTOR_CST); + } else if (CODE_CONTAINS_STRUCT (code, TS_BINFO)) { unsigned HOST_WIDE_INT len = streamer_read_uhwi (ib); @@ -525,7 +533,9 @@ static void lto_input_ts_vector_tree_pointers (struct lto_input_block *ib, struct data_in *data_in, tree expr) { - TREE_VECTOR_CST_ELTS (expr) = streamer_read_chain (ib, data_in); + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + VECTOR_CST_ELT (expr, i) = stream_read_tree (ib, data_in); } diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c index c792fc2acf0..8fe7d7992c6 100644 --- a/gcc/tree-streamer-out.c +++ b/gcc/tree-streamer-out.c @@ -441,7 +441,11 @@ write_ts_common_tree_pointers (struct output_block *ob, tree expr, bool ref_p) static void write_ts_vector_tree_pointers (struct output_block *ob, tree expr, bool ref_p) { - streamer_write_chain (ob, TREE_VECTOR_CST_ELTS (expr), ref_p); + unsigned i; + /* Note that the number of elements for EXPR has already been emitted + in EXPR's header (see streamer_write_tree_header). */ + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + stream_write_tree (ob, VECTOR_CST_ELT (expr, i), ref_p); } @@ -907,6 +911,8 @@ streamer_write_tree_header (struct output_block *ob, tree expr) streamer_write_string_cst (ob, ob->main_stream, expr); else if (CODE_CONTAINS_STRUCT (code, TS_IDENTIFIER)) write_identifier (ob, ob->main_stream, expr); + else if (CODE_CONTAINS_STRUCT (code, TS_VECTOR)) + streamer_write_hwi (ob, VECTOR_CST_NELTS (expr)); else if (CODE_CONTAINS_STRUCT (code, TS_VEC)) streamer_write_hwi (ob, TREE_VEC_LENGTH (expr)); else if (CODE_CONTAINS_STRUCT (code, TS_BINFO)) diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c index 83f177044fa..203f62caec7 100644 --- a/gcc/tree-vect-generic.c +++ b/gcc/tree-vect-generic.c @@ -334,7 +334,7 @@ expand_vector_addition (gimple_stmt_iterator *gsi, static tree uniform_vector_p (tree vec) { - tree first, t, els; + tree first, t; unsigned i; if (vec == NULL_TREE) @@ -342,12 +342,9 @@ uniform_vector_p (tree vec) if (TREE_CODE (vec) == VECTOR_CST) { - els = TREE_VECTOR_CST_ELTS (vec); - first = TREE_VALUE (els); - els = TREE_CHAIN (els); - - for (t = els; t; t = TREE_CHAIN (t)) - if (!operand_equal_p (first, TREE_VALUE (t), 0)) + first = VECTOR_CST_ELT (vec, 0); + for (i = 1; i < VECTOR_CST_NELTS (vec); ++i) + if (!operand_equal_p (first, VECTOR_CST_ELT (vec, i), 0)) return NULL_TREE; return first; @@ -556,14 +553,7 @@ vector_element (gimple_stmt_iterator *gsi, tree vect, tree idx, tree *ptmpvec) } if (TREE_CODE (vect) == VECTOR_CST) - { - unsigned i; - tree vals = TREE_VECTOR_CST_ELTS (vect); - for (i = 0; vals; vals = TREE_CHAIN (vals), ++i) - if (i == index) - return TREE_VALUE (vals); - return build_zero_cst (vect_elt_type); - } + return VECTOR_CST_ELT (vect, index); else if (TREE_CODE (vect) == CONSTRUCTOR) { unsigned i; @@ -640,10 +630,10 @@ lower_vec_perm (gimple_stmt_iterator *gsi) if (TREE_CODE (mask) == VECTOR_CST) { unsigned char *sel_int = XALLOCAVEC (unsigned char, elements); - tree vals = TREE_VECTOR_CST_ELTS (mask); - for (i = 0; i < elements; ++i, vals = TREE_CHAIN (vals)) - sel_int[i] = TREE_INT_CST_LOW (TREE_VALUE (vals)) & (2 * elements - 1); + for (i = 0; i < elements; ++i) + sel_int[i] = (TREE_INT_CST_LOW (VECTOR_CST_ELT (mask, i)) + & (2 * elements - 1)); if (can_vec_perm_p (TYPE_MODE (vect_type), false, sel_int)) return; diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 5733bc8d244..abba2b9dbca 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -3305,7 +3305,7 @@ get_initial_def_for_reduction (gimple stmt, tree init_val, enum tree_code code = gimple_assign_rhs_code (stmt); tree def_for_init; tree init_def; - tree t = NULL_TREE; + tree *elts; int i; bool nested_in_vect_loop = false; tree init_value; @@ -3386,23 +3386,31 @@ get_initial_def_for_reduction (gimple stmt, tree init_val, def_for_init = build_int_cst (scalar_type, int_init_val); /* Create a vector of '0' or '1' except the first element. */ + elts = XALLOCAVEC (tree, nunits); for (i = nunits - 2; i >= 0; --i) - t = tree_cons (NULL_TREE, def_for_init, t); + elts[i + 1] = def_for_init; /* Option1: the first element is '0' or '1' as well. */ if (adjustment_def) { - t = tree_cons (NULL_TREE, def_for_init, t); - init_def = build_vector (vectype, t); + elts[0] = def_for_init; + init_def = build_vector (vectype, elts); break; } /* Option2: the first element is INIT_VAL. */ - t = tree_cons (NULL_TREE, init_value, t); + elts[0] = init_val; if (TREE_CONSTANT (init_val)) - init_def = build_vector (vectype, t); + init_def = build_vector (vectype, elts); else - init_def = build_constructor_from_list (vectype, t); + { + VEC(constructor_elt,gc) *v; + v = VEC_alloc (constructor_elt, gc, nunits); + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_val); + for (i = 1; i < nunits; ++i) + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[i]); + init_def = build_constructor (vectype, v); + } break; diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 3ba984e3bd7..dbfe78d9351 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -2205,15 +2205,15 @@ vect_get_constant_vectors (tree op, slp_tree slp_node, VEC (gimple, heap) *stmts = SLP_TREE_SCALAR_STMTS (slp_node); gimple stmt = VEC_index (gimple, stmts, 0); stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); - int nunits; + unsigned nunits; tree vec_cst; - tree t = NULL_TREE; - int j, number_of_places_left_in_vector; + tree *elts; + unsigned j, number_of_places_left_in_vector; tree vector_type; tree vop; int group_size = VEC_length (gimple, stmts); unsigned int vec_num, i; - int number_of_copies = 1; + unsigned number_of_copies = 1; VEC (tree, heap) *voprnds = VEC_alloc (tree, heap, number_of_vectors); bool constant_p, is_store; tree neutral_op = NULL; @@ -2307,6 +2307,7 @@ vect_get_constant_vectors (tree op, slp_tree slp_node, number_of_copies = least_common_multiple (nunits, group_size) / group_size; number_of_places_left_in_vector = nunits; + elts = XALLOCAVEC (tree, nunits); for (j = 0; j < number_of_copies; j++) { for (i = group_size - 1; VEC_iterate (gimple, stmts, i, stmt); i--) @@ -2361,21 +2362,27 @@ vect_get_constant_vectors (tree op, slp_tree slp_node, } /* Create 'vect_ = {op0,op1,...,opn}'. */ - t = tree_cons (NULL_TREE, op, t); - number_of_places_left_in_vector--; + elts[number_of_places_left_in_vector] = op; if (number_of_places_left_in_vector == 0) { number_of_places_left_in_vector = nunits; if (constant_p) - vec_cst = build_vector (vector_type, t); + vec_cst = build_vector (vector_type, elts); else - vec_cst = build_constructor_from_list (vector_type, t); + { + VEC(constructor_elt,gc) *v; + unsigned k; + v = VEC_alloc (constructor_elt, gc, nunits); + for (k = 0; k < nunits; ++k) + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, elts[k]); + vec_cst = build_constructor (vector_type, v); + } VEC_quick_push (tree, voprnds, - vect_init_vector (stmt, vec_cst, vector_type, NULL)); - t = NULL_TREE; + vect_init_vector (stmt, vec_cst, + vector_type, NULL)); } } } @@ -2383,9 +2390,9 @@ vect_get_constant_vectors (tree op, slp_tree slp_node, /* Since the vectors are created in the reverse order, we should invert them. */ vec_num = VEC_length (tree, voprnds); - for (j = vec_num - 1; j >= 0; j--) + for (j = vec_num; j != 0; j--) { - vop = VEC_index (tree, voprnds, j); + vop = VEC_index (tree, voprnds, j - 1); VEC_quick_push (tree, *vec_oprnds, vop); } @@ -2777,7 +2784,8 @@ vect_transform_slp_perm_load (gimple stmt, VEC (tree, heap) *dr_chain, if (index == nunits) { - tree mask_vec = NULL; + tree mask_vec, *mask_elts; + int l; if (!can_vec_perm_p (mode, false, mask)) { @@ -2791,12 +2799,10 @@ vect_transform_slp_perm_load (gimple stmt, VEC (tree, heap) *dr_chain, return false; } - while (--index >= 0) - { - tree t = build_int_cst (mask_element_type, mask[index]); - mask_vec = tree_cons (NULL, t, mask_vec); - } - mask_vec = build_vector (mask_type, mask_vec); + mask_elts = XALLOCAVEC (tree, nunits); + for (l = 0; l < nunits; ++l) + mask_elts[l] = build_int_cst (mask_element_type, mask[l]); + mask_vec = build_vector (mask_type, mask_elts); index = 0; if (!analyze_only) diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 0e7914f026e..13859aff0b2 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -4091,7 +4091,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, tree vect_gen_perm_mask (tree vectype, unsigned char *sel) { - tree mask_elt_type, mask_type, mask_vec; + tree mask_elt_type, mask_type, mask_vec, *mask_elts; int i, nunits; nunits = TYPE_VECTOR_SUBPARTS (vectype); @@ -4103,11 +4103,10 @@ vect_gen_perm_mask (tree vectype, unsigned char *sel) (int_mode_for_mode (TYPE_MODE (TREE_TYPE (vectype))), 1); mask_type = get_vectype_for_scalar_type (mask_elt_type); - mask_vec = NULL; + mask_elts = XALLOCAVEC (tree, nunits); for (i = nunits - 1; i >= 0; i--) - mask_vec = tree_cons (NULL, build_int_cst (mask_elt_type, sel[i]), - mask_vec); - mask_vec = build_vector (mask_type, mask_vec); + mask_elts[i] = build_int_cst (mask_elt_type, sel[i]); + mask_vec = build_vector (mask_type, mask_elts); return mask_vec; } diff --git a/gcc/tree.c b/gcc/tree.c index c90331ca560..1734fc5ed0a 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -1315,21 +1315,28 @@ cst_and_fits_in_hwi (const_tree x) are in a list pointed to by VALS. */ tree -build_vector (tree type, tree vals) +build_vector_stat (tree type, tree *vals MEM_STAT_DECL) { - tree v = make_node (VECTOR_CST); int over = 0; - tree link; unsigned cnt = 0; + tree v; + int length = ((TYPE_VECTOR_SUBPARTS (type) - 1) * sizeof (tree) + + sizeof (struct tree_vector)); + + record_node_allocation_statistics (VECTOR_CST, length); + + v = ggc_alloc_zone_cleared_tree_node_stat (&tree_zone, length PASS_MEM_STAT); - TREE_VECTOR_CST_ELTS (v) = vals; + TREE_SET_CODE (v, VECTOR_CST); + TREE_CONSTANT (v) = 1; TREE_TYPE (v) = type; /* Iterate through elements and check for overflow. */ - for (link = vals; link; link = TREE_CHAIN (link)) + for (cnt = 0; cnt < TYPE_VECTOR_SUBPARTS (type); ++cnt) { - tree value = TREE_VALUE (link); - cnt++; + tree value = vals[cnt]; + + VECTOR_CST_ELT (v, cnt) = value; /* Don't crash if we get an address constant. */ if (!CONSTANT_CLASS_P (value)) @@ -1338,8 +1345,6 @@ build_vector (tree type, tree vals) over |= TREE_OVERFLOW (value); } - gcc_assert (cnt == TYPE_VECTOR_SUBPARTS (type)); - TREE_OVERFLOW (v) = over; return v; } @@ -1350,16 +1355,16 @@ build_vector (tree type, tree vals) tree build_vector_from_ctor (tree type, VEC(constructor_elt,gc) *v) { - tree list = NULL_TREE; + tree *vec = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type)); unsigned HOST_WIDE_INT idx; tree value; FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value) - list = tree_cons (NULL_TREE, value, list); + vec[idx] = value; for (; idx < TYPE_VECTOR_SUBPARTS (type); ++idx) - list = tree_cons (NULL_TREE, - build_zero_cst (TREE_TYPE (type)), list); - return build_vector (type, nreverse (list)); + vec[idx] = build_zero_cst (TREE_TYPE (type)); + + return build_vector (type, vec); } /* Build a vector of type VECTYPE where all the elements are SCs. */ @@ -1724,9 +1729,9 @@ integer_zerop (const_tree expr) && integer_zerop (TREE_IMAGPART (expr))); case VECTOR_CST: { - tree elt; - for (elt = TREE_VECTOR_CST_ELTS (expr); elt; elt = TREE_CHAIN (elt)) - if (!integer_zerop (TREE_VALUE (elt))) + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + if (!integer_zerop (VECTOR_CST_ELT (expr, i))) return false; return true; } @@ -1753,9 +1758,9 @@ integer_onep (const_tree expr) && integer_zerop (TREE_IMAGPART (expr))); case VECTOR_CST: { - tree elt; - for (elt = TREE_VECTOR_CST_ELTS (expr); elt; elt = TREE_CHAIN (elt)) - if (!integer_onep (TREE_VALUE (elt))) + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + if (!integer_onep (VECTOR_CST_ELT (expr, i))) return false; return true; } @@ -1782,9 +1787,9 @@ integer_all_onesp (const_tree expr) else if (TREE_CODE (expr) == VECTOR_CST) { - tree elt; - for (elt = TREE_VECTOR_CST_ELTS (expr); elt; elt = TREE_CHAIN (elt)) - if (!integer_all_onesp (TREE_VALUE (elt))) + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) + if (!integer_all_onesp (VECTOR_CST_ELT (expr, i))) return 0; return 1; } @@ -6944,7 +6949,12 @@ iterative_hash_expr (const_tree t, hashval_t val) val = iterative_hash_expr (TREE_REALPART (t), val); return iterative_hash_expr (TREE_IMAGPART (t), val); case VECTOR_CST: - return iterative_hash_expr (TREE_VECTOR_CST_ELTS (t), val); + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (t); ++i) + val = iterative_hash_expr (VECTOR_CST_ELT (t, i), val); + return val; + } case SSA_NAME: /* We can just compare by pointer. */ return iterative_hash_host_wide_int (SSA_NAME_VERSION (t), val); @@ -9889,10 +9899,13 @@ initializer_zerop (const_tree init) && ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (TREE_IMAGPART (init)))); case VECTOR_CST: - for (elt = TREE_VECTOR_CST_ELTS (init); elt; elt = TREE_CHAIN (elt)) - if (!initializer_zerop (TREE_VALUE (elt))) - return false; - return true; + { + unsigned i; + for (i = 0; i < VECTOR_CST_NELTS (init); ++i) + if (!initializer_zerop (VECTOR_CST_ELT (init, i))) + return false; + return true; + } case CONSTRUCTOR: { diff --git a/gcc/tree.h b/gcc/tree.h index d9e826b26dd..c0340aafd39 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1534,11 +1534,13 @@ struct GTY(()) tree_complex { }; /* In a VECTOR_CST node. */ -#define TREE_VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elements) +#define VECTOR_CST_NELTS(NODE) (TYPE_VECTOR_SUBPARTS (TREE_TYPE (NODE))) +#define VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elts) +#define VECTOR_CST_ELT(NODE,IDX) (VECTOR_CST_CHECK (NODE)->vector.elts[IDX]) struct GTY(()) tree_vector { struct tree_typed typed; - tree elements; + tree GTY ((length ("TYPE_VECTOR_SUBPARTS (TREE_TYPE ((tree)&%h))"))) elts[1]; }; #include "symtab.h" @@ -4337,7 +4339,8 @@ build_int_cstu (tree type, unsigned HOST_WIDE_INT cst) extern tree build_int_cst (tree, HOST_WIDE_INT); extern tree build_int_cst_type (tree, HOST_WIDE_INT); extern tree build_int_cst_wide (tree, unsigned HOST_WIDE_INT, HOST_WIDE_INT); -extern tree build_vector (tree, tree); +extern tree build_vector_stat (tree, tree * MEM_STAT_DECL); +#define build_vector(t,v) build_vector_stat (t, v MEM_STAT_INFO) extern tree build_vector_from_ctor (tree, VEC(constructor_elt,gc) *); extern tree build_vector_from_val (tree, tree); extern tree build_constructor (tree, VEC(constructor_elt,gc) *); diff --git a/gcc/varasm.c b/gcc/varasm.c index 79c81fa7991..9bead9b10f2 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -2706,12 +2706,12 @@ const_hash_1 (const tree exp) case VECTOR_CST: { - tree link; + unsigned i; - hi = 7 + TYPE_VECTOR_SUBPARTS (TREE_TYPE (exp)); + hi = 7 + VECTOR_CST_NELTS (exp); - for (link = TREE_VECTOR_CST_ELTS (exp); link; link = TREE_CHAIN (link)) - hi = hi * 563 + const_hash_1 (TREE_VALUE (link)); + for (i = 0; i < VECTOR_CST_NELTS (exp); ++i) + hi = hi * 563 + const_hash_1 (VECTOR_CST_ELT (exp, i)); return hi; } @@ -2846,21 +2846,15 @@ compare_constant (const tree t1, const tree t2) case VECTOR_CST: { - tree link1, link2; + unsigned i; - if (TYPE_VECTOR_SUBPARTS (TREE_TYPE (t1)) - != TYPE_VECTOR_SUBPARTS (TREE_TYPE (t2))) + if (VECTOR_CST_NELTS (t1) != VECTOR_CST_NELTS (t2)) return 0; - link2 = TREE_VECTOR_CST_ELTS (t2); - for (link1 = TREE_VECTOR_CST_ELTS (t1); - link1; - link1 = TREE_CHAIN (link1)) - { - if (!compare_constant (TREE_VALUE (link1), TREE_VALUE (link2))) - return 0; - link2 = TREE_CHAIN (link2); - } + for (i = 0; i < VECTOR_CST_NELTS (t1); ++i) + if (!compare_constant (VECTOR_CST_ELT (t1, i), + VECTOR_CST_ELT (t2, i))) + return 0; return 1; } @@ -3014,8 +3008,7 @@ copy_constant (tree exp) copy_constant (TREE_OPERAND (exp, 0))); case VECTOR_CST: - return build_vector (TREE_TYPE (exp), - copy_list (TREE_VECTOR_CST_ELTS (exp))); + return build_vector (TREE_TYPE (exp), VECTOR_CST_ELTS (exp)); case CONSTRUCTOR: { @@ -4595,8 +4588,7 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align) case VECTOR_CST: { int elt_size; - tree link; - unsigned int nalign; + unsigned int i, nalign; enum machine_mode inner; inner = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp))); @@ -4604,12 +4596,11 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align) elt_size = GET_MODE_SIZE (inner); - link = TREE_VECTOR_CST_ELTS (exp); - output_constant (TREE_VALUE (link), elt_size, align); + output_constant (VECTOR_CST_ELT (exp, 0), elt_size, align); thissize = elt_size; - while ((link = TREE_CHAIN (link)) != NULL) + for (i = 1; i < VECTOR_CST_NELTS (exp); ++i) { - output_constant (TREE_VALUE (link), elt_size, nalign); + output_constant (VECTOR_CST_ELT (exp, i), elt_size, nalign); thissize += elt_size; } break; |