]> gcc.gnu.org Git - gcc.git/commitdiff
tree: Add vector_element_bits(_tree) [PR94980 1/3]
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 12 May 2020 08:01:10 +0000 (09:01 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Tue, 12 May 2020 08:01:10 +0000 (09:01 +0100)
A lot of code that wants to know the number of bits in a vector
element gets that information from the element's TYPE_SIZE,
which is always equal to TYPE_SIZE_UNIT * BITS_PER_UNIT.
This doesn't work for SVE and AVX512-style packed boolean vectors,
where several elements can occupy a single byte.

This patch introduces a new pair of helpers for getting the true
(possibly sub-byte) size.  I made a token attempt to convert obvious
element size calculations, but I'm sure I missed some.

2020-05-12  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
PR tree-optimization/94980
* tree.h (vector_element_bits, vector_element_bits_tree): Declare.
* tree.c (vector_element_bits, vector_element_bits_tree): New.
* match.pd: Use the new functions instead of determining the
vector element size directly from TYPE_SIZE(_UNIT).
* tree-vect-data-refs.c (vect_gather_scatter_fn_p): Likewise.
* tree-vect-patterns.c (vect_recog_mask_conversion_pattern): Likewise.
* tree-vect-stmts.c (vect_is_simple_cond): Likewise.
* tree-vect-generic.c (expand_vector_piecewise): Likewise.
(expand_vector_conversion): Likewise.
(expand_vector_addition): Likewise for a TYPE_SIZE_UNIT used as
a divisor.  Convert the dividend to bits to compensate.
* tree-vect-loop.c (vectorizable_live_operation): Call
vector_element_bits instead of open-coding it.

gcc/ChangeLog
gcc/match.pd
gcc/tree-vect-data-refs.c
gcc/tree-vect-generic.c
gcc/tree-vect-loop.c
gcc/tree-vect-patterns.c
gcc/tree-vect-stmts.c
gcc/tree.c
gcc/tree.h

index ffa00559387be1289f765067c08e8216a4272c5b..203cb61c6827573781ec15c26a8eafa0f9ea1c31 100644 (file)
@@ -1,3 +1,20 @@
+2020-05-12  Richard Sandiford  <richard.sandiford@arm.com>
+
+       PR tree-optimization/94980
+       * tree.h (vector_element_bits, vector_element_bits_tree): Declare.
+       * tree.c (vector_element_bits, vector_element_bits_tree): New.
+       * match.pd: Use the new functions instead of determining the
+       vector element size directly from TYPE_SIZE(_UNIT).
+       * tree-vect-data-refs.c (vect_gather_scatter_fn_p): Likewise.
+       * tree-vect-patterns.c (vect_recog_mask_conversion_pattern): Likewise.
+       * tree-vect-stmts.c (vect_is_simple_cond): Likewise.
+       * tree-vect-generic.c (expand_vector_piecewise): Likewise.
+       (expand_vector_conversion): Likewise.
+       (expand_vector_addition): Likewise for a TYPE_SIZE_UNIT used as
+       a divisor.  Convert the dividend to bits to compensate.
+       * tree-vect-loop.c (vectorizable_live_operation): Call
+       vector_element_bits instead of open-coding it.
+
 2020-05-12  Jakub Jelinek  <jakub@redhat.com>
 
        * omp-offload.h (omp_discover_implicit_declare_target): Declare.
index 58a4ac664149547bbd27e0b2e6410a43f141eeb7..33ee1a920bf4a036cc5fdb3c96b38b52765bdefb 100644 (file)
@@ -6306,7 +6306,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       }
       (if (ins)
        (bit_insert { op0; } { ins; }
-         { bitsize_int (at * tree_to_uhwi (TYPE_SIZE (TREE_TYPE (type)))); })
+         { bitsize_int (at * vector_element_bits (type)); })
        (if (changed)
         (vec_perm { op0; } { op1; } { op2; }))))))))))
 
