From patchwork Fri Aug 20 13:50:46 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 62279 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]) by ozlabs.org (Postfix) with SMTP id 24D4DB70EF for ; Fri, 20 Aug 2010 23:50:55 +1000 (EST) Received: (qmail 22857 invoked by alias); 20 Aug 2010 13:50:53 -0000 Received: (qmail 22747 invoked by uid 22791); 20 Aug 2010 13:50:51 -0000 X-SWARE-Spam-Status: No, hits=-6.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 20 Aug 2010 13:50:45 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o7KDoKc3002906 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 20 Aug 2010 09:50:26 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [10.16.42.4]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o7KDoJoe028308 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 20 Aug 2010 09:50:20 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [127.0.0.1]) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4) with ESMTP id o7KDokWK004121; Fri, 20 Aug 2010 15:50:46 +0200 Received: (from jakub@localhost) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4/Submit) id o7KDokRU004119; Fri, 20 Aug 2010 15:50:46 +0200 Date: Fri, 20 Aug 2010 15:50:46 +0200 From: Jakub Jelinek To: Paolo Bonzini , Bernd Schmidt Cc: gcc-patches@gcc.gnu.org Subject: Re: [PATCH] Optimize nested SIGN_EXTENDs/ZERO_EXTENDs (PR target/45336) Message-ID: <20100820135046.GC702@tyan-ft48-01.lab.bos.redhat.com> Reply-To: Jakub Jelinek References: <20100819163330.GX702@tyan-ft48-01.lab.bos.redhat.com> <4C6E4F08.6070801@gnu.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <4C6E4F08.6070801@gnu.org> User-Agent: Mutt/1.5.20 (2009-12-10) X-IsSubscribed: yes 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 On Fri, Aug 20, 2010 at 11:46:48AM +0200, Paolo Bonzini wrote: > On 08/19/2010 06:33 PM, Jakub Jelinek wrote: > >+ /* (sign_extend:M (sign_extend:N)) is (sign_extend:M). */ > >+ if (GET_CODE (op) == SIGN_EXTEND) > >+ return simplify_gen_unary (SIGN_EXTEND, mode, XEXP (op, 0), > >+ GET_MODE (XEXP (op, 0))); > > Maybe > > /* (sign_extend:M (sign_extend:N)) is (sign_extend:M). > (sign_extend:M (zero_extend:N)) is (zero_extend:M). */ > if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND) > { > gcc_assert (GET_MODE (op) != mode); > return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0), > GET_MODE (XEXP (op, 0))); > } > > ? Good idea. On Thu, Aug 19, 2010 at 07:58:24PM +0200, Bernd Schmidt wrote: > > ZERO_EXTEND is expanded into AND instead of LSHIFTRT/ASHIFT by combine, > > and > > two nested ANDs should be easily optimized. If you really want, I can > > handle the ZERO_EXTEND (AND mask) case as a follow-up. > > Oh, in expand_compound_operation? I was thinking about finding such > shifts in a pair of insns (happens on Thumb). Also, what about callers > other than combine? Ok. The following patch thus adds optimization of sign_extend of zero_extend, sign_extend of lshiftrt/ashift and zero_extend of lshiftrt/ashift. Bootstrapped/regtested on x86_64-linux and i686-linux (yes,rtl checking) with additional patchlet to gather statistics and in both bootstraps/regtests together this optimization happened (the fact that simplify-rtx.c simplified it doesn't still mean the result was usable in whatever pass asked for it) times: (sign_extend (sign_extend)) 2059 (sign_extend (zero_extend)) 87019 (sign_extend (ashiftrt)) 1485 (zero_extend (zero_extend)) 15648 lshiftrt wasn't seen, but it is very well possible it shows up on other targets. Ok for trunk? 2010-08-20 Jakub Jelinek Paolo Bonzini * simplify-rtx.c (simplify_unary_operation_1): Optimize (sign_extend (zero_extend ()) and ({sign,zero}_extend (lshiftrt (ashift X (const_int I)) (const_int I))). Jakub --- gcc/simplify-rtx.c.jj 2010-08-20 12:33:30.000000000 +0200 +++ gcc/simplify-rtx.c 2010-08-20 13:11:15.000000000 +0200 @@ -1010,15 +1010,22 @@ simplify_unary_operation_1 (enum rtx_cod && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0)))) return rtl_hooks.gen_lowpart_no_emit (mode, op); - /* (sign_extend:M (sign_extend:N )) is (sign_extend:M ). */ - if (GET_CODE (op) == SIGN_EXTEND) - return simplify_gen_unary (SIGN_EXTEND, mode, XEXP (op, 0), - GET_MODE (XEXP (op, 0))); + /* (sign_extend:M (sign_extend:N )) is (sign_extend:M ). + (sign_extend:M (zero_extend:N )) is (zero_extend:M ). */ + if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND) + { + gcc_assert (GET_MODE_BITSIZE (mode) + > GET_MODE_BITSIZE (GET_MODE (op))); + return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0), + GET_MODE (XEXP (op, 0))); + } /* (sign_extend:M (ashiftrt:N (ashift (const_int I)) (const_int I))) is (sign_extend:M (subreg:O )) if there is mode with - GET_MODE_BITSIZE (N) - I bits. */ - if (GET_CODE (op) == ASHIFTRT + GET_MODE_BITSIZE (N) - I bits. + (sign_extend:M (lshiftrt:N (ashift (const_int I)) (const_int I))) + is similarly (zero_extend:M (subreg:O )). */ + if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT) && GET_CODE (XEXP (op, 0)) == ASHIFT && CONST_INT_P (XEXP (op, 1)) && XEXP (XEXP (op, 0), 1) == XEXP (op, 1) @@ -1027,11 +1034,15 @@ simplify_unary_operation_1 (enum rtx_cod enum machine_mode tmode = mode_for_size (GET_MODE_BITSIZE (GET_MODE (op)) - INTVAL (XEXP (op, 1)), MODE_INT, 1); + gcc_assert (GET_MODE_BITSIZE (mode) + > GET_MODE_BITSIZE (GET_MODE (op))); if (tmode != BLKmode) { rtx inner = rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0)); - return simplify_gen_unary (SIGN_EXTEND, mode, inner, tmode); + return simplify_gen_unary (GET_CODE (op) == ASHIFTRT + ? SIGN_EXTEND : ZERO_EXTEND, + mode, inner, tmode); } } @@ -1066,6 +1077,26 @@ simplify_unary_operation_1 (enum rtx_cod return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0), GET_MODE (XEXP (op, 0))); + /* (zero_extend:M (lshiftrt:N (ashift (const_int I)) (const_int I))) + is (zero_extend:M (subreg:O )) if there is mode with + GET_MODE_BITSIZE (N) - I bits. */ + if (GET_CODE (op) == LSHIFTRT + && GET_CODE (XEXP (op, 0)) == ASHIFT + && CONST_INT_P (XEXP (op, 1)) + && XEXP (XEXP (op, 0), 1) == XEXP (op, 1) + && GET_MODE_BITSIZE (GET_MODE (op)) > INTVAL (XEXP (op, 1))) + { + enum machine_mode tmode + = mode_for_size (GET_MODE_BITSIZE (GET_MODE (op)) + - INTVAL (XEXP (op, 1)), MODE_INT, 1); + if (tmode != BLKmode) + { + rtx inner = + rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0)); + return simplify_gen_unary (ZERO_EXTEND, mode, inner, tmode); + } + } + #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend) /* As we do not know which address space the pointer is refering to, we can do this only if the target does not support different pointer