From 63570af0b58a3c354723bc78b75d76dbb0750f47 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 7 Dec 2017 18:42:41 +0000 Subject: [PATCH] Make more use of VECTOR_CST_ENCODED_ELT 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. 2017-12-07 Richard Sandiford 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. From-SVN: r255480 --- gcc/ChangeLog | 20 +++++++++ gcc/fold-const.c | 31 +++++++------ gcc/ipa-icf.c | 15 ++++--- gcc/print-tree.c | 24 ++++------ gcc/tree-loop-distribution.c | 17 +++++--- gcc/tree-ssa-ccp.c | 12 +++-- gcc/tree-vector-builder.c | 18 ++++++++ gcc/tree-vector-builder.h | 2 + gcc/tree.c | 85 +++++++++++++----------------------- gcc/varasm.c | 26 ++++++----- 10 files changed, 137 insertions(+), 113 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7fb0d5656e1..1cee5e82907 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2017-12-07 Richard Sandiford + + * 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. + 2017-12-07 Richard Sandiford * tree.c (build_vector): Delete. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 1b098d9f4c9..0f110765f44 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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_tree arg1, unsigned int flags) 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, struct md5_ctx *ctx, 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; diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index 3f6f432483b..a8d3b800318 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -83,6 +83,7 @@ along with GCC; see the file COPYING3. If not see #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: diff --git a/gcc/print-tree.c b/gcc/print-tree.c index 3a0f85d4038..2139a7278ea 100644 --- a/gcc/print-tree.c +++ b/gcc/print-tree.c @@ -761,24 +761,18 @@ print_node (FILE *file, const char *prefix, tree node, int indent, 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; diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 52db3c94bd9..29825cc3f53 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -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; } diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index ae6006d1163..3acddf91247 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -147,6 +147,7 @@ along with GCC; see the file COPYING3. If not see #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_t old_val, ccp_prop_value_t new_val) 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; } diff --git a/gcc/tree-vector-builder.c b/gcc/tree-vector-builder.c index 954dbcd7215..88b9d1a9480 100644 --- a/gcc/tree-vector-builder.c +++ b/gcc/tree-vector-builder.c @@ -96,6 +96,24 @@ tree_vector_builder::new_binary_operation (tree type, tree t1, tree t2, 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 diff --git a/gcc/tree-vector-builder.h b/gcc/tree-vector-builder.h index 1038be77c15..a7b9bdb577c 100644 --- a/gcc/tree-vector-builder.h +++ b/gcc/tree-vector-builder.h @@ -40,6 +40,8 @@ public: 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; diff --git a/gcc/tree.c b/gcc/tree.c index 13ae1c978e3..053670cb6b9 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -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 &hstate, unsigned int flags) 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) diff --git a/gcc/varasm.c b/gcc/varasm.c index 392ac443f14..3a53fb00e2b 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -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 tree t2) 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; -- 2.30.2