From patchwork Wed Aug 23 10:49:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 110729 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp3938932qge; Wed, 23 Aug 2017 03:49:27 -0700 (PDT) X-Received: by 10.98.74.155 with SMTP id c27mr2339860pfj.126.1503485367665; Wed, 23 Aug 2017 03:49:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503485367; cv=none; d=google.com; s=arc-20160816; b=aGrr5oV17OousUsrYMYoXav4Cz27ZmHfeSXZdQr+ZFRB5SGtM5q1mRy6CTbIE+mT1W 4oAk8iqdu3RadsOQpeaMjqUHwJHDJQDvaD+VLUedODgxAtr8ivJYpaHjegr+I3FH4wGZ QjdU5hPY/YKpqUYsaOpdpo/mK9vnsvRdRwIZ3o+XwN9scZ3V/CWNswbfHT+CdDvOfGux VtWaotdWSqBfbl0KG02iwH3ZNFCeVnVz5dNKgQQ7CVdFZOre4L4mUY7ShedckS20mHeP jJq9kfYwdCkEVX/0xKFRZAMDgQn2LQoW3NhWPTD2IWteACZiraRubfWD43m9ZTb1ragh OA7w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:user-agent:message-id:date:subject:mail-followup-to:to :from:delivered-to:sender:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=N9eA3uVk96C0iF2uJV6LCYdw5c4AcM4C6pi9absy9hQ=; b=aPrAVvr9CS+sLbR3zLpnZeHBSw365sQPWtvcawJjjDk8OyiIdGdMOusLHOsmPzQJ1/ ZjNyKPOZCay+1CEep7+4Bi+7AqBMmCwX+fJYayguebZd91gi1q4HmLZHCvgU2seZvREJ /UOH6lsAreHc9Mgrskmne26gL/t5f7gBwtHTcJYp2R9ASa7u1FNN61MaEAI69hxBTQ8C KjKZEZTW72HTf0O8UewLLxkpbpGbqgwUd3p5qUCIe6g3GbNH8ord4/8xqwdNyLYfBULJ 8xPVVOL9/QdqP1E3PVRgR5KCGTBTwDF9BjV/vF3tf3SWPIWSGNd9j2l2WnP5ni471K4y vTkg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=aD/VArkN; spf=pass (google.com: domain of gcc-patches-return-460782-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-460782-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id g3si848919pfj.676.2017.08.23.03.49.27 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 Aug 2017 03:49:27 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-460782-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=aD/VArkN; spf=pass (google.com: domain of gcc-patches-return-460782-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-460782-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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=e/dDHvX/d2dUSse88zm8zJnQEnGCroG010iUOuLIorEHpIWr3cMid q8qiBsAEipnZvse60n8aHYYfkDse7vYHdeQq/ZG4VBRBSGLL5UQmercWUTG5D/4J zW9FvMsq/97mmKIatf1Mu5wA08s2qzQodywyKKxrsxTxVNTpRrtOEY= 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=aLGJIiWgoRCGpfpPqSKmQuIGFng=; b=aD/VArkNHGv5HTbFrwnF uhMn3jCfdssfsyeSl7dfInLlrNV5C6aTiEPgkCYp/x8Ni2f2amlBdV6HtEIL4tZ9 TQqpSFsF9+0hKyd1yasQk7s8VWVoh7A5Y5yyU4SxFBMip233uX2t9qqS34exxjOh kzTFfEZ9HhbM8scf4LnFPPk= Received: (qmail 124137 invoked by alias); 23 Aug 2017 10:49:12 -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 124109 invoked by uid 89); 23 Aug 2017 10:49:11 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy=significance, emphasis X-HELO: mail-wr0-f180.google.com Received: from mail-wr0-f180.google.com (HELO mail-wr0-f180.google.com) (209.85.128.180) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 23 Aug 2017 10:49:09 +0000 Received: by mail-wr0-f180.google.com with SMTP id p8so4284832wrf.5 for ; Wed, 23 Aug 2017 03:49:08 -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=N9eA3uVk96C0iF2uJV6LCYdw5c4AcM4C6pi9absy9hQ=; b=Wccdf1cxWmcXHLc+O/rk0pTtQ4LtgZVHbH04ZmIZs0fz87iSJtJvSv59y7D6oTRhfF xXRWD+xnGN2gXBEBqCruim1WsVir55/MSyRnQKv4NurutyAUWwKedjc6GwfoaVeMMY1o RWCLs4USCBl9LbirM9HsQJRIIBexvWzaePjo9w2J+3oCePl+9M3bL6yaqJ2RUPNqvqAf geTUpxVqAaiCz9eUvpMIkBByPfJiQMPrqZjSN9306Ek2WsKtE1N8ncSuU8TKhjXZTVQ/ kZNGVJlmk+/z1g8jDXdL3dBHTswOOVZzzxHb7WyYp6sSB2uqS3qTpw+tvasxe1tUErig 75pw== X-Gm-Message-State: AHYfb5jVKj8FBl9A3T8AXsZ3TpTYDbmZoGGuSt1H6w5fS38FmD4eOCA7 wT3NuIit1LL75998FVsu/w== X-Received: by 10.223.138.165 with SMTP id y34mr1339478wry.209.1503485346519; Wed, 23 Aug 2017 03:49:06 -0700 (PDT) Received: from localhost (92.40.249.210.threembb.co.uk. [92.40.249.210]) by smtp.gmail.com with ESMTPSA id l3sm3014842wrc.4.2017.08.23.03.49.05 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 23 Aug 2017 03:49:05 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: Make more use of df_read_modify_subreg_p Date: Wed, 23 Aug 2017 11:49:03 +0100 Message-ID: <87a82qv9sw.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 This patch uses df_read_modify_subreg_p to check whether writing to a subreg would preserve some of the existing contents. This has the effect of putting more emphasis on the REGMODE_NATURAL_SIZE-based definition of whether something can be partially modified, instead of using UNITS_PER_WORD unconditionally. This becomes important for SVE, where UNITS_PER_WORD has no significance for subregs of multi-register LD2/ST2, LD3/ST3 and LD4/ST4 tuples. Tested on aarch64-linux-gnu and x86_64-linux-gnu, and by making sure that there were no differences in testsuite assembly output for one target per CPU. OK to install? Richard 2017-08-23 Richard Sandiford Alan Hayward David Sherwood gcc/ * df.h (df_read_modify_subreg_p): Take a const_rtx. * df-scan.c (df_read_modify_subreg_p): Likewise. * caller-save.c (mark_referenced_regs): Use dr_read_modify_subreg_p. * combine.c (find_single_use_1): Likewise. (expand_field_assignment): Likewise. (move_deaths): Likewise. * lra-constraints.c (simplify_operand_subreg): Likewise. (curr_insn_transform): Likewise. * lra.c (collect_non_operand_hard_regs): Likewise. (add_regs_to_insn_regno_info): Likewise. * rtlanal.c (reg_referenced_p): Likewise. (covers_regno_no_parallel_p): Likewise. Index: gcc/df.h =================================================================== --- gcc/df.h 2017-05-18 07:51:11.853804033 +0100 +++ gcc/df.h 2017-08-23 10:44:56.294480753 +0100 @@ -1080,7 +1080,7 @@ extern unsigned int df_hard_reg_used_cou extern bool df_regs_ever_live_p (unsigned int); extern void df_set_regs_ever_live (unsigned int, bool); extern void df_compute_regs_ever_live (bool); -extern bool df_read_modify_subreg_p (rtx); +extern bool df_read_modify_subreg_p (const_rtx); extern void df_scan_verify (void); Index: gcc/df-scan.c =================================================================== --- gcc/df-scan.c 2017-08-21 15:49:31.653164829 +0100 +++ gcc/df-scan.c 2017-08-23 10:44:56.294480753 +0100 @@ -2629,7 +2629,7 @@ df_ref_record (enum df_ref_class cl, This function returns true iff the SUBREG X is such a SUBREG. */ bool -df_read_modify_subreg_p (rtx x) +df_read_modify_subreg_p (const_rtx x) { unsigned int isize, osize; if (GET_CODE (x) != SUBREG) Index: gcc/caller-save.c =================================================================== --- gcc/caller-save.c 2017-08-21 15:49:31.653164829 +0100 +++ gcc/caller-save.c 2017-08-23 10:44:56.292488492 +0100 @@ -1034,10 +1034,7 @@ mark_referenced_regs (rtx *loc, refmarke /* If we're setting only part of a multi-word register, we shall mark it as referenced, because the words that are not being set should be restored. */ - && ((GET_MODE_SIZE (GET_MODE (*loc)) - >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (*loc)))) - || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (*loc))) - <= UNITS_PER_WORD)))) + && !df_read_modify_subreg_p (*loc))) return; } if (code == MEM || code == SUBREG) Index: gcc/combine.c =================================================================== --- gcc/combine.c 2017-08-23 10:44:17.183477418 +0100 +++ gcc/combine.c 2017-08-23 10:44:56.293484623 +0100 @@ -579,10 +579,7 @@ find_single_use_1 (rtx dest, rtx *loc) && !REG_P (SET_DEST (x)) && ! (GET_CODE (SET_DEST (x)) == SUBREG && REG_P (SUBREG_REG (SET_DEST (x))) - && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x)))) - + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) - == ((GET_MODE_SIZE (GET_MODE (SET_DEST (x))) - + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))) + && !df_read_modify_subreg_p (SET_DEST (x)))) break; return find_single_use_1 (dest, &SET_SRC (x)); @@ -7279,15 +7276,12 @@ expand_field_assignment (const_rtx x) } } - /* A SUBREG between two modes that occupy the same numbers of words - can be done by moving the SUBREG to the source. */ + /* If the destination is a subreg that overwrites the whole of the inner + register, we can move the subreg to the source. */ else if (GET_CODE (SET_DEST (x)) == SUBREG /* We need SUBREGs to compute nonzero_bits properly. */ && nonzero_sign_valid - && (((GET_MODE_SIZE (GET_MODE (SET_DEST (x))) - + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) - == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x)))) - + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))) + && !df_read_modify_subreg_p (SET_DEST (x))) { x = gen_rtx_SET (SUBREG_REG (SET_DEST (x)), gen_lowpart @@ -13838,10 +13832,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, if (GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == STRICT_LOW_PART || (GET_CODE (dest) == SUBREG - && (((GET_MODE_SIZE (GET_MODE (dest)) - + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) - + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))) + && !df_read_modify_subreg_p (dest))) { move_deaths (dest, maybe_kill_insn, from_luid, to_insn, pnotes); return; Index: gcc/lra-constraints.c =================================================================== --- gcc/lra-constraints.c 2017-08-22 17:14:30.337866206 +0100 +++ gcc/lra-constraints.c 2017-08-23 10:44:56.295476884 +0100 @@ -1680,7 +1680,7 @@ simplify_operand_subreg (int nop, machin bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg)); insert_before = (type != OP_OUT - || GET_MODE_SIZE (innermode) > GET_MODE_SIZE (mode)); + || df_read_modify_subreg_p (operand)); insert_after = (type != OP_IN); insert_move_for_subreg (insert_before ? &before : NULL, insert_after ? &after : NULL, @@ -4244,9 +4244,7 @@ curr_insn_transform (bool check_only_p) constraints. */ if (type == OP_OUT && (curr_static_id->operand[i].strict_low - || (GET_MODE_SIZE (GET_MODE (reg)) > UNITS_PER_WORD - && (GET_MODE_SIZE (mode) - < GET_MODE_SIZE (GET_MODE (reg)))))) + || df_read_modify_subreg_p (*loc))) type = OP_INOUT; loc = &SUBREG_REG (*loc); mode = GET_MODE (*loc); Index: gcc/lra.c =================================================================== --- gcc/lra.c 2017-08-21 15:49:31.652164829 +0100 +++ gcc/lra.c 2017-08-23 10:44:56.295476884 +0100 @@ -831,14 +831,12 @@ collect_non_operand_hard_regs (rtx *x, l subreg_p = false; if (code == SUBREG) { + if (df_read_modify_subreg_p (op)) + subreg_p = true; op = SUBREG_REG (op); code = GET_CODE (op); if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (op))) - { - mode = GET_MODE (op); - if (GET_MODE_SIZE (mode) > REGMODE_NATURAL_SIZE (mode)) - subreg_p = true; - } + mode = GET_MODE (op); } if (REG_P (op)) { @@ -1428,14 +1426,12 @@ add_regs_to_insn_regno_info (lra_insn_re subreg_p = false; if (GET_CODE (x) == SUBREG) { + if (df_read_modify_subreg_p (x)) + subreg_p = true; x = SUBREG_REG (x); code = GET_CODE (x); if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x))) - { - mode = GET_MODE (x); - if (GET_MODE_SIZE (mode) > REGMODE_NATURAL_SIZE (mode)) - subreg_p = true; - } + mode = GET_MODE (x); } if (REG_P (x)) { Index: gcc/rtlanal.c =================================================================== --- gcc/rtlanal.c 2017-08-23 10:44:17.187477282 +0100 +++ gcc/rtlanal.c 2017-08-23 10:44:56.296473014 +0100 @@ -1123,10 +1123,7 @@ reg_referenced_p (const_rtx x, const_rtx && !REG_P (SET_DEST (body)) && ! (GET_CODE (SET_DEST (body)) == SUBREG && REG_P (SUBREG_REG (SET_DEST (body))) - && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (body)))) - + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) - == ((GET_MODE_SIZE (GET_MODE (SET_DEST (body))) - + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))) + && !df_read_modify_subreg_p (SET_DEST (body))) && reg_overlap_mentioned_p (x, SET_DEST (body))) return 1; return 0; @@ -1999,20 +1996,16 @@ dead_or_set_p (const rtx_insn *insn, con return 1; } -/* Return TRUE iff DEST is a register or subreg of a register and - doesn't change the number of words of the inner register, and any - part of the register is TEST_REGNO. */ +/* Return TRUE iff DEST is a register or subreg of a register, is a + complete rather than read-modify-write destination, and contains + register TEST_REGNO. */ static bool covers_regno_no_parallel_p (const_rtx dest, unsigned int test_regno) { unsigned int regno, endregno; - if (GET_CODE (dest) == SUBREG - && (((GET_MODE_SIZE (GET_MODE (dest)) - + UNITS_PER_WORD - 1) / UNITS_PER_WORD) - == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) - + UNITS_PER_WORD - 1) / UNITS_PER_WORD))) + if (GET_CODE (dest) == SUBREG && !df_read_modify_subreg_p (dest)) dest = SUBREG_REG (dest); if (!REG_P (dest))