From patchwork Sat Sep 23 09:01:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 817780 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-462823-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="AjmeO/E0"; 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 3xzkr05V0mz9t63 for ; Sat, 23 Sep 2017 19:02:08 +1000 (AEST) 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:subject:date:message-id:mime-version:content-type; q=dns; s= default; b=wczoLDmox8AnWaXJL+Wj/HxFnaxvU15ZFrV2mbcvBISQo4ZAs/pTH d3lC71BpdvCqo8Y321QByIiVHAlGB0EgDmRLwTxAPqhiQqxtIdUF/aw6O11fpOrb IcVk1ARQzkAGFdhMIzuRp0d40ia5e+nrwsrEQfyjIY6ILO7ZB7pado= 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:subject:date:message-id:mime-version:content-type; s= default; bh=c5KpA3gzKPq9PEJgxhbZONBmkBc=; b=AjmeO/E0+we2aJo950GR 7nGTOyo+TLJGCE1G+bYVX/MZPNm4kwR01W6dMptRCppVEDlKUvRMvb4QX3E0mQzj JfTOCN5tTvBqD3hp6cwn7+nqB76U9loONRvHQIj490M7NlsfaLvgiT7hYAKG2iNN F3VsMuu808qMGqVAPNP7UbA= Received: (qmail 1176 invoked by alias); 23 Sep 2017 09:02:01 -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 1167 invoked by uid 89); 23 Sep 2017 09:02:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-15.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy=wind X-HELO: mail-wr0-f178.google.com Received: from mail-wr0-f178.google.com (HELO mail-wr0-f178.google.com) (209.85.128.178) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 23 Sep 2017 09:01:58 +0000 Received: by mail-wr0-f178.google.com with SMTP id v109so2322307wrc.1 for ; Sat, 23 Sep 2017 02:01:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:mail-followup-to:subject:date:message-id :user-agent:mime-version; bh=LRUhmJrtJNpGD8hfeOuyoXKRoaPAg4f2a/nph8akgBI=; b=oxEt+sSlLCnruphptDJLzCOxXvtBFmqvUVDJBqZi+lqLFstg4t3PNmyltIwWyJ9qpW TPw1HqUoY4nzPsLhp+OQS6XXU3io/Zv7RRoK4UqqJju4+6lVCHRMyTFpHxMVXqeIzcCJ iAsYrS4i6utYZu2TTpHap9AmI1GVe/Vb3+jPkOsLKZ3uiR8IPNeoRwB7APf7IpZTlPME uUKYCc4Sy6IEyhqEjB3aFth2xLHrETrynOhKIypC3j7Eu/LlX2jIwmRn+jZdLprw04d1 0uz781we377WO/V2+v6VJrVUyNyklSvMgvGHIOwr9pUXf4IAgT2Td5MmFMFrVdEmh9Ze doQw== X-Gm-Message-State: AHPjjUhBk2XsyYa/E8QYBZdKttZOdhsuqsUpjW42eO9axQ4ES2ugFcbR qiudqRWJf5cR+JTUyTZE6RH2v6KQ9F4= X-Google-Smtp-Source: AOwi7QD9Fih62AmI3YoylI3stTacoMVwiACPyIxK9OftJn1SlEfqrdDBXXEnOBDjL9H4mfN6Mpd0qA== X-Received: by 10.223.131.65 with SMTP id 59mr1424886wrd.137.1506157316155; Sat, 23 Sep 2017 02:01:56 -0700 (PDT) Received: from localhost ([2.25.234.72]) by smtp.gmail.com with ESMTPSA id e17sm5193780wmf.46.2017.09.23.02.01.54 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 23 Sep 2017 02:01:54 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: Allow vector CONSTs Date: Sat, 23 Sep 2017 10:01:52 +0100 Message-ID: <878th5rdof.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 This patch allows (const ...) wrappers to be used for rtx vector constants, as an alternative to const_vector. This is useful for SVE, where the number of elements isn't known until runtime. It could also be useful in future for fixed-length vectors, to reduce the amount of memory needed to represent simple constants with high element counts. I don't have any plans to make that switch though. Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu. Also tested by comparing the testsuite assembly output on at least one target per CPU directory. OK to install? Richard 2017-09-22 Richard Sandiford Alan Hayward David Sherwood gcc/ * doc/rtl.texi (const): Update description of address constants. Say that vector constants are allowed too. * common.md (E, F): Use CONSTANT_P instead of checking for CONST_VECTOR. * emit-rtl.c (gen_lowpart_common): Use const_vec_p instead of checking for CONST_VECTOR. * expmed.c (make_tree): Use build_vector_from_val for a CONST VEC_DUPLICATE. * expr.c (expand_expr_real_2): Check for vector modes instead of checking for CONST_VECTOR. * rtl.h (const_vec_p): New function. (const_vec_duplicate_p): Check for a CONST VEC_DUPLICATE. (unwrap_const_vec_duplicate): Handle them here too. Index: gcc/doc/rtl.texi =================================================================== --- gcc/doc/rtl.texi 2017-09-23 10:00:32.162585322 +0100 +++ gcc/doc/rtl.texi 2017-09-23 10:00:32.351313708 +0100 @@ -1667,14 +1667,17 @@ Usually that is the only mode for which @findex const @item (const:@var{m} @var{exp}) -Represents a constant that is the result of an assembly-time -arithmetic computation. The operand, @var{exp}, is an expression that -contains only constants (@code{const_int}, @code{symbol_ref} and -@code{label_ref} expressions) combined with @code{plus} and -@code{minus}. However, not all combinations are valid, since the -assembler cannot do arbitrary arithmetic on relocatable symbols. +Wraps an rtx computation @var{exp} whose inputs and result do not +change during the execution of a thread. There are two valid uses. +The first is to represent a global or thread-local address calculation. +In this case @var{exp} should contain @code{const_int}, +@code{symbol_ref}, @code{label_ref} or @code{unspec} expressions, +combined with @code{plus} and @code{minus}. Any such @code{unspec}s +are target-specific and typically represent some form of relocation +operator. @var{m} should be a valid address mode. -@var{m} should be @code{Pmode}. +The second use of @code{const} is to wrap a vector operation. +In this case @var{exp} must be a @code{vec_duplicate} expression. @findex high @item (high:@var{m} @var{exp}) Index: gcc/common.md =================================================================== --- gcc/common.md 2017-09-23 10:00:32.162585322 +0100 +++ gcc/common.md 2017-09-23 10:00:32.351313708 +0100 @@ -80,14 +80,14 @@ (define_constraint "n" (define_constraint "E" "Matches a floating-point constant." (ior (match_test "CONST_DOUBLE_AS_FLOAT_P (op)") - (match_test "GET_CODE (op) == CONST_VECTOR + (match_test "CONSTANT_P (op) && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT"))) ;; There is no longer a distinction between "E" and "F". (define_constraint "F" "Matches a floating-point constant." (ior (match_test "CONST_DOUBLE_AS_FLOAT_P (op)") - (match_test "GET_CODE (op) == CONST_VECTOR + (match_test "CONSTANT_P (op) && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT"))) (define_constraint "X" Index: gcc/emit-rtl.c =================================================================== --- gcc/emit-rtl.c 2017-09-23 10:00:32.162585322 +0100 +++ gcc/emit-rtl.c 2017-09-23 10:00:32.352266882 +0100 @@ -1470,7 +1470,7 @@ gen_lowpart_common (machine_mode mode, r return gen_rtx_fmt_e (GET_CODE (x), int_mode, XEXP (x, 0)); } else if (GET_CODE (x) == SUBREG || REG_P (x) - || GET_CODE (x) == CONCAT || GET_CODE (x) == CONST_VECTOR + || GET_CODE (x) == CONCAT || const_vec_p (x) || CONST_DOUBLE_AS_FLOAT_P (x) || CONST_SCALAR_INT_P (x)) return lowpart_subreg (mode, x, innermode); Index: gcc/expmed.c =================================================================== --- gcc/expmed.c 2017-09-23 10:00:32.162585322 +0100 +++ gcc/expmed.c 2017-09-23 10:00:32.352266882 +0100 @@ -5246,7 +5246,15 @@ make_tree (tree type, rtx x) return fold_convert (type, make_tree (t, XEXP (x, 0))); case CONST: - return make_tree (type, XEXP (x, 0)); + { + rtx op = XEXP (x, 0); + if (GET_CODE (op) == VEC_DUPLICATE) + { + tree elt_tree = make_tree (TREE_TYPE (type), XEXP (op, 0)); + return build_vector_from_val (type, elt_tree); + } + return make_tree (type, op); + } case SYMBOL_REF: t = SYMBOL_REF_DECL (x); Index: gcc/expr.c =================================================================== --- gcc/expr.c 2017-09-23 10:00:32.162585322 +0100 +++ gcc/expr.c 2017-09-23 10:00:32.353220056 +0100 @@ -9426,7 +9426,7 @@ #define REDUCE_BIT_FIELD(expr) (reduce_b /* Careful here: if the target doesn't support integral vector modes, a constant selection vector could wind up smooshed into a normal integral constant. */ - if (CONSTANT_P (op2) && GET_CODE (op2) != CONST_VECTOR) + if (CONSTANT_P (op2) && !VECTOR_MODE_P (GET_MODE (op2))) { tree sel_type = TREE_TYPE (treeop2); machine_mode vmode Index: gcc/rtl.h =================================================================== --- gcc/rtl.h 2017-09-23 10:00:32.162585322 +0100 +++ gcc/rtl.h 2017-09-23 10:00:32.354173229 +0100 @@ -2749,12 +2749,22 @@ extern rtx shallow_copy_rtx (const_rtx C extern int rtx_equal_p (const_rtx, const_rtx); extern bool rtvec_all_equal_p (const_rtvec); +/* Return true if X is some form of vector constant. */ + +inline bool +const_vec_p (const_rtx x) +{ + return VECTOR_MODE_P (GET_MODE (x)) && CONSTANT_P (x); +} + /* Return true if X is a vector constant with a duplicated element value. */ inline bool const_vec_duplicate_p (const_rtx x) { - return GET_CODE (x) == CONST_VECTOR && rtvec_all_equal_p (XVEC (x, 0)); + return ((GET_CODE (x) == CONST_VECTOR && rtvec_all_equal_p (XVEC (x, 0))) + || (GET_CODE (x) == CONST + && GET_CODE (XEXP (x, 0)) == VEC_DUPLICATE)); } /* Return true if X is a vector constant with a duplicated element value. @@ -2764,11 +2774,16 @@ const_vec_duplicate_p (const_rtx x) inline bool const_vec_duplicate_p (T x, T *elt) { - if (const_vec_duplicate_p (x)) + if (GET_CODE (x) == CONST_VECTOR && rtvec_all_equal_p (XVEC (x, 0))) { *elt = CONST_VECTOR_ELT (x, 0); return true; } + if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == VEC_DUPLICATE) + { + *elt = XEXP (XEXP (x, 0), 0); + return true; + } return false; } @@ -2794,8 +2809,10 @@ vec_duplicate_p (T x, T *elt) inline T unwrap_const_vec_duplicate (T x) { - if (const_vec_duplicate_p (x)) - x = CONST_VECTOR_ELT (x, 0); + if (GET_CODE (x) == CONST_VECTOR && rtvec_all_equal_p (XVEC (x, 0))) + return CONST_VECTOR_ELT (x, 0); + if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == VEC_DUPLICATE) + return XEXP (XEXP (x, 0), 0); return x; }