Store VECTOR_CST_NELTS directly in tree_node
authorRichard Sandiford <richard.sandiford@linaro.org>
Thu, 14 Sep 2017 15:25:57 +0000 (15:25 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 14 Sep 2017 15:25:57 +0000 (15:25 +0000)
Previously VECTOR_CST_NELTS (t) read the number of elements from
TYPE_VECTOR_SUBPARTS (TREE_TYPE (t)).  There were two ways of handling
this with variable TYPE_VECTOR_SUBPARTS: either forcibly convert the
number to a constant (which is doable) or store the number directly
in the VECTOR_CST.  The latter seemed better, since it involves less
pointer chasing and since the tree_node u field is otherwise unused
for VECTOR_CST.  It would still be easy to switch to the former in
future if we need to free up the field for someting else.

The patch also changes various bits of VECTOR_CST code to use
VECTOR_CST_NELTS instead of TYPE_VECTOR_SUBPARTS when iterating
over VECTOR_CST_ELTs.  Also, when the two are checked for equality,
the patch prefers to read VECTOR_CST_NELTS (which must be constant)
and check against TYPE_VECTOR_SUBPARTS, instead of the other way
around.

2017-09-14  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* tree-core.h (tree_base::u): Add an "nelts" field.
(tree_vector): Use VECTOR_CST_NELTS as the length.
* tree.c (tree_size): Likewise.
(make_vector): Initialize VECTOR_CST_NELTS.
* tree.h (VECTOR_CST_NELTS): Use the u.nelts field.
* cfgexpand.c (expand_debug_expr): Use VECTOR_CST_NELTS instead of
TYPE_VECTOR_SUBPARTS.
* expr.c (const_vector_mask_from_tree): Consistently use "units"
as the number of units, setting it from VECTOR_CST_NELTS.
(const_vector_from_tree): Likewise.
* fold-const.c (negate_expr_p): Use VECTOR_CST_NELTS instead of
TYPE_VECTOR_SUBPARTS for the number of elements in a VECTOR_CST.
(fold_negate_expr_1): Likewise.
(fold_convert_const): Likewise.
(const_binop): Likewise.  Differentiate the number of output and
input elements.
(const_unop): Likewise.
(fold_ternary_loc): Use VECTOR_CST_NELTS for the number of elements
in a VECTOR_CST, asserting that it is the same as TYPE_VECTOR_SUBPARTS
in cases that did the opposite.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r252758

gcc/ChangeLog
gcc/cfgexpand.c
gcc/expr.c
gcc/fold-const.c
gcc/tree-core.h
gcc/tree.c
gcc/tree.h

index 3925e46594e3a3a264a8011b63d92ce4250badc5..fb9c448efafc541a02fc3c5dc2b06a59d835504a 100644 (file)
@@ -1,3 +1,28 @@
+2017-09-14  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * tree-core.h (tree_base::u): Add an "nelts" field.
+       (tree_vector): Use VECTOR_CST_NELTS as the length.
+       * tree.c (tree_size): Likewise.
+       (make_vector): Initialize VECTOR_CST_NELTS.
+       * tree.h (VECTOR_CST_NELTS): Use the u.nelts field.
+       * cfgexpand.c (expand_debug_expr): Use VECTOR_CST_NELTS instead of
+       TYPE_VECTOR_SUBPARTS.
+       * expr.c (const_vector_mask_from_tree): Consistently use "units"
+       as the number of units, setting it from VECTOR_CST_NELTS.
+       (const_vector_from_tree): Likewise.
+       * fold-const.c (negate_expr_p): Use VECTOR_CST_NELTS instead of
+       TYPE_VECTOR_SUBPARTS for the number of elements in a VECTOR_CST.
+       (fold_negate_expr_1): Likewise.
+       (fold_convert_const): Likewise.
+       (const_binop): Likewise.  Differentiate the number of output and
+       input elements.
+       (const_unop): Likewise.
+       (fold_ternary_loc): Use VECTOR_CST_NELTS for the number of elements
+       in a VECTOR_CST, asserting that it is the same as TYPE_VECTOR_SUBPARTS
+       in cases that did the opposite.
+
 2017-09-14  Richard Biener  <rguenther@suse.de>
 
        * tree-ssa-sccvn.c (visit_phi): Merge undefined values similar
index 7657a65ec895fac492613d838b09545f136123ec..bd3312eb3baa0a218b45852199e2108ab4c4df96 100644 (file)
@@ -4921,12 +4921,12 @@ expand_debug_expr (tree exp)
 
     case VECTOR_CST:
       {
-       unsigned i;
+       unsigned i, nelts;
 
-       op0 = gen_rtx_CONCATN
-         (mode, rtvec_alloc (TYPE_VECTOR_SUBPARTS (TREE_TYPE (exp))));
+       nelts = VECTOR_CST_NELTS (exp);
+       op0 = gen_rtx_CONCATN (mode, rtvec_alloc (nelts));
 
-       for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
+       for (i = 0; i < nelts; ++i)
          {
            op1 = expand_debug_expr (VECTOR_CST_ELT (exp, i));
            if (!op1)
index 989badcac59ed60a98def8b15a26126bb9b04215..a9689a6fd52987705c584029683fe6c47f50a4c3 100644 (file)
@@ -11700,18 +11700,17 @@ static rtx
 const_vector_mask_from_tree (tree exp)
 {
   rtvec v;
-  unsigned i;
-  int units;
+  unsigned i, units;
   tree elt;
   machine_mode inner, mode;
 
   mode = TYPE_MODE (TREE_TYPE (exp));
-  units = GET_MODE_NUNITS (mode);
+  units = VECTOR_CST_NELTS (exp);
   inner = GET_MODE_INNER (mode);
 
   v = rtvec_alloc (units);
 
-  for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
+  for (i = 0; i < units; ++i)
     {
       elt = VECTOR_CST_ELT (exp, i);
 
@@ -11756,8 +11755,7 @@ static rtx
 const_vector_from_tree (tree exp)
 {
   rtvec v;
-  unsigned i;
-  int units;
+  unsigned i, units;
   tree elt;
   machine_mode inner, mode;
 
@@ -11769,12 +11767,12 @@ const_vector_from_tree (tree exp)
   if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
     return const_vector_mask_from_tree (exp);
 
-  units = GET_MODE_NUNITS (mode);
+  units = VECTOR_CST_NELTS (exp);
   inner = GET_MODE_INNER (mode);
 
   v = rtvec_alloc (units);
 
-  for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
+  for (i = 0; i < units; ++i)
     {
       elt = VECTOR_CST_ELT (exp, i);
 
index 16bf45694bfe5e301caa527542d861be49c0647d..66e7cc7b189fa3a3f8865582f232f2258198e2db 100644 (file)
@@ -410,7 +410,7 @@ negate_expr_p (tree t)
        if (FLOAT_TYPE_P (TREE_TYPE (type)) || TYPE_OVERFLOW_WRAPS (type))
          return true;
 
-       int count = TYPE_VECTOR_SUBPARTS (type), i;
+       int count = VECTOR_CST_NELTS (t), i;
 
        for (i = 0; i < count; i++)
          if (!negate_expr_p (VECTOR_CST_ELT (t, i)))
@@ -564,7 +564,7 @@ fold_negate_expr_1 (location_t loc, tree t)
 
     case VECTOR_CST:
       {
-       int count = TYPE_VECTOR_SUBPARTS (type), i;
+       int count = VECTOR_CST_NELTS (t), i;
        tree *elts = XALLOCAVEC (tree, count);
 
        for (i = 0; i < count; i++)
@@ -1413,7 +1413,7 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
       && TREE_CODE (arg2) == VECTOR_CST)
     {
       tree type = TREE_TYPE (arg1);
-      int count = TYPE_VECTOR_SUBPARTS (type), i;
+      int count = VECTOR_CST_NELTS (arg1), i;
       tree *elts = XALLOCAVEC (tree, count);
 
       for (i = 0; i < count; i++)
@@ -1437,7 +1437,7 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
       && TREE_CODE (arg2) == INTEGER_CST)
     {
       tree type = TREE_TYPE (arg1);
-      int count = TYPE_VECTOR_SUBPARTS (type), i;
+      int count = VECTOR_CST_NELTS (arg1), i;
       tree *elts = XALLOCAVEC (tree, count);
 
       for (i = 0; i < count; i++)
@@ -1481,21 +1481,24 @@ const_binop (enum tree_code code, tree type, tree arg1, tree arg2)
     case VEC_PACK_TRUNC_EXPR:
     case VEC_PACK_FIX_TRUNC_EXPR:
       {
-       unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
        tree *elts;
+       unsigned int out_nelts, in_nelts, i;
 
-       gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)) == nelts / 2
-                   && TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg2)) == nelts / 2);
        if (TREE_CODE (arg1) != VECTOR_CST
            || TREE_CODE (arg2) != VECTOR_CST)
          return NULL_TREE;
 
-       elts = XALLOCAVEC (tree, nelts);
+       in_nelts = VECTOR_CST_NELTS (arg1);
+       out_nelts = in_nelts * 2;
+       gcc_assert (in_nelts == VECTOR_CST_NELTS (arg2)
+                   && out_nelts == TYPE_VECTOR_SUBPARTS (type));
+
+       elts = XALLOCAVEC (tree, out_nelts);
        if (!vec_cst_ctor_to_array (arg1, elts)
-           || !vec_cst_ctor_to_array (arg2, elts + nelts / 2))
+           || !vec_cst_ctor_to_array (arg2, elts + in_nelts))
          return NULL_TREE;
 
-       for (i = 0; i < nelts; i++)
+       for (i = 0; i < out_nelts; i++)
          {
            elts[i] = fold_convert_const (code == VEC_PACK_TRUNC_EXPR
                                          ? NOP_EXPR : FIX_TRUNC_EXPR,
@@ -1512,33 +1515,35 @@ const_binop (enum tree_code code, tree type, tree arg1, tree arg2)
     case VEC_WIDEN_MULT_EVEN_EXPR:
     case VEC_WIDEN_MULT_ODD_EXPR:
       {
-       unsigned int nelts = TYPE_VECTOR_SUBPARTS (type);
-       unsigned int out, ofs, scale;
+       unsigned int out_nelts, in_nelts, out, ofs, scale;
        tree *elts;
 
-       gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)) == nelts * 2
-                   && TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg2)) == nelts * 2);
        if (TREE_CODE (arg1) != VECTOR_CST || TREE_CODE (arg2) != VECTOR_CST)
          return NULL_TREE;
 
-       elts = XALLOCAVEC (tree, nelts * 4);
+       in_nelts = VECTOR_CST_NELTS (arg1);
+       out_nelts = in_nelts / 2;
+       gcc_assert (in_nelts == VECTOR_CST_NELTS (arg2)
+                   && out_nelts == TYPE_VECTOR_SUBPARTS (type));
+
+       elts = XALLOCAVEC (tree, in_nelts * 2);
        if (!vec_cst_ctor_to_array (arg1, elts)
-           || !vec_cst_ctor_to_array (arg2, elts + nelts * 2))
+           || !vec_cst_ctor_to_array (arg2, elts + in_nelts))
          return NULL_TREE;
 
        if (code == VEC_WIDEN_MULT_LO_EXPR)
