This patch makes various bits of CONST_VECTOR-building code use rtx_vector_builder, operating directly on a specific encoding.
2017-12-28 Richard Sandiford <richard.sandif...@linaro.org> gcc/ * expr.c: Include rtx-vector-builder.h. (const_vector_mask_from_tree): Use rtx_vector_builder and operate directly on the tree encoding. (const_vector_from_tree): Likewise. * optabs.c: Include rtx-vector-builder.h. (expand_vec_perm_var): Use rtx_vector_builder and create a repeating sequence of "u" values. * vec-perm-indices.c: Include rtx-vector-builder.h. (vec_perm_indices_to_rtx): Use rtx_vector_builder and operate directly on the vec_perm_indices encoding. Index: gcc/expr.c =================================================================== --- gcc/expr.c 2017-12-22 12:58:44.518127920 +0000 +++ gcc/expr.c 2017-12-22 13:09:48.535709302 +0000 @@ -61,6 +61,7 @@ Software Foundation; either version 3, o #include "tree-chkp.h" #include "rtl-chkp.h" #include "ccmp.h" +#include "rtx-vector-builder.h" /* If this is nonzero, we do not bother generating VOLATILE @@ -11761,32 +11762,25 @@ try_tablejump (tree index_type, tree ind static rtx const_vector_mask_from_tree (tree exp) { - rtvec v; - unsigned i, units; - tree elt; - machine_mode inner, mode; - - mode = TYPE_MODE (TREE_TYPE (exp)); - units = VECTOR_CST_NELTS (exp); - inner = GET_MODE_INNER (mode); - - v = rtvec_alloc (units); + machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); + machine_mode inner = GET_MODE_INNER (mode); - for (i = 0; i < units; ++i) + rtx_vector_builder builder (mode, VECTOR_CST_NPATTERNS (exp), + VECTOR_CST_NELTS_PER_PATTERN (exp)); + unsigned int count = builder.encoded_nelts (); + for (unsigned int i = 0; i < count; ++i) { - elt = VECTOR_CST_ELT (exp, i); - + tree elt = VECTOR_CST_ELT (exp, i); gcc_assert (TREE_CODE (elt) == INTEGER_CST); if (integer_zerop (elt)) - RTVEC_ELT (v, i) = CONST0_RTX (inner); + builder.quick_push (CONST0_RTX (inner)); else if (integer_onep (elt) || integer_minus_onep (elt)) - RTVEC_ELT (v, i) = CONSTM1_RTX (inner); + builder.quick_push (CONSTM1_RTX (inner)); else gcc_unreachable (); } - - return gen_rtx_CONST_VECTOR (mode, v); + return builder.build (); } /* EXP is a VECTOR_CST in which each element is either all-zeros or all-ones. @@ -11816,12 +11810,7 @@ const_scalar_mask_from_tree (scalar_int_ static rtx const_vector_from_tree (tree exp) { - rtvec v; - unsigned i, units; - tree elt; - machine_mode inner, mode; - - mode = TYPE_MODE (TREE_TYPE (exp)); + machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); if (initializer_zerop (exp)) return CONST0_RTX (mode); @@ -11829,27 +11818,25 @@ const_vector_from_tree (tree exp) if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp))) return const_vector_mask_from_tree (exp); - units = VECTOR_CST_NELTS (exp); - inner = GET_MODE_INNER (mode); - - v = rtvec_alloc (units); + machine_mode inner = GET_MODE_INNER (mode); - for (i = 0; i < units; ++i) + rtx_vector_builder builder (mode, VECTOR_CST_NPATTERNS (exp), + VECTOR_CST_NELTS_PER_PATTERN (exp)); + unsigned int count = builder.encoded_nelts (); + for (unsigned int i = 0; i < count; ++i) { - elt = VECTOR_CST_ELT (exp, i); - + tree 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), - inner); + builder.quick_push (const_double_from_real_value (TREE_REAL_CST (elt), + inner)); else if (TREE_CODE (elt) == FIXED_CST) - RTVEC_ELT (v, i) = CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (elt), - inner); + builder.quick_push (CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (elt), + inner)); else - RTVEC_ELT (v, i) = immed_wide_int_const (wi::to_poly_wide (elt), - inner); + builder.quick_push (immed_wide_int_const (wi::to_poly_wide (elt), + inner)); } - - return gen_rtx_CONST_VECTOR (mode, v); + return builder.build (); } /* Build a decl for a personality function given a language prefix. */ Index: gcc/optabs.c =================================================================== --- gcc/optabs.c 2017-12-22 13:06:03.092620276 +0000 +++ gcc/optabs.c 2017-12-22 13:09:48.535709302 +0000 @@ -33,6 +33,7 @@ Software Foundation; either version 3, o #include "emit-rtl.h" #include "recog.h" #include "diagnostic-core.h" +#include "rtx-vector-builder.h" /* Include insn-config.h before expr.h so that HAVE_conditional_move is properly defined. */ @@ -5609,7 +5610,6 @@ expand_vec_perm_var (machine_mode mode, enum insn_code icode; unsigned int i, w, u; rtx tmp, sel_qi; - rtvec vec; w = GET_MODE_SIZE (mode); u = GET_MODE_UNIT_SIZE (mode); @@ -5661,10 +5661,10 @@ expand_vec_perm_var (machine_mode mode, /* Add the byte offset to each byte element. */ /* Note that the definition of the indicies here is memory ordering, so there should be no difference between big and little endian. */ - vec = rtvec_alloc (w); - for (i = 0; i < w; ++i) - RTVEC_ELT (vec, i) = GEN_INT (i % u); - tmp = gen_rtx_CONST_VECTOR (qimode, vec); + rtx_vector_builder byte_indices (qimode, u, 1); + for (i = 0; i < u; ++i) + byte_indices.quick_push (GEN_INT (i)); + tmp = byte_indices.build (); sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp, sel, 0, OPTAB_DIRECT); gcc_assert (sel_qi != NULL); Index: gcc/vec-perm-indices.c =================================================================== --- gcc/vec-perm-indices.c 2017-12-22 13:05:20.155253154 +0000 +++ gcc/vec-perm-indices.c 2017-12-22 13:09:48.535709302 +0000 @@ -29,6 +29,7 @@ Software Foundation; either version 3, o #include "memmodel.h" #include "emit-rtl.h" #include "selftest.h" +#include "rtx-vector-builder.h" /* Switch to a new permutation vector that selects between NINPUTS vector inputs that have NELTS_PER_INPUT elements each. Take the elements of the @@ -223,11 +224,12 @@ vec_perm_indices_to_rtx (machine_mode mo { gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT && GET_MODE_NUNITS (mode) == indices.length ()); - unsigned int nelts = indices.length (); - rtvec v = rtvec_alloc (nelts); - for (unsigned int i = 0; i < nelts; ++i) - RTVEC_ELT (v, i) = gen_int_mode (indices[i], GET_MODE_INNER (mode)); - return gen_rtx_CONST_VECTOR (mode, v); + rtx_vector_builder sel (mode, indices.encoding ().npatterns (), + indices.encoding ().nelts_per_pattern ()); + unsigned int encoded_nelts = sel.encoded_nelts (); + for (unsigned int i = 0; i < encoded_nelts; i++) + sel.quick_push (gen_int_mode (indices[i], GET_MODE_INNER (mode))); + return sel.build (); } #if CHECKING_P