From patchwork Wed Mar 15 15:00:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Schmidt X-Patchwork-Id: 739300 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3vjvtb2k05z9ryZ for ; Thu, 16 Mar 2017 02:00:54 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="Qh8WGYCk"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:from:message-id:date:mime-version :in-reply-to:content-type; q=dns; s=default; b=nsYXqvF2OsrwjtdwX QnPOpXV58M7mTDtntw9CMI5z+1sHRtIxzWoN7FxyuJYj9sSbOatJCgaOhU1pDfXw fRoLhDg8xMCdsMuxW0vxA4+i6R8hrIehpBvp8B92BPTnMp9v7QibSdoRLBiCEQVL lcbWi785S3m28+mLsDkC2IERAQ= 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 :subject:to:references:from:message-id:date:mime-version :in-reply-to:content-type; s=default; bh=Zd77n4X1sPrbCQG5+8zNkeN ENm8=; b=Qh8WGYCkXADbn2lp9j5AFPNPSM47WIRtG8torXDdmTSm0Puu6P1OuK+ 6ks8qc8BhOMkW0FS1n9WZbsjq7YkkdTIVoMzF7+qUMozsZGtme/Mp7ev0uWdJbga kc6AYhOzEqtpKbHVwx3FIBdEzR2unGTsvrwltYOR5oiCHpaX6DBs= Received: (qmail 118825 invoked by alias); 15 Mar 2017 15:00:45 -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 118700 invoked by uid 89); 15 Mar 2017 15:00:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.9 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=sk:distrib X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 15 Mar 2017 15:00:31 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BEA8E81244 for ; Wed, 15 Mar 2017 15:00:23 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com BEA8E81244 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=bschmidt@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com BEA8E81244 Received: from localhost.localdomain (ovpn-117-181.ams2.redhat.com [10.36.117.181]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v2FF0Mno032341; Wed, 15 Mar 2017 11:00:22 -0400 Subject: Re: Combiner fix for PR79910 To: Jeff Law , GCC Patches References: <15d38062-fd33-7de7-5bba-79f17adefc65@redhat.com> <5c9df1bf-65b3-c5bc-c350-f82466c3659b@redhat.com> From: Bernd Schmidt Message-ID: <95129f0b-df37-a90f-af88-3d2392b88be4@redhat.com> Date: Wed, 15 Mar 2017 16:00:21 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.7.0 MIME-Version: 1.0 In-Reply-To: <5c9df1bf-65b3-c5bc-c350-f82466c3659b@redhat.com> X-IsSubscribed: yes On 03/15/2017 12:09 AM, Bernd Schmidt wrote: > I'll retest with your > suggestion and with the bitmap creation conditional on i1 being nonnull. Like this (also had to throw in a bitmap_empty_p). Retested as before. Ok? Bernd Index: gcc/combine.c =================================================================== --- gcc/combine.c (revision 245685) +++ gcc/combine.c (working copy) @@ -104,6 +104,7 @@ along with GCC; see the file COPYING3. #include "valtrack.h" #include "rtl-iter.h" #include "print-rtl.h" +#include "dbgcnt.h" /* Number of attempts to combine instructions in this function. */ @@ -2559,6 +2560,57 @@ can_split_parallel_of_n_reg_sets (rtx_in return true; } +/* Set up a set of registers used in an insn. Called through note_uses, + arguments as described for that function. */ + +static void +record_used_regs (rtx *xptr, void *data) +{ + bitmap set = (bitmap)data; + int i, j; + enum rtx_code code; + const char *fmt; + rtx x = *xptr; + + /* repeat is used to turn tail-recursion into iteration since GCC + can't do it when there's no return value. */ + repeat: + if (x == 0) + return; + + code = GET_CODE (x); + if (REG_P (x)) + { + unsigned regno = REGNO (x); + unsigned end_regno = END_REGNO (x); + while (regno < end_regno) + bitmap_set_bit (set, regno++); + return; + } + + /* Recursively scan the operands of this expression. */ + + for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--) + { + if (fmt[i] == 'e') + { + /* If we are about to do the last recursive call + needed at this level, change it into iteration. + This function is called enough to be worth it. */ + if (i == 0) + { + x = XEXP (x, 0); + goto repeat; + } + + record_used_regs (&XEXP (x, i), data); + } + else if (fmt[i] == 'E') + for (j = 0; j < XVECLEN (x, i); j++) + record_used_regs (&XVECEXP (x, i, j), data); + } +} + /* Try to combine the insns I0, I1 and I2 into I3. Here I0, I1 and I2 appear earlier than I3. I0 and I1 can be zero; then we combine just I2 into I3, or I1 and I2 into @@ -2742,6 +2794,27 @@ try_combine (rtx_insn *i3, rtx_insn *i2, added_links_insn = 0; + /* For combinations that may result in two insns, we have to gather + some extra information about registers used, so that we can + update all relevant LOG_LINKS later. */ + auto_bitmap i2_regset, i3_regset, links_regset; + if (i1) + { + note_uses (&PATTERN (i2), record_used_regs, (bitmap)i2_regset); + note_uses (&PATTERN (i3), record_used_regs, (bitmap)i3_regset); + insn_link *ll; + FOR_EACH_LOG_LINK (ll, i3) + bitmap_set_bit (links_regset, ll->regno); + FOR_EACH_LOG_LINK (ll, i2) + bitmap_set_bit (links_regset, ll->regno); + if (i1) + FOR_EACH_LOG_LINK (ll, i1) + bitmap_set_bit (links_regset, ll->regno); + if (i0) + FOR_EACH_LOG_LINK (ll, i0) + bitmap_set_bit (links_regset, ll->regno); + } + /* First check for one important special case that the code below will not handle. Namely, the case where I1 is zero, I2 is a PARALLEL and I3 is a SET whose SET_SRC is a SET_DEST in I2. In that case, @@ -4004,6 +4077,12 @@ try_combine (rtx_insn *i3, rtx_insn *i2, } } + if (!dbg_cnt (combine)) + { + undo_all (); + return 0; + } + /* If it still isn't recognized, fail and change things back the way they were. */ if ((insn_code_number < 0 @@ -4051,6 +4130,33 @@ try_combine (rtx_insn *i3, rtx_insn *i2, return 0; } + auto_bitmap new_regs_in_i2; + if (newi2pat) + { + /* We need to discover situations where we introduce a use of a + register into I2, where none of the existing LOG_LINKS contain + a reference to it. This can happen if previously I3 referenced + the reg, and there is an additional use between I2 and I3. We + must remove the LOG_LINKS entry from that additional use and + distribute it along with our own ones. */ + note_uses (&newi2pat, record_used_regs, (bitmap)new_regs_in_i2); + bitmap_and_compl_into (new_regs_in_i2, i2_regset); + bitmap_and_compl_into (new_regs_in_i2, links_regset); + + /* Here, we first look for situations where a hard register use + moved, and just give up. This should happen approximately + never, and it's not worth it to deal with possibilities like + multi-word registers. Later, when fixing up LOG_LINKS, we + deal with the case where a pseudo use moved. */ + if (!bitmap_empty_p (new_regs_in_i2) + && prev_nonnote_insn (i3) != i2 + && bitmap_first_set_bit (new_regs_in_i2) < FIRST_PSEUDO_REGISTER) + { + undo_all (); + return 0; + } + } + if (MAY_HAVE_DEBUG_INSNS) { struct undo *undo; @@ -4494,6 +4600,45 @@ try_combine (rtx_insn *i3, rtx_insn *i2, NULL_RTX, NULL_RTX, NULL_RTX); } + if (newi2pat) + { + bitmap_iterator iter; + unsigned int i; + + /* See comments above where we calculate the bitmap. */ + EXECUTE_IF_SET_IN_BITMAP ((bitmap)new_regs_in_i2, + LAST_VIRTUAL_REGISTER, i, iter) + { + rtx reg = regno_reg_rtx[i]; + rtx_insn *other; + for (other = NEXT_INSN (i2); other != i3; other = NEXT_INSN (other)) + if (NONDEBUG_INSN_P (other) + && (reg_overlap_mentioned_p (reg, PATTERN (other)) + || (CALL_P (other) && find_reg_fusage (other, USE, reg)))) + { + if (dump_file) + fprintf (dump_file, + "found extra use of reg %d at insn %d\n", i, + INSN_UID (other)); + insn_link **plink; + for (plink = &LOG_LINKS (other); + *plink; + plink = &(*plink)->next) + { + insn_link *link = *plink; + if (link->regno == i) + { + *plink = link->next; + link->next = i3links; + i3links = link; + break; + } + } + break; + } + } + } + distribute_links (i3links); distribute_links (i2links); distribute_links (i1links);