-         scale = 0, ofs = BYTES_BIG_ENDIAN ? nelts : 0;
+         scale = 0, ofs = BYTES_BIG_ENDIAN ? out_nelts : 0;
        else if (code == VEC_WIDEN_MULT_HI_EXPR)
-         scale = 0, ofs = BYTES_BIG_ENDIAN ? 0 : nelts;
+         scale = 0, ofs = BYTES_BIG_ENDIAN ? 0 : out_nelts;
        else if (code == VEC_WIDEN_MULT_EVEN_EXPR)
          scale = 1, ofs = 0;
        else /* if (code == VEC_WIDEN_MULT_ODD_EXPR) */
          scale = 1, ofs = 1;
 
-       for (out = 0; out < nelts; out++)
+       for (out = 0; out < out_nelts; out++)
          {
            unsigned int in1 = (out << scale) + ofs;
-           unsigned int in2 = in1 + nelts * 2;
+           unsigned int in2 = in1 + in_nelts;
            tree t1, t2;
 
            t1 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), elts[in1]);
@@ -1671,28 +1676,31 @@ const_unop (enum tree_code code, tree type, tree arg0)
     case VEC_UNPACK_FLOAT_LO_EXPR:
     case VEC_UNPACK_FLOAT_HI_EXPR:
       {
-       unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
+       unsigned int out_nelts, in_nelts, i;
        tree *elts;
        enum tree_code subcode;
 
-       gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts * 2);
        if (TREE_CODE (arg0) != VECTOR_CST)
          return NULL_TREE;
 