index d41ba49fabfe17a8abf573f139705ed364174b94..b950aa9e50d1b5be71d48480b17f85522736051f 100644 (file)
@@ -3693,7 +3693,7 @@ vect_gather_scatter_fn_p (vec_info *vinfo, bool read_p, bool masked_p,
                          tree *offset_vectype_out)
 {
   unsigned int memory_bits = tree_to_uhwi (TYPE_SIZE (memory_type));
-  unsigned int element_bits = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (vectype)));
+  unsigned int element_bits = vector_element_bits (vectype);
   if (element_bits != memory_bits)
     /* For now the vector elements must be the same width as the
        memory elements.  */
index 8b00f3250543e1b95630aa372b8a6429318f3d3d..126e906e0a91406047264b992aeab4effe3e38c5 100644 (file)
@@ -276,8 +276,7 @@ expand_vector_piecewise (gimple_stmt_iterator *gsi, elem_op_func f,
   tree part_width = TYPE_SIZE (inner_type);
   tree index = bitsize_int (0);
   int nunits = nunits_for_known_piecewise_op (type);
-  int delta = tree_to_uhwi (part_width)
-             / tree_to_uhwi (TYPE_SIZE (TREE_TYPE (type)));
+  int delta = tree_to_uhwi (part_width) / vector_element_bits (type);
   int i;
   location_t loc = gimple_location (gsi_stmt (*gsi));
 
@@ -357,8 +356,7 @@ expand_vector_addition (gimple_stmt_iterator *gsi,
                        elem_op_func f, elem_op_func f_parallel,
                        tree type, tree a, tree b, enum tree_code code)
 {
-  int parts_per_word = UNITS_PER_WORD
-                      / tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type)));
+  int parts_per_word = BITS_PER_WORD / vector_element_bits (type);
 
   if (INTEGRAL_TYPE_P (TREE_TYPE (type))
       && parts_per_word >= 4
@@ -1727,19 +1725,17 @@ expand_vector_conversion (gimple_stmt_iterator *gsi)
   optab optab1 = unknown_optab;
 
   gcc_checking_assert (VECTOR_TYPE_P (ret_type) && VECTOR_TYPE_P (arg_type));
-  gcc_checking_assert (tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (ret_type))));
-  gcc_checking_assert (tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type))));
   if (INTEGRAL_TYPE_P (TREE_TYPE (ret_type))
       && SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg_type)))
     code = FIX_TRUNC_EXPR;
   else if (INTEGRAL_TYPE_P (TREE_TYPE (arg_type))
           && SCALAR_FLOAT_TYPE_P (TREE_TYPE (ret_type)))
     code = FLOAT_EXPR;
-  if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (ret_type)))
-      < tree_to_uhwi (TYPE_SIZE (TREE_TYPE (arg_type))))
+  unsigned int ret_elt_bits = vector_element_bits (ret_type);
+  unsigned int arg_elt_bits = vector_element_bits (arg_type);
+  if (ret_elt_bits < arg_elt_bits)
     modifier = NARROW;
-  else if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (ret_type)))
-          > tree_to_uhwi (TYPE_SIZE (TREE_TYPE (arg_type))))
+  else if (ret_elt_bits > arg_elt_bits)
     modifier = WIDEN;
 
   if (modifier == NONE && (code == FIX_TRUNC_EXPR || code == FLOAT_EXPR))
@@ -1902,8 +1898,7 @@ expand_vector_conversion (gimple_stmt_iterator *gsi)
              tree part_width = TYPE_SIZE (compute_type);
              tree index = bitsize_int (0);
              int nunits = nunits_for_known_piecewise_op (arg_type);
-             int delta = tree_to_uhwi (part_width)
-                         / tree_to_uhwi (TYPE_SIZE (TREE_TYPE (arg_type)));
+             int delta = tree_to_uhwi (part_width) / arg_elt_bits;
              int i;
              location_t loc = gimple_location (gsi_stmt (*gsi));
 
