From patchwork Thu Jan 10 14:47:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1022976 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-493780-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="nUYRQPSk"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43b83h4bTsz9sCs for ; Fri, 11 Jan 2019 01:47:27 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type; q=dns; s=default; b=UeyFd/ZmEFOf/0Ad9C35Q1WTliBWyemfXXzeI60zuGXXQLZuMK lb2DnL+bbfaiGx0vPhoBY58g6G8IovpyYOQ4Q/byZ8r5whKXgdz2ib2TS9oSlaoW V1/RYTM8lcJ2/HlkoEpiL6/5WWXdV3u0TK7O1lNm2B+jf+ZY5gdEBmc+0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type; s= default; bh=8LeUgNDO6pGw9yENeMUAAejcxhg=; b=nUYRQPSk0oY87jQGuu6G DYjO4KqsltR0vAkyvRVVxxnBqnMO/aiea3YaIUYM79fRe07yMSQeru+81fSt1BOF bOl7WS7IQdMHAwlcS7VjtnwVPnJRn9QhfrfIyIFnCYZA6bpTU0W7TWkBj7Q4N+ln O+Au535KD0M+MXXm+ZUttOU= Received: (qmail 13448 invoked by alias); 10 Jan 2019 14:47:19 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 13439 invoked by uid 89); 10 Jan 2019 14:47:19 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.2 spammy=Two, va_gc, ACLE, UD:id X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 10 Jan 2019 14:47:13 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5409E1596; Thu, 10 Jan 2019 06:47:12 -0800 (PST) Received: from localhost (unknown [10.32.98.35]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 608193F5AF; Thu, 10 Jan 2019 06:47:11 -0800 (PST) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, Kugan Vivekanandarajah , Prathamesh Kulkarni , richard.sandiford@arm.com Cc: Kugan Vivekanandarajah , Prathamesh Kulkarni Subject: [SVE ACLE] Two infrastructure tweaks Date: Thu, 10 Jan 2019 14:47:09 +0000 Message-ID: <87pnt47eoi.fsf@arm.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) MIME-Version: 1.0 Hi, The first patch replaces the autogenerated function enum with an explicit one, so that we can have more than one .def entry with the same function base name (e.g. predicated AND vs. integer AND). The second patch makes us get the expected modes from the insn data, rather than force callers to supply the modes explicitly. Committed to aarch64/sve-acle-branch. Richard [SVE ACLE] Get operand modes from insn_data Specifying the modes of operands explicitly was getting awkward, and getting the modes from the insn patterns still gives a decent amount of sanity checking. diff --git a/gcc/config/aarch64/aarch64-sve-builtins.c b/gcc/config/aarch64/aarch64-sve-builtins.c index a439fb9358e..46ff17caf86 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.c +++ b/gcc/config/aarch64/aarch64-sve-builtins.c @@ -444,10 +444,10 @@ private: rtx expand_signed_pred_op (rtx_code, rtx_code, int); rtx expand_signed_pred_op (int, int, int); - rtx expand_via_unpred_direct_optab (optab, unsigned int = 0); - rtx expand_via_unpred_insn (insn_code, unsigned int = 0); + rtx expand_via_unpred_direct_optab (optab); + rtx expand_via_unpred_insn (insn_code); rtx expand_via_pred_direct_optab (optab, unsigned int = DEFAULT_MERGE_ARGNO); - rtx expand_via_sel_insn (insn_code, unsigned int); + rtx expand_via_sel_insn (insn_code); rtx expand_via_pred_insn (insn_code, unsigned int = DEFAULT_MERGE_ARGNO); rtx expand_via_signed_unpred_insn (rtx_code, rtx_code); rtx expand_via_pred_x_insn (insn_code); @@ -462,8 +462,9 @@ private: rtx get_fallback_value (machine_mode, unsigned int, unsigned int, unsigned int &); - void add_output_operand (machine_mode); - void add_input_operand (rtx, machine_mode); + machine_mode get_next_operand_mode (insn_code); + void add_output_operand (insn_code); + void add_input_operand (insn_code, rtx); void add_integer_operand (HOST_WIDE_INT); rtx generate_insn (insn_code); @@ -1712,21 +1713,16 @@ function_expander::expand_dup () { if (m_fi.pred == PRED_none || m_fi.pred == PRED_x) - return expand_via_unpred_direct_optab (vec_duplicate_optab, 1); + return expand_via_unpred_direct_optab (vec_duplicate_optab); else { insn_code icode; machine_mode mode = get_mode (0); if (valid_for_const_vector_p (GET_MODE_INNER (mode), m_args.last ())) - { - icode = code_for_vcond_mask (get_mode (0), get_mode (0)); - return expand_via_sel_insn (icode, 0); - } + icode = code_for_vcond_mask (get_mode (0), get_mode (0)); else - { - icode = code_for_aarch64_sel_dup (get_mode (0)); - return expand_via_sel_insn (icode, 1); - } + icode = code_for_aarch64_sel_dup (get_mode (0)); + return expand_via_sel_insn (icode); } } @@ -1734,7 +1730,7 @@ function_expander::expand_dup () rtx function_expander::expand_index () { - return expand_via_unpred_direct_optab (vec_series_optab, 2); + return expand_via_unpred_direct_optab (vec_series_optab); } /* Expand a call to svmax. */ @@ -1824,36 +1820,28 @@ function_expander::expand_sub (bool reversed_p) } /* Implement the call using optab OP, which is an unpredicated direct - (i.e. single-mode) optab. The last NSCALAR inputs are scalar, and - map to scalar operands in the underlying instruction. */ + (i.e. single-mode) optab. */ rtx -function_expander::expand_via_unpred_direct_optab (optab op, - unsigned int nscalar) +function_expander::expand_via_unpred_direct_optab (optab op) { machine_mode mode = get_mode (0); insn_code icode = direct_optab_handler (op, mode); - return expand_via_unpred_insn (icode, nscalar); + return expand_via_unpred_insn (icode); } -/* Implement the call using instruction ICODE. The last NSCALAR inputs - are scalar, and map to scalar operands in the underlying instruction. */ +/* Implement the call using instruction ICODE. */ rtx -function_expander::expand_via_unpred_insn (insn_code icode, - unsigned int nscalar) +function_expander::expand_via_unpred_insn (insn_code icode) { /* Discount the output operand. */ unsigned int nops = insn_data[icode].n_operands - 1; /* Drop the predicate argument in the case of _x predication. */ unsigned int bias = (m_fi.pred == PRED_x ? 1 : 0); - machine_mode mode = get_mode (0); unsigned int i = 0; - add_output_operand (mode); - - for (; i < nops - nscalar; ++i) - add_input_operand (m_args[i + bias], mode); + add_output_operand (icode); for (; i < nops; ++i) - add_input_operand (m_args[i + bias], GET_MODE_INNER (mode)); + add_input_operand (icode, m_args[i + bias]); return generate_insn (icode); } @@ -1876,29 +1864,21 @@ function_expander::expand_via_pred_direct_optab (optab op, 0: output 1: true value 2: false value - 3: predicate - - The last NSCALAR inputs are scalar, and map to scalar operands - in the underlying instruction. */ + 3: predicate. */ rtx -function_expander::expand_via_sel_insn (insn_code icode, - unsigned int nscalar) +function_expander::expand_via_sel_insn (insn_code icode) { machine_mode mode = get_mode (0); - machine_mode pred_mode = get_pred_mode (0); unsigned int opno = 0; rtx false_arg = get_fallback_value (mode, 1, 0, opno); rtx pred_arg = m_args[opno++]; rtx true_arg = m_args[opno++]; - add_output_operand (mode); - if (nscalar) - add_input_operand (true_arg, GET_MODE_INNER (mode)); - else - add_input_operand (true_arg, mode); - add_input_operand (false_arg, mode); - add_input_operand (pred_arg, pred_mode); + add_output_operand (icode); + add_input_operand (icode, true_arg); + add_input_operand (icode, false_arg); + add_input_operand (icode, pred_arg); return generate_insn (icode); } @@ -1915,17 +1895,16 @@ function_expander::expand_via_pred_insn (insn_code icode, /* Discount the output, predicate, and fallback value. */ unsigned int nops = insn_data[icode].n_operands - 3; machine_mode mode = get_mode (0); - machine_mode pred_mode = get_pred_mode (0); unsigned int opno = 0; rtx fallback_arg = get_fallback_value (mode, nops, merge_argno, opno); rtx pred_arg = m_args[opno++]; - add_output_operand (mode); - add_input_operand (pred_arg, pred_mode); + add_output_operand (icode); + add_input_operand (icode, pred_arg); for (unsigned int i = 0; i < nops; ++i) - add_input_operand (m_args[opno + i], mode); - add_input_operand (fallback_arg, mode); + add_input_operand (icode, m_args[opno + i]); + add_input_operand (icode, fallback_arg); return generate_insn (icode); } @@ -1939,10 +1918,10 @@ function_expander::expand_via_pred_x_insn (insn_code icode) machine_mode pred_mode = get_pred_mode (0); /* Add the normal operands. */ - add_output_operand (mode); - add_input_operand (m_args[0], pred_mode); + add_output_operand (icode); + add_input_operand (icode, m_args[0]); for (unsigned int i = 0; i < nops; ++i) - add_input_operand (m_args[i + 1], mode); + add_input_operand (icode, m_args[i + 1]); /* Add a flag that indicates whether unpredicated instructions are allowed. */ @@ -2150,29 +2129,43 @@ function_expander::get_fallback_value (machine_mode mode, unsigned int nops, return m_args[merge_argno]; } -/* Add an output operand of mode MODE to the instruction, binding it - to the preferred target rtx if possible. */ +/* Return the mode of the next operand of the instruction we're building, + which has code ICODE. */ +machine_mode +function_expander::get_next_operand_mode (insn_code icode) +{ + machine_mode mode = insn_data[icode].operand[m_ops.length ()].mode; + /* SVE ACLE patterns must specify a mode for every operand. */ + gcc_assert (mode != VOIDmode); + return mode; +} + +/* Add an output operand to the instruction we're building, which has + code ICODE. Bind the output to the preferred target rtx if possible. */ void -function_expander::add_output_operand (machine_mode mode) +function_expander::add_output_operand (insn_code icode) { + machine_mode mode = get_next_operand_mode (icode); m_ops.safe_grow (m_ops.length () + 1); create_output_operand (&m_ops.last (), m_target, mode); } -/* Add an input operand with mode MODE to the instruction. Calculate - the value of the operand as follows: +/* Add an input operand to the instruction we're building, which has + code ICODE. Calculate the value of the operand as follows: - - If MODE is a vector and X is not, broadcast X to fill a vector of - mode MODE. + - If the operand is a vector and X is not, broadcast X to fill a + vector of the appropriate mode. - - Otherwise, if MODE is a predicate mode, coerce X to have that mode. - In this case X is known to be VNx16BImode. + - Otherwise, if the operand is a predicate, coerce X to have the + mode that the instruction expects. In this case X is known to be + VNx16BImode (the mode of svbool_t). - - Otherwise use X directly. The expand machinery checks that X is - consistent with MODE. */ + - Otherwise use X directly. The expand machinery checks that X has + the right mode for the instruction. */ void -function_expander::add_input_operand (rtx x, machine_mode mode) +function_expander::add_input_operand (insn_code icode, rtx x) { + machine_mode mode = get_next_operand_mode (icode); if (!VECTOR_MODE_P (GET_MODE (x)) && VECTOR_MODE_P (mode)) x = expand_vector_broadcast (mode, x); else if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)