-       elts = XALLOCAVEC (tree, nelts * 2);
+       in_nelts = VECTOR_CST_NELTS (arg0);
+       out_nelts = in_nelts / 2;
+       gcc_assert (out_nelts == TYPE_VECTOR_SUBPARTS (type));
+
+       elts = XALLOCAVEC (tree, in_nelts);
        if (!vec_cst_ctor_to_array (arg0, elts))
          return NULL_TREE;
 
        if ((!BYTES_BIG_ENDIAN) ^ (code == VEC_UNPACK_LO_EXPR
                                   || code == VEC_UNPACK_FLOAT_LO_EXPR))
-         elts += nelts;
+         elts += out_nelts;
 
        if (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_HI_EXPR)
          subcode = NOP_EXPR;
        else
          subcode = FLOAT_EXPR;
 
-       for (i = 0; i < nelts; i++)
+       for (i = 0; i < out_nelts; i++)
          {
            elts[i] = fold_convert_const (subcode, TREE_TYPE (type), elts[i]);
            if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i]))
@@ -1712,7 +1720,7 @@ const_unop (enum tree_code code, tree type, tree arg0)
 
        if (TREE_CODE (arg0) != VECTOR_CST)
          return NULL_TREE;
-        nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
+       nelts = VECTOR_CST_NELTS (arg0);
 
        elts = XALLOCAVEC (tree, nelts);
        if (!vec_cst_ctor_to_array (arg0, elts))
