aboutsummaryrefslogtreecommitdiff
path: root/gcc/machmode.h
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-01-03 21:41:49 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-01-03 21:41:49 +0000
commit7b777afa955ad765500dfd53d6da990c84067197 (patch)
tree59c49cc214d86eec3fc81dedbb8c6b6b71dbfcb7 /gcc/machmode.h
parente5f83886b05c22f4bc221dac05e64b54ef7eece4 (diff)
downloadgcc-7b777afa955ad765500dfd53d6da990c84067197.zip
gcc-7b777afa955ad765500dfd53d6da990c84067197.tar.gz
gcc-7b777afa955ad765500dfd53d6da990c84067197.tar.bz2
poly_int: GET_MODE_NUNITS
This patch changes GET_MODE_NUNITS from unsigned char to poly_uint16, although it remains a macro when compiling target code with NUM_POLY_INT_COEFFS == 1. We can handle permuted loads and stores for variable nunits if the number of statements is a power of 2, but not otherwise. The to_constant call in make_vector_type goes away in a later patch. 2018-01-03 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * machmode.h (mode_nunits): Change from unsigned char to poly_uint16_pod. (ONLY_FIXED_SIZE_MODES): New macro. (pod_mode::measurement_type, scalar_int_mode::measurement_type) (scalar_float_mode::measurement_type, scalar_mode::measurement_type) (complex_mode::measurement_type, fixed_size_mode::measurement_type): New typedefs. (mode_to_nunits): Return a poly_uint16 rather than an unsigned short. (GET_MODE_NUNITS): Return a constant if ONLY_FIXED_SIZE_MODES, or if measurement_type is not polynomial. * genmodes.c (ZERO_COEFFS): New macro. (emit_mode_nunits_inline): Make mode_nunits_inline return a poly_uint16. (emit_mode_nunits): Change the type of mode_nunits to poly_uint16_pod. Use ZERO_COEFFS when emitting initializers. * data-streamer.h (bp_pack_poly_value): New function. (bp_unpack_poly_value): Likewise. * lto-streamer-in.c (lto_input_mode_table): Use bp_unpack_poly_value for GET_MODE_NUNITS. * lto-streamer-out.c (lto_write_mode_table): Use bp_pack_poly_value for GET_MODE_NUNITS. * tree.c (make_vector_type): Remove temporary shim and make the real function take the number of units as a poly_uint64 rather than an int. (build_vector_type_for_mode): Handle polynomial nunits. * dwarf2out.c (loc_descriptor, add_const_value_attribute): Likewise. * emit-rtl.c (const_vec_series_p_1): Likewise. (gen_rtx_CONST_VECTOR): Likewise. * fold-const.c (test_vec_duplicate_folding): Likewise. * genrecog.c (validate_pattern): Likewise. * optabs-query.c (can_vec_perm_var_p, can_mult_highpart_p): Likewise. * optabs-tree.c (expand_vec_cond_expr_p): Likewise. * optabs.c (expand_vector_broadcast, expand_binop_directly): Likewise. (shift_amt_for_vec_perm_mask, expand_vec_perm_var): Likewise. (expand_vec_cond_expr, expand_mult_highpart): Likewise. * rtlanal.c (subreg_get_info): Likewise. * tree-vect-data-refs.c (vect_grouped_store_supported): Likewise. (vect_grouped_load_supported): Likewise. * tree-vect-generic.c (type_for_widest_vector_mode): Likewise. * tree-vect-loop.c (have_whole_vector_shift): Likewise. * simplify-rtx.c (simplify_unary_operation_1): Likewise. (simplify_const_unary_operation, simplify_binary_operation_1) (simplify_const_binary_operation, simplify_ternary_operation) (test_vector_ops_duplicate, test_vector_ops): Likewise. (simplify_immed_subreg): Use GET_MODE_NUNITS on a fixed_size_mode instead of CONST_VECTOR_NUNITS. * varasm.c (output_constant_pool_2): Likewise. * rtx-vector-builder.c (rtx_vector_builder::build): Only include the explicit-encoded elements in the XVEC for variable-length vectors. gcc/ada/ * gcc-interface/misc.c (enumerate_modes): Handle polynomial GET_MODE_NUNITS. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r256195
Diffstat (limited to 'gcc/machmode.h')
-rw-r--r--gcc/machmode.h42
1 files changed, 39 insertions, 3 deletions
diff --git a/gcc/machmode.h b/gcc/machmode.h
index 6d9f542..b97e046 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -25,7 +25,7 @@ typedef opt_mode<machine_mode> opt_machine_mode;
extern CONST_MODE_SIZE unsigned short mode_size[NUM_MACHINE_MODES];
extern const unsigned short mode_precision[NUM_MACHINE_MODES];
extern const unsigned char mode_inner[NUM_MACHINE_MODES];
-extern const unsigned char mode_nunits[NUM_MACHINE_MODES];
+extern const poly_uint16_pod mode_nunits[NUM_MACHINE_MODES];
extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];
extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];
extern const unsigned char mode_wider[NUM_MACHINE_MODES];
@@ -76,6 +76,14 @@ struct mode_traits<machine_mode>
typedef machine_mode from_int;
};
+/* Always treat machine modes as fixed-size while compiling code specific
+ to targets that have no variable-size modes. */
+#if defined (IN_TARGET_CODE) && NUM_POLY_INT_COEFFS == 1
+#define ONLY_FIXED_SIZE_MODES 1
+#else
+#define ONLY_FIXED_SIZE_MODES 0
+#endif
+
/* Get the name of mode MODE as a string. */
extern const char * const mode_name[NUM_MACHINE_MODES];
@@ -313,6 +321,7 @@ template<typename T>
struct pod_mode
{
typedef typename mode_traits<T>::from_int from_int;
+ typedef typename T::measurement_type measurement_type;
machine_mode m_mode;
ALWAYS_INLINE operator machine_mode () const { return m_mode; }
@@ -391,6 +400,7 @@ class scalar_int_mode
{
public:
typedef mode_traits<scalar_int_mode>::from_int from_int;
+ typedef unsigned short measurement_type;
ALWAYS_INLINE scalar_int_mode () {}
ALWAYS_INLINE scalar_int_mode (from_int m) : m_mode (machine_mode (m)) {}
@@ -415,6 +425,7 @@ class scalar_float_mode
{
public:
typedef mode_traits<scalar_float_mode>::from_int from_int;
+ typedef unsigned short measurement_type;
ALWAYS_INLINE scalar_float_mode () {}
ALWAYS_INLINE scalar_float_mode (from_int m) : m_mode (machine_mode (m)) {}
@@ -439,6 +450,7 @@ class scalar_mode
{
public:
typedef mode_traits<scalar_mode>::from_int from_int;
+ typedef unsigned short measurement_type;
ALWAYS_INLINE scalar_mode () {}
ALWAYS_INLINE scalar_mode (from_int m) : m_mode (machine_mode (m)) {}
@@ -480,6 +492,7 @@ class complex_mode
{
public:
typedef mode_traits<complex_mode>::from_int from_int;
+ typedef unsigned short measurement_type;
ALWAYS_INLINE complex_mode () {}
ALWAYS_INLINE complex_mode (from_int m) : m_mode (machine_mode (m)) {}
@@ -570,7 +583,7 @@ mode_to_unit_precision (machine_mode mode)
/* Return the base GET_MODE_NUNITS value for MODE. */
-ALWAYS_INLINE unsigned short
+ALWAYS_INLINE poly_uint16
mode_to_nunits (machine_mode mode)
{
#if GCC_VERSION >= 4001
@@ -627,7 +640,29 @@ extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES];
/* Get the number of units in an object of mode MODE. This is 2 for
complex modes and the number of elements for vector modes. */
-#define GET_MODE_NUNITS(MODE) (mode_to_nunits (MODE))
+#if ONLY_FIXED_SIZE_MODES
+#define GET_MODE_NUNITS(MODE) (mode_to_nunits (MODE).coeffs[0])
+#else
+ALWAYS_INLINE poly_uint16
+GET_MODE_NUNITS (machine_mode mode)
+{
+ return mode_to_nunits (mode);
+}
+
+template<typename T>
+ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type
+GET_MODE_NUNITS (const T &mode)
+{
+ return mode_to_nunits (mode);
+}
+
+template<typename T>
+ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type
+GET_MODE_NUNITS (const T &mode)
+{
+ return mode_to_nunits (mode).coeffs[0];
+}
+#endif
/* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI). */
@@ -660,6 +695,7 @@ class fixed_size_mode
{
public:
typedef mode_traits<fixed_size_mode>::from_int from_int;
+ typedef unsigned short measurement_type;
ALWAYS_INLINE fixed_size_mode () {}
ALWAYS_INLINE fixed_size_mode (from_int m) : m_mode (machine_mode (m)) {}