index 64463b874c71fa9bbaea061f97bb8bf84fafbbce..180790abf421ceffe5af9a53f4847e37ba776b6f 100644 (file)
@@ -8017,9 +8017,7 @@ vectorizable_live_operation (loop_vec_info loop_vinfo,
        : gimple_get_lhs (stmt);
   lhs_type = TREE_TYPE (lhs);
 
-  bitsize = (VECTOR_BOOLEAN_TYPE_P (vectype)
-            ? bitsize_int (TYPE_PRECISION (TREE_TYPE (vectype)))
-            : TYPE_SIZE (TREE_TYPE (vectype)));
+  bitsize = vector_element_bits_tree (vectype);
   vec_bitsize = TYPE_SIZE (vectype);
 
   /* Get the vectorized lhs of STMT and the lane to use (counted in bits).  */
index 1f148a0e620943a6b16762ac0a481c46ab6dd6b5..a1fd67341d770de99f388289c4eacbdf3b399380 100644 (file)
@@ -4381,8 +4381,7 @@ vect_recog_mask_conversion_pattern (vec_info *vinfo,
                  || dt == vect_constant_def))
            {
              tree wide_scalar_type = build_nonstandard_integer_type
-               (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (vectype1))),
-                TYPE_UNSIGNED (rhs1_type));
+               (vector_element_bits (vectype1), TYPE_UNSIGNED (rhs1_type));
              tree vectype3 = get_vectype_for_scalar_type (vinfo,
                                                           wide_scalar_type);
              if (expand_vec_cond_expr_p (vectype1, vectype3, TREE_CODE (rhs1)))
index f7f19fee1bb7fce1eb161f48251a17257d0573a1..9a715b82f1acb54e6df768fb3c94c06973e3e2d2 100644 (file)
@@ -10041,8 +10041,7 @@ vect_is_simple_cond (tree cond, vec_info *vinfo, slp_tree slp_node,
              && tree_int_cst_lt (TYPE_SIZE (scalar_type),
                                  TYPE_SIZE (TREE_TYPE (vectype))))
            scalar_type = build_nonstandard_integer_type
-             (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (vectype))),
-              TYPE_UNSIGNED (scalar_type));
+             (vector_element_bits (vectype), TYPE_UNSIGNED (scalar_type));
          *comp_vectype = get_vectype_for_scalar_type (vinfo, scalar_type,
                                                       slp_node);
        }
index 5b7d3fddbcbcc1f4814677f99e7a4c25b55fd53e..1aabffeea433fc690c2610f9ba7978912b840c17 100644 (file)
@@ -13806,6 +13806,30 @@ vector_type_mode (const_tree t)
   return mode;
 }
 
+/* Return the size in bits of each element of vector type TYPE.  */
+
+unsigned int
+vector_element_bits (const_tree type)
+{
+  gcc_checking_assert (VECTOR_TYPE_P (type));
+  if (VECTOR_BOOLEAN_TYPE_P (type))
+    return vector_element_size (tree_to_poly_uint64 (TYPE_SIZE (type)),
+                               TYPE_VECTOR_SUBPARTS (type));
+  return tree_to_uhwi (TYPE_SIZE (TREE_TYPE (type)));
+}
+
+/* Calculate the size in bits of each element of vector type TYPE
+   and return the result as a tree of type bitsizetype.  */
+
+tree
+vector_element_bits_tree (const_tree type)
+{
+  gcc_checking_assert (VECTOR_TYPE_P (type));
+  if (VECTOR_BOOLEAN_TYPE_P (type))
+    return bitsize_int (vector_element_bits (type));
+  return TYPE_SIZE (TREE_TYPE (type));
+}
+
 /* Verify that basic properties of T match TV and thus T can be a variant of
    TV.  TV should be the more specified variant (i.e. the main variant).  */
 
index 4644d6616d91229fde7035c5fc5f50bf170e67b8..11c109fffcd725a0a539bb1231bdd93f3d74681a 100644 (file)
@@ -1996,6 +1996,8 @@ class auto_suppress_location_wrappers
 
 extern machine_mode element_mode (const_tree);
 extern machine_mode vector_type_mode (const_tree);
+extern unsigned int vector_element_bits (const_tree);
+extern tree vector_element_bits_tree (const_tree);
 
 /* The "canonical" type for this type node, which is used by frontends to
    compare the type for equality with another type.  If two types are
This page took 0.09795 seconds and 5 git commands to generate.