@@ -2153,7 +2161,7 @@ fold_convert_const (enum tree_code code, tree type, tree arg1)
       if (TREE_CODE (arg1) == VECTOR_CST
          && TYPE_VECTOR_SUBPARTS (type) == VECTOR_CST_NELTS (arg1))
        {
-         int len = TYPE_VECTOR_SUBPARTS (type);
+         int len = VECTOR_CST_NELTS (arg1);
          tree elttype = TREE_TYPE (type);
          tree *v = XALLOCAVEC (tree, len);
          for (int i = 0; i < len; ++i)
@@ -11311,9 +11319,9 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
              && (TREE_CODE (arg2) == VECTOR_CST
                  || TREE_CODE (arg2) == CONSTRUCTOR))
            {
-             unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
+             unsigned int nelts = VECTOR_CST_NELTS (arg0), i;
              unsigned char *sel = XALLOCAVEC (unsigned char, nelts);
-             gcc_assert (nelts == VECTOR_CST_NELTS (arg0));
+             gcc_assert (nelts == TYPE_VECTOR_SUBPARTS (type));
              for (i = 0; i < nelts; i++)
                {
                  tree val = VECTOR_CST_ELT (arg0, i);
@@ -11642,7 +11650,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
     case VEC_PERM_EXPR:
       if (TREE_CODE (arg2) == VECTOR_CST)
        {
-         unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i, mask, mask2;
+         unsigned int nelts = VECTOR_CST_NELTS (arg2), i, mask, mask2;
          unsigned char *sel = XALLOCAVEC (unsigned char, 2 * nelts);
          unsigned char *sel2 = sel + nelts;
          bool need_mask_canon = false;
@@ -11655,7 +11663,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
 
          mask2 = 2 * nelts - 1;
          mask = single_arg ? (nelts - 1) : mask2;
-         gcc_assert (nelts == VECTOR_CST_NELTS (arg2));
+         gcc_assert (nelts == TYPE_VECTOR_SUBPARTS (type));
          for (i = 0; i < nelts; i++)
            {
              tree val = VECTOR_CST_ELT (arg2, i);
@@ -11766,9 +11774,9 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
                return arg0;
              else
                {
-                 tree *elts = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type));
-                 memcpy (elts, VECTOR_CST_ELTS (arg0),
-                         sizeof (tree) * TYPE_VECTOR_SUBPARTS (type));
+                 unsigned int nelts = VECTOR_CST_NELTS (arg0);
+                 tree *elts = XALLOCAVEC (tree, nelts);
+                 memcpy (elts, VECTOR_CST_ELTS (arg0), sizeof (tree) * nelts);
                  elts[k] = arg1;
                  return build_vector (type, elts);
                }
index dc358e86e82daf562d2e11964fb94e5662a16947..b34080e25754b4d00d1a4c3f3967d3d0be5e4562 100644 (file)
@@ -975,6 +975,9 @@ struct GTY(()) tree_base {
     /* VEC length.  This field is only used with TREE_VEC.  */
     int length;
 
+    /* Number of elements.  This field is only used with VECTOR_CST.  */
+    unsigned int nelts;
+
     /* SSA version number.  This field is only used with SSA_NAME.  */
     unsigned int version;
 
@@ -1326,7 +1329,7 @@ struct GTY(()) tree_complex {
 
 struct GTY(()) tree_vector {
   struct tree_typed typed;
-  tree GTY ((length ("TYPE_VECTOR_SUBPARTS (TREE_TYPE ((tree)&%h))"))) elts[1];
+  tree GTY ((length ("VECTOR_CST_NELTS ((tree) &%h)"))) elts[1];
 };
 
 struct GTY(()) tree_identifier {
index 721330a4a499e722fd3233988bf54843b0136a6c..0f505c2db01758590a2ad16cbf258f33e7552348 100644 (file)
@@ -873,7 +873,7 @@ tree_size (const_tree node)
 
     case VECTOR_CST:
       return (sizeof (struct tree_vector)
-             + (TYPE_VECTOR_SUBPARTS (TREE_TYPE (node)) - 1) * sizeof (tree));
+             + (VECTOR_CST_NELTS (node) - 1) * sizeof (tree));
 
     case STRING_CST:
       return TREE_STRING_LENGTH (node) + offsetof (struct tree_string, str) + 1;
@@ -1696,6 +1696,7 @@ make_vector (unsigned len MEM_STAT_DECL)
 
   TREE_SET_CODE (t, VECTOR_CST);
   TREE_CONSTANT (t) = 1;
+  VECTOR_CST_NELTS (t) = len;
 
   return t;
 }
index 19dd8073c555fe7670932923d3bc9ca7e91eeadb..490c3b6e51dbcb77fe0d97db346b45b9da5e5084 100644 (file)
@@ -1026,7 +1026,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
 #define TREE_IMAGPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.imag)
 
 /* In a VECTOR_CST node.  */
-#define VECTOR_CST_NELTS(NODE) (TYPE_VECTOR_SUBPARTS (TREE_TYPE (NODE)))
+#define VECTOR_CST_NELTS(NODE) (VECTOR_CST_CHECK (NODE)->base.u.nelts)
 #define VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elts)
 #define VECTOR_CST_ELT(NODE,IDX) (VECTOR_CST_CHECK (NODE)->vector.elts[IDX])