From patchwork Tue Dec 5 10:13:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1872029 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4SkxGw6Mgjz23mf for ; Tue, 5 Dec 2023 21:14:48 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A309B384CB9C for ; Tue, 5 Dec 2023 10:14:38 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 475BD385734D for ; Tue, 5 Dec 2023 10:13:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 475BD385734D Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 475BD385734D Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701771219; cv=none; b=bn60vhX77DckXpdLWqQ85f2qFU+MigBrX1rFy+sKzEZLYxO8O46hkMwNKJWSQYMDW15fcJEMI48khpXN1hqxd/NgwlRYV3TOdcmS6AD92f0540Jvk3YV1fBZO6SlvQjI+q24yPhSJcSn64d1Vb0xpgwiEKOlg4RU+ogWnjHGIvM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701771219; c=relaxed/simple; bh=yRk1wOpvFKgnS6QLIEMGZzYTsrEkDg3MKcWNrxXDyoo=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=YysMNIdjBsInz9IQD/NhMhZ24GB1lHdZM49Dw15X4gCxo5qfaDH0+1/GmEbpzst/YawiZ7TqDSzZTAizu4VzPazipdJPid6nu1zEVDJRfnkRyl36rOspYy8j7eIARCCGQEKocffiKygLY45z+qAT9WzG7PMYI2EBRssDQ7XkCxw= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A5BA91570; Tue, 5 Dec 2023 02:14:23 -0800 (PST) Received: from e121540-lin.manchester.arm.com (e121540-lin.manchester.arm.com [10.32.110.72]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 973313F5A1; Tue, 5 Dec 2023 02:13:36 -0800 (PST) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Cc: Richard Sandiford Subject: [pushed v2 05/25] aarch64: Add sve_type to SVE builtins code Date: Tue, 5 Dec 2023 10:13:03 +0000 Message-Id: <20231205101323.1914247-6-richard.sandiford@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231205101323.1914247-1-richard.sandiford@arm.com> References: <20231205101323.1914247-1-richard.sandiford@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-22.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org 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 55938413ef0..058b1defa9e 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 name associated with TYPE. Using the 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 dde35e15259..0dbd06791b8 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 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,