Message ID | 87mv2v98qj.fsf_-_@linaro.org |
---|---|
State | New |
Headers | show |
Series | Make more use of VECTOR_CST_ENCODED_ELT | expand |
On Wed, Dec 6, 2017 at 4:28 PM, Richard Sandiford <richard.sandiford@linaro.org> wrote: > This patch makes various bits of code operate directly on the new > VECTOR_CST encoding, instead of using VECTOR_CST_ELT on all elements > of the vector. > > Previous patches handled operations that produce a new VECTOR_CST, > while this patch handles things like predicates. It also makes > print_node dump the encoding instead of the full vector that > the encoding represents. > > Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu. > Also spot-checked on sparc64-linux-gnu. OK to install? Ok. Richard. > Thanks, > Richard > > > 2017-12-06 Richard Sandiford <richard.sandiford@linaro.org> > > gcc/ > * tree-vector-builder.h > (tree_vector_builder::binary_encoded_nelts): Declare. > * tree-vector-builder.c > (tree_vector_builder::binary_encoded_nelts): New function. > * fold-const.c (negate_expr_p): Likewise. > (operand_equal_p, fold_checksum_tree): Likewise. > * tree-loop-distribution.c (const_with_all_bytes_same): Likewise. > * tree.c (integer_zerop, integer_onep, integer_all_onesp, real_zerop) > (real_onep, real_minus_onep, add_expr, initializer_zerop): Likewise. > (uniform_vector_p): Likewise. > * varasm.c (const_hash_1, compare_constant): Likewise. > * tree-ssa-ccp.c: Include tree-vector-builder.h. > (valid_lattice_transition): Operate directly on the VECTOR_CST > encoding. > * ipa-icf.c: Include tree-vector-builder.h. > (sem_variable::equals): Operate directly on the VECTOR_CST encoding. > * print-tree.c (print_node): Print encoding of VECTOR_CSTs. > > Index: gcc/tree-vector-builder.h > =================================================================== > --- gcc/tree-vector-builder.h 2017-12-06 14:49:04.289693414 +0000 > +++ gcc/tree-vector-builder.h 2017-12-06 14:50:45.559564436 +0000 > @@ -40,6 +40,8 @@ #define GCC_TREE_VECTOR_BUILDER_H > bool new_unary_operation (tree, tree, bool); > bool new_binary_operation (tree, tree, tree, bool); > > + static unsigned int binary_encoded_nelts (tree, tree); > + > private: > bool equal_p (const_tree, const_tree) const; > bool allow_steps_p () const; > Index: gcc/tree-vector-builder.c > =================================================================== > --- gcc/tree-vector-builder.c 2017-12-06 14:49:04.289693414 +0000 > +++ gcc/tree-vector-builder.c 2017-12-06 14:50:45.558564477 +0000 > @@ -96,6 +96,24 @@ tree_vector_builder::new_binary_operatio > return true; > } > > +/* Return the number of elements that the caller needs to operate on in > + order to handle a binary operation on VECTOR_CSTs T1 and T2. This static > + function is used instead of new_binary_operation if the result of the > + operation is not a VECTOR_CST. */ > + > +unsigned int > +tree_vector_builder::binary_encoded_nelts (tree t1, tree t2) > +{ > + unsigned int nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (t1)); > + gcc_assert (nelts == TYPE_VECTOR_SUBPARTS (TREE_TYPE (t2))); > + /* See new_binary_operation for details. */ > + unsigned int npatterns = least_common_multiple (VECTOR_CST_NPATTERNS (t1), > + VECTOR_CST_NPATTERNS (t2)); > + unsigned int nelts_per_pattern = MAX (VECTOR_CST_NELTS_PER_PATTERN (t1), > + VECTOR_CST_NELTS_PER_PATTERN (t2)); > + return MIN (npatterns * nelts_per_pattern, nelts); > +} > + > /* Return a vector element with the value BASE + FACTOR * STEP. */ > > tree > Index: gcc/fold-const.c > =================================================================== > --- gcc/fold-const.c 2017-12-06 14:49:00.386854068 +0000 > +++ gcc/fold-const.c 2017-12-06 14:50:45.557564518 +0000 > @@ -410,10 +410,10 @@ negate_expr_p (tree t) > if (FLOAT_TYPE_P (TREE_TYPE (type)) || TYPE_OVERFLOW_WRAPS (type)) > return true; > > - int count = VECTOR_CST_NELTS (t), i; > - > - for (i = 0; i < count; i++) > - if (!negate_expr_p (VECTOR_CST_ELT (t, i))) > + /* Steps don't prevent negation. */ > + unsigned int count = vector_cst_encoded_nelts (t); > + for (unsigned int i = 0; i < count; ++i) > + if (!negate_expr_p (VECTOR_CST_ENCODED_ELT (t, i))) > return false; > > return true; > @@ -2981,17 +2981,19 @@ operand_equal_p (const_tree arg0, const_ > > case VECTOR_CST: > { > - unsigned i; > + if (VECTOR_CST_LOG2_NPATTERNS (arg0) > + != VECTOR_CST_LOG2_NPATTERNS (arg1)) > + return 0; > > - if (VECTOR_CST_NELTS (arg0) != VECTOR_CST_NELTS (arg1)) > + if (VECTOR_CST_NELTS_PER_PATTERN (arg0) > + != VECTOR_CST_NELTS_PER_PATTERN (arg1)) > return 0; > > - for (i = 0; i < VECTOR_CST_NELTS (arg0); ++i) > - { > - if (!operand_equal_p (VECTOR_CST_ELT (arg0, i), > - VECTOR_CST_ELT (arg1, i), flags)) > - return 0; > - } > + unsigned int count = vector_cst_encoded_nelts (arg0); > + for (unsigned int i = 0; i < count; ++i) > + if (!operand_equal_p (VECTOR_CST_ENCODED_ELT (arg0, i), > + VECTOR_CST_ENCODED_ELT (arg1, i), flags)) > + return 0; > return 1; > } > > @@ -11992,8 +11994,9 @@ fold_checksum_tree (const_tree expr, str > fold_checksum_tree (TREE_IMAGPART (expr), ctx, ht); > break; > case VECTOR_CST: > - for (i = 0; i < (int) VECTOR_CST_NELTS (expr); ++i) > - fold_checksum_tree (VECTOR_CST_ELT (expr, i), ctx, ht); > + len = vector_cst_encoded_nelts (expr); > + for (i = 0; i < len; ++i) > + fold_checksum_tree (VECTOR_CST_ENCODED_ELT (expr, i), ctx, ht); > break; > default: > break; > Index: gcc/tree-loop-distribution.c > =================================================================== > --- gcc/tree-loop-distribution.c 2017-11-29 11:06:34.810688336 +0000 > +++ gcc/tree-loop-distribution.c 2017-12-06 14:50:45.558564477 +0000 > @@ -944,13 +944,16 @@ const_with_all_bytes_same (tree val) > return 0; > break; > case VECTOR_CST: > - unsigned int j; > - for (j = 0; j < VECTOR_CST_NELTS (val); ++j) > - if (const_with_all_bytes_same (VECTOR_CST_ELT (val, j))) > - break; > - if (j == VECTOR_CST_NELTS (val)) > - return 0; > - break; > + { > + unsigned int count = vector_cst_encoded_nelts (val); > + unsigned int j; > + for (j = 0; j < count; ++j) > + if (const_with_all_bytes_same (VECTOR_CST_ENCODED_ELT (val, j))) > + break; > + if (j == count) > + return 0; > + break; > + } > default: > break; > } > Index: gcc/tree.c > =================================================================== > --- gcc/tree.c 2017-12-06 14:49:10.295445836 +0000 > +++ gcc/tree.c 2017-12-06 14:50:45.560564396 +0000 > @@ -2338,13 +2338,9 @@ integer_zerop (const_tree expr) > return (integer_zerop (TREE_REALPART (expr)) > && integer_zerop (TREE_IMAGPART (expr))); > case VECTOR_CST: > - { > - unsigned i; > - for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) > - if (!integer_zerop (VECTOR_CST_ELT (expr, i))) > - return false; > - return true; > - } > + return (VECTOR_CST_NPATTERNS (expr) == 1 > + && VECTOR_CST_DUPLICATE_P (expr) > + && integer_zerop (VECTOR_CST_ENCODED_ELT (expr, 0))); > default: > return false; > } > @@ -2364,13 +2360,9 @@ integer_onep (const_tree expr) > return (integer_onep (TREE_REALPART (expr)) > && integer_zerop (TREE_IMAGPART (expr))); > case VECTOR_CST: > - { > - unsigned i; > - for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) > - if (!integer_onep (VECTOR_CST_ELT (expr, i))) > - return false; > - return true; > - } > + return (VECTOR_CST_NPATTERNS (expr) == 1 > + && VECTOR_CST_DUPLICATE_P (expr) > + && integer_onep (VECTOR_CST_ENCODED_ELT (expr, 0))); > default: > return false; > } > @@ -2401,13 +2393,9 @@ integer_all_onesp (const_tree expr) > return 1; > > else if (TREE_CODE (expr) == VECTOR_CST) > - { > - unsigned i; > - for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) > - if (!integer_all_onesp (VECTOR_CST_ELT (expr, i))) > - return 0; > - return 1; > - } > + return (VECTOR_CST_NPATTERNS (expr) == 1 > + && VECTOR_CST_DUPLICATE_P (expr) > + && integer_all_onesp (VECTOR_CST_ENCODED_ELT (expr, 0))); > > else if (TREE_CODE (expr) != INTEGER_CST) > return 0; > @@ -2630,9 +2618,11 @@ real_zerop (const_tree expr) > && real_zerop (TREE_IMAGPART (expr)); > case VECTOR_CST: > { > - unsigned i; > - for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) > - if (!real_zerop (VECTOR_CST_ELT (expr, i))) > + /* Don't simply check for a duplicate because the predicate > + accepts both +0.0 and -0.0. */ > + unsigned count = vector_cst_encoded_nelts (expr); > + for (unsigned int i = 0; i < count; ++i) > + if (!real_zerop (VECTOR_CST_ENCODED_ELT (expr, i))) > return false; > return true; > } > @@ -2657,13 +2647,9 @@ real_onep (const_tree expr) > return real_onep (TREE_REALPART (expr)) > && real_zerop (TREE_IMAGPART (expr)); > case VECTOR_CST: > - { > - unsigned i; > - for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) > - if (!real_onep (VECTOR_CST_ELT (expr, i))) > - return false; > - return true; > - } > + return (VECTOR_CST_NPATTERNS (expr) == 1 > + && VECTOR_CST_DUPLICATE_P (expr) > + && real_onep (VECTOR_CST_ENCODED_ELT (expr, 0))); > default: > return false; > } > @@ -2684,13 +2670,9 @@ real_minus_onep (const_tree expr) > return real_minus_onep (TREE_REALPART (expr)) > && real_zerop (TREE_IMAGPART (expr)); > case VECTOR_CST: > - { > - unsigned i; > - for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) > - if (!real_minus_onep (VECTOR_CST_ELT (expr, i))) > - return false; > - return true; > - } > + return (VECTOR_CST_NPATTERNS (expr) == 1 > + && VECTOR_CST_DUPLICATE_P (expr) > + && real_minus_onep (VECTOR_CST_ENCODED_ELT (expr, 0))); > default: > return false; > } > @@ -7102,9 +7084,11 @@ add_expr (const_tree t, inchash::hash &h > return; > case VECTOR_CST: > { > - unsigned i; > - for (i = 0; i < VECTOR_CST_NELTS (t); ++i) > - inchash::add_expr (VECTOR_CST_ELT (t, i), hstate, flags); > + hstate.add_int (VECTOR_CST_NPATTERNS (t)); > + hstate.add_int (VECTOR_CST_NELTS_PER_PATTERN (t)); > + unsigned int count = vector_cst_encoded_nelts (t); > + for (unsigned int i = 0; i < count; ++i) > + inchash::add_expr (VECTOR_CST_ENCODED_ELT (t, i), hstate, flags); > return; > } > case SSA_NAME: > @@ -10431,13 +10415,9 @@ initializer_zerop (const_tree init) > && ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (TREE_IMAGPART (init)))); > > case VECTOR_CST: > - { > - unsigned i; > - for (i = 0; i < VECTOR_CST_NELTS (init); ++i) > - if (!initializer_zerop (VECTOR_CST_ELT (init, i))) > - return false; > - return true; > - } > + return (VECTOR_CST_NPATTERNS (init) == 1 > + && VECTOR_CST_DUPLICATE_P (init) > + && initializer_zerop (VECTOR_CST_ENCODED_ELT (init, 0))); > > case CONSTRUCTOR: > { > @@ -10486,12 +10466,9 @@ uniform_vector_p (const_tree vec) > > if (TREE_CODE (vec) == VECTOR_CST) > { > - 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; > + if (VECTOR_CST_NPATTERNS (vec) == 1 && VECTOR_CST_DUPLICATE_P (vec)) > + return VECTOR_CST_ENCODED_ELT (vec, 0); > + return NULL_TREE; > } > > else if (TREE_CODE (vec) == CONSTRUCTOR) > Index: gcc/varasm.c > =================================================================== > --- gcc/varasm.c 2017-12-05 14:24:56.163946903 +0000 > +++ gcc/varasm.c 2017-12-06 14:50:45.560564396 +0000 > @@ -3007,13 +3007,11 @@ const_hash_1 (const tree exp) > > case VECTOR_CST: > { > - unsigned i; > - > - hi = 7 + VECTOR_CST_NELTS (exp); > - > - for (i = 0; i < VECTOR_CST_NELTS (exp); ++i) > - hi = hi * 563 + const_hash_1 (VECTOR_CST_ELT (exp, i)); > - > + hi = 7 + VECTOR_CST_NPATTERNS (exp); > + hi = hi * 563 + VECTOR_CST_NELTS_PER_PATTERN (exp); > + unsigned int count = vector_cst_encoded_nelts (exp); > + for (unsigned int i = 0; i < count; ++i) > + hi = hi * 563 + const_hash_1 (VECTOR_CST_ENCODED_ELT (exp, i)); > return hi; > } > > @@ -3151,14 +3149,18 @@ compare_constant (const tree t1, const t > > case VECTOR_CST: > { > - unsigned i; > + if (VECTOR_CST_NPATTERNS (t1) > + != VECTOR_CST_NPATTERNS (t2)) > + return 0; > > - if (VECTOR_CST_NELTS (t1) != VECTOR_CST_NELTS (t2)) > + if (VECTOR_CST_NELTS_PER_PATTERN (t1) > + != VECTOR_CST_NELTS_PER_PATTERN (t2)) > return 0; > > - for (i = 0; i < VECTOR_CST_NELTS (t1); ++i) > - if (!compare_constant (VECTOR_CST_ELT (t1, i), > - VECTOR_CST_ELT (t2, i))) > + unsigned int count = vector_cst_encoded_nelts (t1); > + for (unsigned int i = 0; i < count; ++i) > + if (!compare_constant (VECTOR_CST_ENCODED_ELT (t1, i), > + VECTOR_CST_ENCODED_ELT (t2, i))) > return 0; > > return 1; > Index: gcc/tree-ssa-ccp.c > =================================================================== > --- gcc/tree-ssa-ccp.c 2017-12-05 14:24:55.073967105 +0000 > +++ gcc/tree-ssa-ccp.c 2017-12-06 14:50:45.558564477 +0000 > @@ -147,6 +147,7 @@ Free Software Foundation; either version > #include "diagnostic-core.h" > #include "stringpool.h" > #include "attribs.h" > +#include "tree-vector-builder.h" > > /* Possible lattice values. */ > typedef enum > @@ -465,11 +466,14 @@ valid_lattice_transition (ccp_prop_value > else if (VECTOR_FLOAT_TYPE_P (type) > && !HONOR_NANS (type)) > { > - for (unsigned i = 0; i < VECTOR_CST_NELTS (old_val.value); ++i) > + unsigned int count > + = tree_vector_builder::binary_encoded_nelts (old_val.value, > + new_val.value); > + for (unsigned int i = 0; i < count; ++i) > if (!REAL_VALUE_ISNAN > - (TREE_REAL_CST (VECTOR_CST_ELT (old_val.value, i))) > - && !operand_equal_p (VECTOR_CST_ELT (old_val.value, i), > - VECTOR_CST_ELT (new_val.value, i), 0)) > + (TREE_REAL_CST (VECTOR_CST_ENCODED_ELT (old_val.value, i))) > + && !operand_equal_p (VECTOR_CST_ENCODED_ELT (old_val.value, i), > + VECTOR_CST_ENCODED_ELT (new_val.value, i), 0)) > return false; > return true; > } > Index: gcc/ipa-icf.c > =================================================================== > --- gcc/ipa-icf.c 2017-11-29 11:06:34.810688336 +0000 > +++ gcc/ipa-icf.c 2017-12-06 14:50:45.557564518 +0000 > @@ -83,6 +83,7 @@ #define INCLUDE_LIST > #include "ipa-icf.h" > #include "stor-layout.h" > #include "dbgcnt.h" > +#include "tree-vector-builder.h" > > using namespace ipa_icf_gimple; > > @@ -2024,17 +2025,17 @@ sem_variable::equals (tree t1, tree t2) > &TREE_REAL_CST (t2))); > case VECTOR_CST: > { > - unsigned i; > - > if (VECTOR_CST_NELTS (t1) != VECTOR_CST_NELTS (t2)) > return return_false_with_msg ("VECTOR_CST nelts mismatch"); > > - for (i = 0; i < VECTOR_CST_NELTS (t1); ++i) > - if (!sem_variable::equals (VECTOR_CST_ELT (t1, i), > - VECTOR_CST_ELT (t2, i))) > - return 0; > + unsigned int count > + = tree_vector_builder::binary_encoded_nelts (t1, t2); > + for (unsigned int i = 0; i < count; ++i) > + if (!sem_variable::equals (VECTOR_CST_ENCODED_ELT (t1, i), > + VECTOR_CST_ENCODED_ELT (t2, i))) > + return false; > > - return 1; > + return true; > } > case ARRAY_REF: > case ARRAY_RANGE_REF: > Index: gcc/print-tree.c > =================================================================== > --- gcc/print-tree.c 2017-11-29 11:06:34.810688336 +0000 > +++ gcc/print-tree.c 2017-12-06 14:50:45.558564477 +0000 > @@ -761,24 +761,18 @@ print_node (FILE *file, const char *pref > > case VECTOR_CST: > { > - /* Big enough for 2 UINT_MAX plus the string below. */ > + /* Big enough for UINT_MAX plus the string below. */ > char buf[32]; > - unsigned i; > > - for (i = 0; i < VECTOR_CST_NELTS (node); ++i) > + fprintf (file, " npatterns:%u nelts-per-pattern:%u", > + VECTOR_CST_NPATTERNS (node), > + VECTOR_CST_NELTS_PER_PATTERN (node)); > + unsigned int count = vector_cst_encoded_nelts (node); > + for (unsigned int i = 0; i < count; ++i) > { > - unsigned j; > - /* Coalesce the output of identical consecutive elements. */ > - for (j = i + 1; j < VECTOR_CST_NELTS (node); j++) > - if (VECTOR_CST_ELT (node, j) != VECTOR_CST_ELT (node, i)) > - break; > - j--; > - if (i == j) > - sprintf (buf, "elt:%u: ", i); > - else > - sprintf (buf, "elt:%u...%u: ", i, j); > - print_node (file, buf, VECTOR_CST_ELT (node, i), indent + 4); > - i = j; > + sprintf (buf, "elt:%u: ", i); > + print_node (file, buf, VECTOR_CST_ENCODED_ELT (node, i), > + indent + 4); > } > } > break;
Index: gcc/tree-vector-builder.h =================================================================== --- gcc/tree-vector-builder.h 2017-12-06 14:49:04.289693414 +0000 +++ gcc/tree-vector-builder.h 2017-12-06 14:50:45.559564436 +0000 @@ -40,6 +40,8 @@ #define GCC_TREE_VECTOR_BUILDER_H bool new_unary_operation (tree, tree, bool); bool new_binary_operation (tree, tree, tree, bool); + static unsigned int binary_encoded_nelts (tree, tree); + private: bool equal_p (const_tree, const_tree) const; bool allow_steps_p () const; Index: gcc/tree-vector-builder.c =================================================================== --- gcc/tree-vector-builder.c 2017-12-06 14:49:04.289693414 +0000 +++ gcc/tree-vector-builder.c 2017-12-06 14:50:45.558564477 +0000 @@ -96,6 +96,24 @@ tree_vector_builder::new_binary_operatio return true; } +/* Return the number of elements that the caller needs to operate on in + order to handle a binary operation on VECTOR_CSTs T1 and T2. This static + function is used instead of new_binary_operation if the result of the + operation is not a VECTOR_CST. */ + +unsigned int +tree_vector_builder::binary_encoded_nelts (tree t1, tree t2) +{ + unsigned int nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (t1)); + gcc_assert (nelts == TYPE_VECTOR_SUBPARTS (TREE_TYPE (t2))); + /* See new_binary_operation for details. */ + unsigned int npatterns = least_common_multiple (VECTOR_CST_NPATTERNS (t1), + VECTOR_CST_NPATTERNS (t2)); + unsigned int nelts_per_pattern = MAX (VECTOR_CST_NELTS_PER_PATTERN (t1), + VECTOR_CST_NELTS_PER_PATTERN (t2)); + return MIN (npatterns * nelts_per_pattern, nelts); +} + /* Return a vector element with the value BASE + FACTOR * STEP. */ tree Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c 2017-12-06 14:49:00.386854068 +0000 +++ gcc/fold-const.c 2017-12-06 14:50:45.557564518 +0000 @@ -410,10 +410,10 @@ negate_expr_p (tree t) if (FLOAT_TYPE_P (TREE_TYPE (type)) || TYPE_OVERFLOW_WRAPS (type)) return true; - int count = VECTOR_CST_NELTS (t), i; - - for (i = 0; i < count; i++) - if (!negate_expr_p (VECTOR_CST_ELT (t, i))) + /* Steps don't prevent negation. */ + unsigned int count = vector_cst_encoded_nelts (t); + for (unsigned int i = 0; i < count; ++i) + if (!negate_expr_p (VECTOR_CST_ENCODED_ELT (t, i))) return false; return true; @@ -2981,17 +2981,19 @@ operand_equal_p (const_tree arg0, const_ case VECTOR_CST: { - unsigned i; + if (VECTOR_CST_LOG2_NPATTERNS (arg0) + != VECTOR_CST_LOG2_NPATTERNS (arg1)) + return 0; - if (VECTOR_CST_NELTS (arg0) != VECTOR_CST_NELTS (arg1)) + if (VECTOR_CST_NELTS_PER_PATTERN (arg0) + != VECTOR_CST_NELTS_PER_PATTERN (arg1)) return 0; - for (i = 0; i < VECTOR_CST_NELTS (arg0); ++i) - { - if (!operand_equal_p (VECTOR_CST_ELT (arg0, i), - VECTOR_CST_ELT (arg1, i), flags)) - return 0; - } + unsigned int count = vector_cst_encoded_nelts (arg0); + for (unsigned int i = 0; i < count; ++i) + if (!operand_equal_p (VECTOR_CST_ENCODED_ELT (arg0, i), + VECTOR_CST_ENCODED_ELT (arg1, i), flags)) + return 0; return 1; } @@ -11992,8 +11994,9 @@ fold_checksum_tree (const_tree expr, str fold_checksum_tree (TREE_IMAGPART (expr), ctx, ht); break; case VECTOR_CST: - for (i = 0; i < (int) VECTOR_CST_NELTS (expr); ++i) - fold_checksum_tree (VECTOR_CST_ELT (expr, i), ctx, ht); + len = vector_cst_encoded_nelts (expr); + for (i = 0; i < len; ++i) + fold_checksum_tree (VECTOR_CST_ENCODED_ELT (expr, i), ctx, ht); break; default: break; Index: gcc/tree-loop-distribution.c =================================================================== --- gcc/tree-loop-distribution.c 2017-11-29 11:06:34.810688336 +0000 +++ gcc/tree-loop-distribution.c 2017-12-06 14:50:45.558564477 +0000 @@ -944,13 +944,16 @@ const_with_all_bytes_same (tree val) return 0; break; case VECTOR_CST: - unsigned int j; - for (j = 0; j < VECTOR_CST_NELTS (val); ++j) - if (const_with_all_bytes_same (VECTOR_CST_ELT (val, j))) - break; - if (j == VECTOR_CST_NELTS (val)) - return 0; - break; + { + unsigned int count = vector_cst_encoded_nelts (val); + unsigned int j; + for (j = 0; j < count; ++j) + if (const_with_all_bytes_same (VECTOR_CST_ENCODED_ELT (val, j))) + break; + if (j == count) + return 0; + break; + } default: break; } Index: gcc/tree.c =================================================================== --- gcc/tree.c 2017-12-06 14:49:10.295445836 +0000 +++ gcc/tree.c 2017-12-06 14:50:45.560564396 +0000 @@ -2338,13 +2338,9 @@ integer_zerop (const_tree expr) return (integer_zerop (TREE_REALPART (expr)) && integer_zerop (TREE_IMAGPART (expr))); case VECTOR_CST: - { - unsigned i; - for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) - if (!integer_zerop (VECTOR_CST_ELT (expr, i))) - return false; - return true; - } + return (VECTOR_CST_NPATTERNS (expr) == 1 + && VECTOR_CST_DUPLICATE_P (expr) + && integer_zerop (VECTOR_CST_ENCODED_ELT (expr, 0))); default: return false; } @@ -2364,13 +2360,9 @@ integer_onep (const_tree expr) return (integer_onep (TREE_REALPART (expr)) && integer_zerop (TREE_IMAGPART (expr))); case VECTOR_CST: - { - unsigned i; - for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) - if (!integer_onep (VECTOR_CST_ELT (expr, i))) - return false; - return true; - } + return (VECTOR_CST_NPATTERNS (expr) == 1 + && VECTOR_CST_DUPLICATE_P (expr) + && integer_onep (VECTOR_CST_ENCODED_ELT (expr, 0))); default: return false; } @@ -2401,13 +2393,9 @@ integer_all_onesp (const_tree expr) return 1; else if (TREE_CODE (expr) == VECTOR_CST) - { - unsigned i; - for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) - if (!integer_all_onesp (VECTOR_CST_ELT (expr, i))) - return 0; - return 1; - } + return (VECTOR_CST_NPATTERNS (expr) == 1 + && VECTOR_CST_DUPLICATE_P (expr) + && integer_all_onesp (VECTOR_CST_ENCODED_ELT (expr, 0))); else if (TREE_CODE (expr) != INTEGER_CST) return 0; @@ -2630,9 +2618,11 @@ real_zerop (const_tree expr) && real_zerop (TREE_IMAGPART (expr)); case VECTOR_CST: { - unsigned i; - for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) - if (!real_zerop (VECTOR_CST_ELT (expr, i))) + /* Don't simply check for a duplicate because the predicate + accepts both +0.0 and -0.0. */ + unsigned count = vector_cst_encoded_nelts (expr); + for (unsigned int i = 0; i < count; ++i) + if (!real_zerop (VECTOR_CST_ENCODED_ELT (expr, i))) return false; return true; } @@ -2657,13 +2647,9 @@ real_onep (const_tree expr) return real_onep (TREE_REALPART (expr)) && real_zerop (TREE_IMAGPART (expr)); case VECTOR_CST: - { - unsigned i; - for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) - if (!real_onep (VECTOR_CST_ELT (expr, i))) - return false; - return true; - } + return (VECTOR_CST_NPATTERNS (expr) == 1 + && VECTOR_CST_DUPLICATE_P (expr) + && real_onep (VECTOR_CST_ENCODED_ELT (expr, 0))); default: return false; } @@ -2684,13 +2670,9 @@ real_minus_onep (const_tree expr) return real_minus_onep (TREE_REALPART (expr)) && real_zerop (TREE_IMAGPART (expr)); case VECTOR_CST: - { - unsigned i; - for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) - if (!real_minus_onep (VECTOR_CST_ELT (expr, i))) - return false; - return true; - } + return (VECTOR_CST_NPATTERNS (expr) == 1 + && VECTOR_CST_DUPLICATE_P (expr) + && real_minus_onep (VECTOR_CST_ENCODED_ELT (expr, 0))); default: return false; } @@ -7102,9 +7084,11 @@ add_expr (const_tree t, inchash::hash &h return; case VECTOR_CST: { - unsigned i; - for (i = 0; i < VECTOR_CST_NELTS (t); ++i) - inchash::add_expr (VECTOR_CST_ELT (t, i), hstate, flags); + hstate.add_int (VECTOR_CST_NPATTERNS (t)); + hstate.add_int (VECTOR_CST_NELTS_PER_PATTERN (t)); + unsigned int count = vector_cst_encoded_nelts (t); + for (unsigned int i = 0; i < count; ++i) + inchash::add_expr (VECTOR_CST_ENCODED_ELT (t, i), hstate, flags); return; } case SSA_NAME: @@ -10431,13 +10415,9 @@ initializer_zerop (const_tree init) && ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (TREE_IMAGPART (init)))); case VECTOR_CST: - { - unsigned i; - for (i = 0; i < VECTOR_CST_NELTS (init); ++i) - if (!initializer_zerop (VECTOR_CST_ELT (init, i))) - return false; - return true; - } + return (VECTOR_CST_NPATTERNS (init) == 1 + && VECTOR_CST_DUPLICATE_P (init) + && initializer_zerop (VECTOR_CST_ENCODED_ELT (init, 0))); case CONSTRUCTOR: { @@ -10486,12 +10466,9 @@ uniform_vector_p (const_tree vec) if (TREE_CODE (vec) == VECTOR_CST) { - 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; + if (VECTOR_CST_NPATTERNS (vec) == 1 && VECTOR_CST_DUPLICATE_P (vec)) + return VECTOR_CST_ENCODED_ELT (vec, 0); + return NULL_TREE; } else if (TREE_CODE (vec) == CONSTRUCTOR) Index: gcc/varasm.c =================================================================== --- gcc/varasm.c 2017-12-05 14:24:56.163946903 +0000 +++ gcc/varasm.c 2017-12-06 14:50:45.560564396 +0000 @@ -3007,13 +3007,11 @@ const_hash_1 (const tree exp) case VECTOR_CST: { - unsigned i; - - hi = 7 + VECTOR_CST_NELTS (exp); - - for (i = 0; i < VECTOR_CST_NELTS (exp); ++i) - hi = hi * 563 + const_hash_1 (VECTOR_CST_ELT (exp, i)); - + hi = 7 + VECTOR_CST_NPATTERNS (exp); + hi = hi * 563 + VECTOR_CST_NELTS_PER_PATTERN (exp); + unsigned int count = vector_cst_encoded_nelts (exp); + for (unsigned int i = 0; i < count; ++i) + hi = hi * 563 + const_hash_1 (VECTOR_CST_ENCODED_ELT (exp, i)); return hi; } @@ -3151,14 +3149,18 @@ compare_constant (const tree t1, const t case VECTOR_CST: { - unsigned i; + if (VECTOR_CST_NPATTERNS (t1) + != VECTOR_CST_NPATTERNS (t2)) + return 0; - if (VECTOR_CST_NELTS (t1) != VECTOR_CST_NELTS (t2)) + if (VECTOR_CST_NELTS_PER_PATTERN (t1) + != VECTOR_CST_NELTS_PER_PATTERN (t2)) return 0; - for (i = 0; i < VECTOR_CST_NELTS (t1); ++i) - if (!compare_constant (VECTOR_CST_ELT (t1, i), - VECTOR_CST_ELT (t2, i))) + unsigned int count = vector_cst_encoded_nelts (t1); + for (unsigned int i = 0; i < count; ++i) + if (!compare_constant (VECTOR_CST_ENCODED_ELT (t1, i), + VECTOR_CST_ENCODED_ELT (t2, i))) return 0; return 1; Index: gcc/tree-ssa-ccp.c =================================================================== --- gcc/tree-ssa-ccp.c 2017-12-05 14:24:55.073967105 +0000 +++ gcc/tree-ssa-ccp.c 2017-12-06 14:50:45.558564477 +0000 @@ -147,6 +147,7 @@ Free Software Foundation; either version #include "diagnostic-core.h" #include "stringpool.h" #include "attribs.h" +#include "tree-vector-builder.h" /* Possible lattice values. */ typedef enum @@ -465,11 +466,14 @@ valid_lattice_transition (ccp_prop_value else if (VECTOR_FLOAT_TYPE_P (type) && !HONOR_NANS (type)) { - for (unsigned i = 0; i < VECTOR_CST_NELTS (old_val.value); ++i) + unsigned int count + = tree_vector_builder::binary_encoded_nelts (old_val.value, + new_val.value); + for (unsigned int i = 0; i < count; ++i) if (!REAL_VALUE_ISNAN - (TREE_REAL_CST (VECTOR_CST_ELT (old_val.value, i))) - && !operand_equal_p (VECTOR_CST_ELT (old_val.value, i), - VECTOR_CST_ELT (new_val.value, i), 0)) + (TREE_REAL_CST (VECTOR_CST_ENCODED_ELT (old_val.value, i))) + && !operand_equal_p (VECTOR_CST_ENCODED_ELT (old_val.value, i), + VECTOR_CST_ENCODED_ELT (new_val.value, i), 0)) return false; return true; } Index: gcc/ipa-icf.c =================================================================== --- gcc/ipa-icf.c 2017-11-29 11:06:34.810688336 +0000 +++ gcc/ipa-icf.c 2017-12-06 14:50:45.557564518 +0000 @@ -83,6 +83,7 @@ #define INCLUDE_LIST #include "ipa-icf.h" #include "stor-layout.h" #include "dbgcnt.h" +#include "tree-vector-builder.h" using namespace ipa_icf_gimple; @@ -2024,17 +2025,17 @@ sem_variable::equals (tree t1, tree t2) &TREE_REAL_CST (t2))); case VECTOR_CST: { - unsigned i; - if (VECTOR_CST_NELTS (t1) != VECTOR_CST_NELTS (t2)) return return_false_with_msg ("VECTOR_CST nelts mismatch"); - for (i = 0; i < VECTOR_CST_NELTS (t1); ++i) - if (!sem_variable::equals (VECTOR_CST_ELT (t1, i), - VECTOR_CST_ELT (t2, i))) - return 0; + unsigned int count + = tree_vector_builder::binary_encoded_nelts (t1, t2); + for (unsigned int i = 0; i < count; ++i) + if (!sem_variable::equals (VECTOR_CST_ENCODED_ELT (t1, i), + VECTOR_CST_ENCODED_ELT (t2, i))) + return false; - return 1; + return true; } case ARRAY_REF: case ARRAY_RANGE_REF: Index: gcc/print-tree.c =================================================================== --- gcc/print-tree.c 2017-11-29 11:06:34.810688336 +0000 +++ gcc/print-tree.c 2017-12-06 14:50:45.558564477 +0000 @@ -761,24 +761,18 @@ print_node (FILE *file, const char *pref case VECTOR_CST: { - /* Big enough for 2 UINT_MAX plus the string below. */ + /* Big enough for UINT_MAX plus the string below. */ char buf[32]; - unsigned i; - for (i = 0; i < VECTOR_CST_NELTS (node); ++i) + fprintf (file, " npatterns:%u nelts-per-pattern:%u", + VECTOR_CST_NPATTERNS (node), + VECTOR_CST_NELTS_PER_PATTERN (node)); + unsigned int count = vector_cst_encoded_nelts (node); + for (unsigned int i = 0; i < count; ++i) { - unsigned j; - /* Coalesce the output of identical consecutive elements. */ - for (j = i + 1; j < VECTOR_CST_NELTS (node); j++) - if (VECTOR_CST_ELT (node, j) != VECTOR_CST_ELT (node, i)) - break; - j--; - if (i == j) - sprintf (buf, "elt:%u: ", i); - else - sprintf (buf, "elt:%u...%u: ", i, j); - print_node (file, buf, VECTOR_CST_ELT (node, i), indent + 4); - i = j; + sprintf (buf, "elt:%u: ", i); + print_node (file, buf, VECTOR_CST_ENCODED_ELT (node, i), + indent + 4); } } break;