Make more use of VECTOR_CST_ENCODED_ELT
authorRichard Sandiford <richard.sandiford@linaro.org>
Thu, 7 Dec 2017 18:42:41 +0000 (18:42 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 7 Dec 2017 18:42:41 +0000 (18:42 +0000)
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  <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.

From-SVN: r255480

gcc/ChangeLog
gcc/fold-const.c
gcc/ipa-icf.c
gcc/print-tree.c
gcc/tree-loop-distribution.c
gcc/tree-ssa-ccp.c
gcc/tree-vector-builder.c
gcc/tree-vector-builder.h
gcc/tree.c
gcc/varasm.c

index 7fb0d5656e11e4d920688731e441afa6aeee7f71..1cee5e8290700e0d0680882e3cc0f5d9d631caad 100644 (file)
@@ -1,3 +1,23 @@
+2017-12-07  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * 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  <richard.sandiford@linaro.org>
 
        * tree.c (build_vector): Delete.
index 1b098d9f4c91af002aeacd433ad92ffda0afb9ab..0f110765f44ba42754ddca3dbdcaf36f0809182d 100644 (file)
@@ -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;
index 3f6f432483b374404f62c7ce660a489ee7d1719e..a8d3b80031877917e573c46c2d8c0e1b90947d79 100644 (file)
@@ -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:
index 3a0f85d4038759ec797f546922002ce0e5b5ab6d..2139a7278eaadab2986a1b14116422942216a7d8 100644 (file)
@@ -761,24 +761,18 @@ print_node (FILE *file, const char *prefix, tree node, int indent,
 
        case VECTOR_CST:
          {
-           /* Big enough for 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 52db3c94bd9563d89a1ea65e5e621d59065b8f8c..29825cc3f53041f9d3830961c8798a4e31eb24e2 100644 (file)
@@ -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 ae6006d1163dfe034c51406c002446d4189a190c..3acddf9124737c984366180c10a1442df94e43cc 100644 (file)
@@ -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;
     }
index 954dbcd721515ddc459ed931f59db95df1076e9d..88b9d1a94808b904b50af9533d2df7a7660f5b8e 100644 (file)
@@ -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
index 1038be77c151392a9d3dd6292502ed2d680976e4..a7b9bdb577cac30f4fd12abbfa6dd40532b160b5 100644 (file)
@@ -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;
index 13ae1c978e38b48c51daa4e3ac4f83d467e62416..053670cb6b979fd26f913abcc84f6b6a2c310976 100644 (file)
@@ -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)
index 392ac443f14fadfd4107c8ff665a711fe73baea4..3a53fb00e2b5e8aaf84fcdf4890432f1cb68eebb 100644 (file)
@@ -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;