231 lines
8.9 KiB
Diff
231 lines
8.9 KiB
Diff
From a32a9321b3336907fe2d17148cb9e4652642a3e6 Mon Sep 17 00:00:00 2001
|
|
From: Richard Sandiford <richard.sandiford@arm.com>
|
|
Date: Tue, 5 Dec 2023 10:11:20 +0000
|
|
Subject: [PATCH 066/157] [Backport][SME] aarch64: Add sve_type to SVE builtins
|
|
code
|
|
|
|
Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=7f6de9861e5d7745a0af5174582519a39d545a92
|
|
|
|
Until now, the SVE ACLE code had mostly been able to represent
|
|
individual SVE arguments with just an element type suffix (s32, u32,
|
|
etc.). However, the SME2 ACLE provides many overloaded intrinsics
|
|
that operate on tuples rather than single vectors. This patch
|
|
therefore adds a new type (sve_type) that combines an element
|
|
type suffix with a vector count. This is enough to uniquely
|
|
represent all SVE ACLE types.
|
|
|
|
gcc/
|
|
* config/aarch64/aarch64-sve-builtins.h (sve_type): New struct.
|
|
(sve_type::operator==): New function.
|
|
(function_resolver::get_vector_type): Delete.
|
|
(function_resolver::report_no_such_form): Take an sve_type rather
|
|
than a type_suffix_index.
|
|
* config/aarch64/aarch64-sve-builtins.cc (get_vector_type): New
|
|
function.
|
|
(function_resolver::get_vector_type): Delete.
|
|
(function_resolver::report_no_such_form): Take an sve_type rather
|
|
than a type_suffix_index.
|
|
(find_sve_type): New function, split out from...
|
|
(function_resolver::infer_vector_or_tuple_type): ...here.
|
|
---
|
|
gcc/config/aarch64/aarch64-sve-builtins.cc | 93 ++++++++++++----------
|
|
gcc/config/aarch64/aarch64-sve-builtins.h | 37 ++++++++-
|
|
2 files changed, 88 insertions(+), 42 deletions(-)
|
|
|
|
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc
|
|
index dc3fd80da..cc676bfe1 100644
|
|
--- a/gcc/config/aarch64/aarch64-sve-builtins.cc
|
|
+++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
|
|
@@ -659,6 +659,14 @@ find_type_suffix_for_scalar_type (const_tree type)
|
|
return NUM_TYPE_SUFFIXES;
|
|
}
|
|
|
|
+/* Return the vector type associated with TYPE. */
|
|
+static tree
|
|
+get_vector_type (sve_type type)
|
|
+{
|
|
+ auto vector_type = type_suffixes[type.type].vector_type;
|
|
+ return acle_vector_types[type.num_vectors - 1][vector_type];
|
|
+}
|
|
+
|
|
/* Report an error against LOCATION that the user has tried to use
|
|
function FNDECL when extension EXTENSION is disabled. */
|
|
static void
|
|
@@ -1190,13 +1198,6 @@ function_resolver::function_resolver (location_t location,
|
|
{
|
|
}
|
|
|
|
-/* Return the vector type associated with type suffix TYPE. */
|
|
-tree
|
|
-function_resolver::get_vector_type (type_suffix_index type)
|
|
-{
|
|
- return acle_vector_types[0][type_suffixes[type].vector_type];
|
|
-}
|
|
-
|
|
/* Return the <stdint.h> name associated with TYPE. Using the <stdint.h>
|
|
name should be more user-friendly than the underlying canonical type,
|
|
since it makes the signedness and bitwidth explicit. */
|
|
@@ -1227,10 +1228,10 @@ function_resolver::scalar_argument_p (unsigned int i)
|
|
|| SCALAR_FLOAT_TYPE_P (type));
|
|
}
|
|
|
|
-/* Report that the function has no form that takes type suffix TYPE.
|
|
+/* Report that the function has no form that takes type TYPE.
|
|
Return error_mark_node. */
|
|
tree
|
|
-function_resolver::report_no_such_form (type_suffix_index type)
|
|
+function_resolver::report_no_such_form (sve_type type)
|
|
{
|
|
error_at (location, "%qE has no form that takes %qT arguments",
|
|
fndecl, get_vector_type (type));
|
|
@@ -1352,6 +1353,25 @@ function_resolver::infer_pointer_type (unsigned int argno,
|
|
return type;
|
|
}
|
|
|
|
+/* If TYPE is an SVE predicate or vector type, or a tuple of such a type,
|
|
+ return the associated sve_type, otherwise return an invalid sve_type. */
|
|
+static sve_type
|
|
+find_sve_type (const_tree type)
|
|
+{
|
|
+ /* A linear search should be OK here, since the code isn't hot and
|
|
+ the number of types is only small. */
|
|
+ for (unsigned int size_i = 0; size_i < MAX_TUPLE_SIZE; ++size_i)
|
|
+ for (unsigned int suffix_i = 0; suffix_i < NUM_TYPE_SUFFIXES; ++suffix_i)
|
|
+ {
|
|
+ vector_type_index type_i = type_suffixes[suffix_i].vector_type;
|
|
+ tree this_type = acle_vector_types[size_i][type_i];
|
|
+ if (this_type && matches_type_p (this_type, type))
|
|
+ return { type_suffix_index (suffix_i), size_i + 1 };
|
|
+ }
|
|
+
|
|
+ return {};
|
|
+}
|
|
+
|
|
/* Require argument ARGNO to be a single vector or a tuple of NUM_VECTORS
|
|
vectors; NUM_VECTORS is 1 for the former. Return the associated type
|
|
suffix on success, using TYPE_SUFFIX_b for predicates. Report an error
|
|
@@ -1364,37 +1384,30 @@ function_resolver::infer_vector_or_tuple_type (unsigned int argno,
|
|
if (actual == error_mark_node)
|
|
return NUM_TYPE_SUFFIXES;
|
|
|
|
- /* A linear search should be OK here, since the code isn't hot and
|
|
- the number of types is only small. */
|
|
- for (unsigned int size_i = 0; size_i < MAX_TUPLE_SIZE; ++size_i)
|
|
- for (unsigned int suffix_i = 0; suffix_i < NUM_TYPE_SUFFIXES; ++suffix_i)
|
|
- {
|
|
- vector_type_index type_i = type_suffixes[suffix_i].vector_type;
|
|
- tree type = acle_vector_types[size_i][type_i];
|
|
- if (type && matches_type_p (type, actual))
|
|
- {
|
|
- if (size_i + 1 == num_vectors)
|
|
- return type_suffix_index (suffix_i);
|
|
-
|
|
- if (num_vectors == 1)
|
|
- error_at (location, "passing %qT to argument %d of %qE, which"
|
|
- " expects a single SVE vector rather than a tuple",
|
|
- actual, argno + 1, fndecl);
|
|
- else if (size_i == 0 && type_i != VECTOR_TYPE_svbool_t)
|
|
- /* num_vectors is always != 1, so the singular isn't needed. */
|
|
- error_n (location, num_vectors, "%qT%d%qE%d",
|
|
- "passing single vector %qT to argument %d"
|
|
- " of %qE, which expects a tuple of %d vectors",
|
|
- actual, argno + 1, fndecl, num_vectors);
|
|
- else
|
|
- /* num_vectors is always != 1, so the singular isn't needed. */
|
|
- error_n (location, num_vectors, "%qT%d%qE%d",
|
|
- "passing %qT to argument %d of %qE, which"
|
|
- " expects a tuple of %d vectors", actual, argno + 1,
|
|
- fndecl, num_vectors);
|
|
- return NUM_TYPE_SUFFIXES;
|
|
- }
|
|
- }
|
|
+ if (auto sve_type = find_sve_type (actual))
|
|
+ {
|
|
+ if (sve_type.num_vectors == num_vectors)
|
|
+ return sve_type.type;
|
|
+
|
|
+ if (num_vectors == 1)
|
|
+ error_at (location, "passing %qT to argument %d of %qE, which"
|
|
+ " expects a single SVE vector rather than a tuple",
|
|
+ actual, argno + 1, fndecl);
|
|
+ else if (sve_type.num_vectors == 1
|
|
+ && sve_type.type != TYPE_SUFFIX_b)
|
|
+ /* num_vectors is always != 1, so the singular isn't needed. */
|
|
+ error_n (location, num_vectors, "%qT%d%qE%d",
|
|
+ "passing single vector %qT to argument %d"
|
|
+ " of %qE, which expects a tuple of %d vectors",
|
|
+ actual, argno + 1, fndecl, num_vectors);
|
|
+ else
|
|
+ /* num_vectors is always != 1, so the singular isn't needed. */
|
|
+ error_n (location, num_vectors, "%qT%d%qE%d",
|
|
+ "passing %qT to argument %d of %qE, which"
|
|
+ " expects a tuple of %d vectors", actual, argno + 1,
|
|
+ fndecl, num_vectors);
|
|
+ return NUM_TYPE_SUFFIXES;
|
|
+ }
|
|
|
|
if (num_vectors == 1)
|
|
error_at (location, "passing %qT to argument %d of %qE, which"
|
|
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.h b/gcc/config/aarch64/aarch64-sve-builtins.h
|
|
index 374c57e93..f4f2c415f 100644
|
|
--- a/gcc/config/aarch64/aarch64-sve-builtins.h
|
|
+++ b/gcc/config/aarch64/aarch64-sve-builtins.h
|
|
@@ -263,6 +263,40 @@ struct group_suffix_info
|
|
unsigned int vectors_per_tuple;
|
|
};
|
|
|
|
+/* Represents an SVE vector, predicate, tuple of vectors, or tuple of
|
|
+ predicates. There is also a representation of "no type"/"invalid type". */
|
|
+struct sve_type
|
|
+{
|
|
+ sve_type () = default;
|
|
+ sve_type (type_suffix_index type) : type (type), num_vectors (1) {}
|
|
+ sve_type (type_suffix_index type, unsigned int num_vectors)
|
|
+ : type (type), num_vectors (num_vectors) {}
|
|
+
|
|
+ /* Return true if the type is valid. */
|
|
+ explicit operator bool () const { return type != NUM_TYPE_SUFFIXES; }
|
|
+
|
|
+ bool operator== (const sve_type &) const;
|
|
+ bool operator!= (const sve_type &x) const { return !operator== (x); }
|
|
+
|
|
+ /* This is one of:
|
|
+
|
|
+ - TYPE_SUFFIX_b for svbool_t-based types
|
|
+ - TYPE_SUFFIX_c for svcount_t-based types
|
|
+ - the type suffix of a data element for SVE data vectors and tuples
|
|
+ - NUM_TYPE_SUFFIXES for invalid types. */
|
|
+ type_suffix_index type = NUM_TYPE_SUFFIXES;
|
|
+
|
|
+ /* If the type is a tuple, this is the number of vectors in the tuple,
|
|
+ otherwise it is 1. */
|
|
+ unsigned int num_vectors = 1;
|
|
+};
|
|
+
|
|
+inline bool
|
|
+sve_type::operator== (const sve_type &other) const
|
|
+{
|
|
+ return type == other.type && num_vectors == other.num_vectors;
|
|
+}
|
|
+
|
|
/* Static information about a set of functions. */
|
|
struct function_group_info
|
|
{
|
|
@@ -413,12 +447,11 @@ public:
|
|
function_resolver (location_t, const function_instance &, tree,
|
|
vec<tree, va_gc> &);
|
|
|
|
- tree get_vector_type (type_suffix_index);
|
|
const char *get_scalar_type_name (type_suffix_index);
|
|
tree get_argument_type (unsigned int);
|
|
bool scalar_argument_p (unsigned int);
|
|
|
|
- tree report_no_such_form (type_suffix_index);
|
|
+ tree report_no_such_form (sve_type);
|
|
tree lookup_form (mode_suffix_index,
|
|
type_suffix_index = NUM_TYPE_SUFFIXES,
|
|
type_suffix_index = NUM_TYPE_SUFFIXES,
|
|
--
|
|
2.33.0
|
|
|