diff options
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 74 |
1 files changed, 69 insertions, 5 deletions
@@ -8041,6 +8041,34 @@ build_nonstandard_integer_type (unsigned HOST_WIDE_INT precision, return ret; } +#define MAX_BOOL_CACHED_PREC \ + (HOST_BITS_PER_WIDE_INT > 64 ? HOST_BITS_PER_WIDE_INT : 64) +static GTY(()) tree nonstandard_boolean_type_cache[MAX_BOOL_CACHED_PREC + 1]; + +/* Builds a boolean type of precision PRECISION. + Used for boolean vectors to choose proper vector element size. */ +tree +build_nonstandard_boolean_type (unsigned HOST_WIDE_INT precision) +{ + tree type; + + if (precision <= MAX_BOOL_CACHED_PREC) + { + type = nonstandard_boolean_type_cache[precision]; + if (type) + return type; + } + + type = make_node (BOOLEAN_TYPE); + TYPE_PRECISION (type) = precision; + fixup_unsigned_type (type); + + if (precision <= MAX_INT_CACHED_PREC) + nonstandard_boolean_type_cache[precision] = type; + + return type; +} + /* Create a range of some discrete type TYPE (an INTEGER_TYPE, ENUMERAL_TYPE or BOOLEAN_TYPE) with low bound LOWVAL and high bound HIGHVAL. If SHARED is true, reuse such a type that has already been constructed. */ @@ -9791,8 +9819,9 @@ make_vector_type (tree innertype, int nunits, machine_mode mode) if (TYPE_STRUCTURAL_EQUALITY_P (innertype)) SET_TYPE_STRUCTURAL_EQUALITY (t); - else if (TYPE_CANONICAL (innertype) != innertype - || mode != VOIDmode) + else if ((TYPE_CANONICAL (innertype) != innertype + || mode != VOIDmode) + && !VECTOR_BOOLEAN_TYPE_P (t)) TYPE_CANONICAL (t) = make_vector_type (TYPE_CANONICAL (innertype), nunits, VOIDmode); @@ -10617,6 +10646,40 @@ build_vector_type (tree innertype, int nunits) return make_vector_type (innertype, nunits, VOIDmode); } +/* Build truth vector with specified length and number of units. */ + +tree +build_truth_vector_type (unsigned nunits, unsigned vector_size) +{ + machine_mode mask_mode = targetm.vectorize.get_mask_mode (nunits, + vector_size); + + gcc_assert (mask_mode != VOIDmode); + + unsigned HOST_WIDE_INT esize = GET_MODE_BITSIZE (mask_mode) / nunits; + gcc_assert (esize * nunits == GET_MODE_BITSIZE (mask_mode)); + + tree bool_type = build_nonstandard_boolean_type (esize); + + return make_vector_type (bool_type, nunits, mask_mode); +} + +/* Returns a vector type corresponding to a comparison of VECTYPE. */ + +tree +build_same_sized_truth_vector_type (tree vectype) +{ + if (VECTOR_BOOLEAN_TYPE_P (vectype)) + return vectype; + + unsigned HOST_WIDE_INT size = GET_MODE_SIZE (TYPE_MODE (vectype)); + + if (!size) + size = tree_to_uhwi (TYPE_SIZE_UNIT (vectype)); + + return build_truth_vector_type (TYPE_VECTOR_SUBPARTS (vectype), size); +} + /* Similarly, but builds a variant type with TYPE_VECTOR_OPAQUE set. */ tree @@ -11103,9 +11166,10 @@ truth_type_for (tree type) { if (TREE_CODE (type) == VECTOR_TYPE) { - tree elem = lang_hooks.types.type_for_size - (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type))), 0); - return build_opaque_vector_type (elem, TYPE_VECTOR_SUBPARTS (type)); + if (VECTOR_BOOLEAN_TYPE_P (type)) + return type; + return build_truth_vector_type (TYPE_VECTOR_SUBPARTS (type), + GET_MODE_SIZE (TYPE_MODE (type))); } else return boolean_type_node; |