From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14229 invoked by alias); 3 Aug 2007 14:34:39 -0000 Received: (qmail 14215 invoked by uid 22791); 3 Aug 2007 14:34:36 -0000 X-Spam-Check-By: sourceware.org Received: from mtagate5.de.ibm.com (HELO mtagate5.de.ibm.com) (195.212.29.154) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 03 Aug 2007 14:34:31 +0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate5.de.ibm.com (8.13.8/8.13.8) with ESMTP id l73EYSaC366516 for ; Fri, 3 Aug 2007 14:34:28 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.13.8/8.13.8/NCO v8.4) with ESMTP id l73EYSv71724460 for ; Fri, 3 Aug 2007 16:34:28 +0200 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id l73EYOaS011556 for ; Fri, 3 Aug 2007 16:34:24 +0200 Received: from blc4eb430604175.ibm.com (dyn-9-152-216-52.boeblingen.de.ibm.com [9.152.216.52]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.12.11) with SMTP id l73EYOZI011553; Fri, 3 Aug 2007 16:34:24 +0200 Received: by blc4eb430604175.ibm.com (sSMTP sendmail emulation); Fri, 3 Aug 2007 16:33:27 +0200 Date: Fri, 03 Aug 2007 14:34:00 -0000 From: Andreas Krebbel To: Rask Ingemann Lambertsen Cc: gcc-patches@gcc.gnu.org, matz@suse.de Subject: Re: [PATCH] lower-subreg: Decompose multiword shifts Message-ID: <20070803143327.GA14804@blc4eb430604175.ibm.com> References: <20070802153434.GA24953@blc4eb430604175.ibm.com> <20070802231609.GL25795@sygehus.dk> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20070802231609.GL25795@sygehus.dk> User-Agent: Mutt/1.4.1i Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2007-08/txt/msg00179.txt.bz2 Hello, as Michael already stated there are two superfluous register save/restore pairs. Both seem to have completely different causes. foo: pushl %ebp # 43 *pushsi2 [length = 1] movl %esp, %ebp # 44 *movsi_1/1 [length = 2] pushl %esi # 45 *pushsi2 [length = 1] pushl %ebx # 46 *pushsi2 [length = 1] movl 12(%ebp), %eax # 39 *movsi_1/1 [length = 3] popl %ebx # 49 popsi1 [length = 1] movl 8(%ebp), %ecx # 41 *movsi_1/1 [length = 3] popl %esi # 50 popsi1 [length = 1] leave # 51 leave [length = 1] movl %ecx, %edx # 36 *movsi_1/1 [length = 2] ret # 52 return_internal [length = 1] %esi: With and without my patch lower subreg decomposes the following clobber insn: (insn 12 9 10 2 t.c:6 (clobber (reg:DI 61)) -1 (expr_list:REG_LIBCALL_ID (const_int 0 [0x0]) (insn_list:REG_LIBCALL 13 (nil)))) into: (insn 12 29 30 2 t.c:6 (clobber (reg:SI 67)) -1 (expr_list:REG_LIBCALL_ID (const_int 0 [0x0]) (nil))) (insn 30 12 10 2 t.c:6 (clobber (reg:SI 68 [+4 ])) -1 (nil)) Also the REG_LIBCALL note and the respective REG_RETVAL notes are removed. But only one of the resulting INSN has a REG_LIBCALL_ID note afterwards. DCE seem to care about these notes when deleting insns. After cse1 only the second clobber is deleted (insn 30). The difference with my patch is that *all* other insns of that libcall can be deleted by fwprop. So only insn 12 is left from the libcall and unfortunately stays until reload which assigns si to pseudo 67. I've tried to copy the REG_LIBCALL_ID note to the second clobber in lower subreg and was hoping that DCE then would be able to remove the libcall block as a whole but this didn't work. But since this clobber is probably just issued to make it explicit that the whole multiword register is written by the libcall I think after decomposing that multiword register we can safely remove the clobber insn anyway - right?! The following patch does this what makes the pushl %esi/popl %esi pair to disappear in the example above. Index: gcc/lower-subreg.c =================================================================== *** gcc/lower-subreg.c.orig 2007-08-03 12:38:10.000000000 +0200 --- gcc/lower-subreg.c 2007-08-03 14:05:16.000000000 +0200 *************** resolve_clobber (rtx pat, rtx insn) *** 900,910 **** --- 900,918 ---- enum machine_mode orig_mode; unsigned int words, i; int ret; + rtx reg_libcall_id_note; reg = XEXP (pat, 0); if (!resolve_reg_p (reg) && !resolve_subreg_p (reg)) return false; + reg_libcall_id_note = find_reg_note (insn, REG_LIBCALL_ID, NULL_RTX); + if (resolve_reg_p (reg) && reg_libcall_id_note != NULL_RTX) + { + delete_insn (insn); + return true; + } + orig_mode = GET_MODE (reg); words = GET_MODE_SIZE (orig_mode); words = (words + UNITS_PER_WORD - 1) / UNITS_PER_WORD; %ebx: After reload the following two insns exist: (insn:HI 7 4 8 2 t.c:6 (parallel [ (set (reg:DI 0 ax [orig:62 low ] [62]) (zero_extend:DI (mem/c/i:SI (plus:SI (reg/f:SI 6 bp) (const_int 12 [0xc])) [2 low+0 S4 A32]))) (clobber (reg:CC 17 flags)) ]) 112 {zero_extendsidi2_32} (nil)) (insn:HI 8 7 35 2 t.c:6 (parallel [ (set (reg:DI 2 cx [orig:63 high ] [63]) (zero_extend:DI (mem/c/i:SI (plus:SI (reg/f:SI 6 bp) (const_int 8 [0x8])) [2 high+0 S4 A32]))) (clobber (reg:CC 17 flags)) ]) 112 {zero_extendsidi2_32} (nil)) Both gets split: (insn 39 4 40 2 t.c:6 (set (reg:SI 0 ax [orig:62 low ] [62]) (mem/c/i:SI (plus:SI (reg/f:SI 6 bp) (const_int 12 [0xc])) [2 low+0 S4 A32])) 40 {*movsi_1} (nil)) (insn 40 39 41 2 t.c:6 (set (reg:SI 1 dx [ low+4 ]) (const_int 0 [0x0])) 40 {*movsi_1} (nil)) (insn 41 40 42 2 t.c:6 (set (reg:SI 2 cx [orig:63 high ] [63]) (mem/c/i:SI (plus:SI (reg/f:SI 6 bp) (const_int 8 [0x8])) [2 high+0 S4 A32])) 40 {*movsi_1} (nil)) (insn 42 41 36 2 t.c:6 (set (reg:SI 3 bx [ high+4 ]) (const_int 0 [0x0])) 40 {*movsi_1} (nil)) And *directly* afterwards the prologue and epilogue generation pass runs. The problem seems to be that we are running the pass generating the register save/restore instructions directly after a pass which might (and in this case does) generate dead code. I think this problem would disappear with an intermediate DCE step in between the split pass and prologue/epilogue generation. 187 dce finally removes insns 40 and 42 but the pushl/popl insns are already generated: (insn 39 4 41 2 t.c:6 (set (reg:SI 0 ax [orig:62 low ] [62]) (mem/c/i:SI (plus:SI (reg/f:SI 6 bp) (const_int 12 [0xc])) [2 low+0 S4 A32])) 40 {*movsi_1} (nil)) (insn 41 39 36 2 t.c:6 (set (reg:SI 2 cx [orig:63 high ] [63]) (mem/c/i:SI (plus:SI (reg/f:SI 6 bp) (const_int 8 [0x8])) [2 high+0 S4 A32])) 40 {*movsi_1} (nil)) Bye, -Andreas-