summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog40
-rw-r--r--gcc/c-family/ChangeLog4
-rw-r--r--gcc/c-family/c-pretty-print.c10
-rw-r--r--gcc/cfgexpand.c19
-rw-r--r--gcc/config/i386/i386.c6
-rw-r--r--gcc/config/sparc/sparc.c108
-rw-r--r--gcc/expmed.c8
-rw-r--r--gcc/expr.c31
-rw-r--r--gcc/fold-const.c188
-rw-r--r--gcc/gimple-fold.c9
-rw-r--r--gcc/print-tree.c11
-rw-r--r--gcc/tree-pretty-print.c9
-rw-r--r--gcc/tree-streamer-in.c12
-rw-r--r--gcc/tree-streamer-out.c8
-rw-r--r--gcc/tree-vect-generic.c26
-rw-r--r--gcc/tree-vect-loop.c22
-rw-r--r--gcc/tree-vect-slp.c44
-rw-r--r--gcc/tree-vect-stmts.c9
-rw-r--r--gcc/tree.c69
-rw-r--r--gcc/tree.h9
-rw-r--r--gcc/varasm.c39
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;