From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 314 invoked by alias); 15 Aug 2014 05:16:06 -0000 Mailing-List: contact gcc-help-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-help-owner@gcc.gnu.org Received: (qmail 300 invoked by uid 89); 15 Aug 2014 05:16:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 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 (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 15 Aug 2014 05:16:02 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s7F5G0uV003573 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 15 Aug 2014 01:16:00 -0400 Received: from stumpy.slc.redhat.com (ovpn-113-24.phx2.redhat.com [10.3.113.24]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s7F5Fwj4004282; Fri, 15 Aug 2014 01:15:59 -0400 Message-ID: <53ED978E.4050300@redhat.com> Date: Fri, 15 Aug 2014 05:16:00 -0000 From: Jeff Law User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.7.0 MIME-Version: 1.0 To: Cherry Vanc , gcc-help@gcc.gnu.org Subject: Re: help with fusing multiple dependent ops in gcc combine pass References: In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2014-08/txt/msg00108.txt.bz2 On 08/14/14 19:21, Cherry Vanc wrote: > I received very helpful comments previously > (https://gcc.gnu.org/ml/gcc-help/2014-08/msg00010.html). And I could > successfully fuse dependent ops like following : > > ... > r1 = (r1) op1 (const) > ... > ... > r1 = (r1) op2 (r2) > ... > ... > r3 = op3 (r1) > ... > > using a define_insn pattern to a new op "testnew36". > > Now, How can I fuse the following stream of ops : > > ... > op1 > ... > op2 (consumes result of op1) > ... > op3 (consumes result of op2) > ... > op4 (consumes result of op2) > ... > > to the following : > > ... > testnew36 > ... > testnew40 > > The pertinent pattern seen in .combine file is a parallel expression : > > (parallel [ > (set (reg:DI 256 [ *_15 ]) > (op3:DI (op2:DI (op1:DI (reg:DI 202 [ D.1563 ]) > (const_int 4 [0x4])) > (reg:DI 242 [ inbuf ])) )) > (set (reg:DI 205 [ D.1566 ]) > (op2:DI (op1:DI (reg:DI 202 [ D.1563 ]) > (const_int 4 [0x4])) > (reg:DI 242 [ inbuf ]))) > ]) If you see a PARALLEL, then it means that one of the output operands in the original series of insns is used later. Thus that side effect must be preserved. In the example above, you'll find uses of regs 256 and 205. PARALLELs are typically far less useful because targets typically don't have many instructions that produce multiple outputs. Typically when a PARALLEL is generated, you're going to be outputting multiple instructions for the PARALLEL. In that case you're better off using a define_insn_and_split. You can find many examples in the various MD files distributed with GCC. If all the intermediate destinations die when they are consumed, then the combiner will not need to preserve the side effects and thus won't generate a PARALLEL and you would implement that as a simple define_insn in the machine description. Again, you can find many examples of patterns for the combiner in the various MD files included in GCC. Jeff