From patchwork Tue May 15 13:08:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 159317 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 3EA7CB6FB4 for ; Tue, 15 May 2012 23:08:45 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1337692126; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:From:To:Mail-Followup-To:Cc:Subject:References:Date: In-Reply-To:Message-ID:User-Agent:MIME-Version:Content-Type: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=GZa0p58gHMSPKk+GAPJL yGBeTxo=; b=hj8uufAYH8Dfuo/p11CgurrUuIAxY8AqxX9GE//3R0fNlXVRG6IN YImGubqsfCk49e0sqgGdYi4cE7PsOo8bmV0el0xw0hNtvIZwQ30YaAONv3TPay5V kUTr4M/9vhQ2aNQWPwEHYbgMC833Y1aLaiNg4tIfrsBvI5yXCyz74v8= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:From:To:Mail-Followup-To:Cc:Subject:References:Date:In-Reply-To:Message-ID:User-Agent:MIME-Version:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=i3AWw/EazxV1rM9tVh6I1Zs3JnIb+2UwKcgVNSuqP9Yl3m/RKxYiOSgYTACAhm /XXTdhg+/bHG2HD1/VOAKD/RUuQDg/WnUz1x9/HkGrhfi3/85/UQh51pJIx7UIaa TzHaiPN7xYJLj3kAK4ZHUQKKDrfqdiqBL/5SvkNv+90CU=; Received: (qmail 12322 invoked by alias); 15 May 2012 13:08:37 -0000 Received: (qmail 12101 invoked by uid 22791); 15 May 2012 13:08:35 -0000 X-SWARE-Spam-Status: No, hits=-4.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, KHOP_RCVD_TRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE X-Spam-Check-By: sourceware.org Received: from mail-ee0-f47.google.com (HELO mail-ee0-f47.google.com) (74.125.83.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 15 May 2012 13:08:21 +0000 Received: by eekd49 with SMTP id d49so1823029eek.20 for ; Tue, 15 May 2012 06:08:20 -0700 (PDT) Received: by 10.14.53.76 with SMTP id f52mr458594eec.79.1337087300251; Tue, 15 May 2012 06:08:20 -0700 (PDT) Received: from richards-thinkpad.stglab.manchester.uk.ibm.com (gbibp9ph1--blueice3n2.emea.ibm.com. [195.212.29.84]) by mx.google.com with ESMTPS id a16sm12585238eeg.0.2012.05.15.06.08.17 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 15 May 2012 06:08:19 -0700 (PDT) From: Richard Sandiford To: DJ Delorie Mail-Followup-To: DJ Delorie , gcc-patches@gcc.gnu.org, vmakarov@redhat.com, rdsandiford@googlemail.com Cc: gcc-patches@gcc.gnu.org, vmakarov@redhat.com Subject: find_movable_pseudos vs. split moves (was Re: rx-elf fails after r187015) References: <201205142150.q4ELoDU0001504@greed.delorie.com> Date: Tue, 15 May 2012 14:08:16 +0100 In-Reply-To: <201205142150.q4ELoDU0001504@greed.delorie.com> (DJ Delorie's message of "Mon, 14 May 2012 17:50:13 -0400") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux) MIME-Version: 1.0 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 DJ Delorie writes: > After r187015 (Mar 31), gcc builds for rx-elf are failing with: > > make[3]: Entering directory `/greed/dj/m32c/gcc/rx-elf-head/rx-elf/64-bit-double/libgcc' > # If this is the top-level multilib, build all the other > # multilibs. > /greed/dj/m32c/gcc/rx-elf-head/./gcc/xgcc -B/greed/dj/m32c/gcc/rx-elf-head/./gcc/ -B/greed/dj/m32c/install/rx-elf/bin/ -B/greed/dj/m32c/install/rx-elf/lib/ -isystem /greed/dj/m32c/install/rx-elf/include -isystem /greed/dj/m32c/install/rx-elf/sys-include -g -O2 -m64bit-doubles -O2 -g -O2 -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -Dinhibit_libc -I. -I. -I../../.././gcc -I../../../../gcc/libgcc -I../../../../gcc/libgcc/. -I../../../../gcc/libgcc/../gcc -I../../../../gcc/libgcc/../include -DHAVE_CC_TLS -DUSE_EMUTLS -o _mulvdi3.o -MT _mulvdi3.o -MD -MP -MF _mulvdi3.dep -DL_mulvdi3 -c ../../../../gcc/libgcc/libgcc2.c > ../../../../gcc/libgcc/libgcc2.c: In function '__mulvdi3': > ../../../../gcc/libgcc/libgcc2.c:397:1: internal compiler error: in subreg_get_info, at rtlanal.c:3308 > } > ^ > > Can anyone else confirm this? I can well believe that that patch exposed the problem, but the bug seems to be in IRA. find_moveable_pseudos tries to redirect a DImode multiplication to a new register, then copies the new register to the original one before the first use. The problem here is that rx has no DImode move pattern, so we end up splitting the DImode move into two SImode moves and a clobber. When allocation fails for the new register, move_unallocated_pseudos deletes one of these three instructions, but the other two are left around. reload then gets confused because we have a subreg of a pseudo that isn't allocated and has no stack slot. One fix would be to check whether the backend has a move pattern. I don't particularly like that though, since I don't think targets like rx should be punished for not defining a DImode move. The fact that the first lower-subreg pass is so early in the rtl pipeline suggests that having unitary multiword moves shouldn't be important these days. This patch instead deletes all instructions that set the new register. One advantage is that IRA no longer needs to track the move specially. Tested by making sure that rx-elf build again and that the new code deletes all three instructions generated by gen_move_insn. Also bootstrapped & regression-tested on x86_64-linux-gnu. OK to install? Richard gcc/ * ira.c (pseudo_move_insn): Delete. (find_moveable_pseudos): Don't set it. (move_unallocated_pseudos): Use DF_REG_DEF_CHAIN to find the definitions of the original pseudo. Delete all of them. Index: gcc/ira.c =================================================================== --- gcc/ira.c 2012-05-15 10:47:19.000000000 +0100 +++ gcc/ira.c 2012-05-15 11:04:50.888126216 +0100 @@ -3621,9 +3621,6 @@ insn_dominated_by_p (rtx i1, rtx i2, int first_moveable_pseudo. */ /* The original home register. */ static VEC (rtx, heap) *pseudo_replaced_reg; -/* The move instruction we added to move the value to its original home - register. */ -static VEC (rtx, heap) *pseudo_move_insn; /* Look for instances where we have an instruction that is known to increase register pressure, and whose result is not used immediately. If it is @@ -3667,9 +3664,7 @@ find_moveable_pseudos (void) bitmap_initialize (&interesting, 0); first_moveable_pseudo = max_regs; - VEC_free (rtx, heap, pseudo_move_insn); VEC_free (rtx, heap, pseudo_replaced_reg); - VEC_safe_grow (rtx, heap, pseudo_move_insn, max_regs); VEC_safe_grow (rtx, heap, pseudo_replaced_reg, max_regs); df_analyze (); @@ -3964,10 +3959,8 @@ find_moveable_pseudos (void) if (validate_change (def_insn, DF_REF_LOC (def), newreg, 0)) { unsigned nregno = REGNO (newreg); - rtx move = emit_insn_before (gen_move_insn (def_reg, newreg), - use_insn); + emit_insn_before (gen_move_insn (def_reg, newreg), use_insn); nregno -= max_regs; - VEC_replace (rtx, pseudo_move_insn, nregno, move); VEC_replace (rtx, pseudo_replaced_reg, nregno, def_reg); } } @@ -4010,27 +4003,32 @@ move_unallocated_pseudos (void) for (i = first_moveable_pseudo; i < last_moveable_pseudo; i++) if (reg_renumber[i] < 0) { - df_ref def = DF_REG_DEF_CHAIN (i); int idx = i - first_moveable_pseudo; rtx other_reg = VEC_index (rtx, pseudo_replaced_reg, idx); - rtx def_insn = DF_REF_INSN (def); - rtx move_insn = VEC_index (rtx, pseudo_move_insn, idx); - rtx set; + rtx def_insn = DF_REF_INSN (DF_REG_DEF_CHAIN (i)); + /* The use must follow all definitions of OTHER_REG, so we can + insert the new definition immediately after any of them. */ + df_ref other_def = DF_REG_DEF_CHAIN (REGNO (other_reg)); + rtx move_insn = DF_REF_INSN (other_def); rtx newinsn = emit_insn_after (PATTERN (def_insn), move_insn); + rtx set; int success; if (dump_file) fprintf (dump_file, "moving def of %d (insn %d now) ", REGNO (other_reg), INSN_UID (def_insn)); + delete_insn (move_insn); + while ((other_def = DF_REG_DEF_CHAIN (REGNO (other_reg)))) + delete_insn (DF_REF_INSN (other_def)); + delete_insn (def_insn); + set = single_set (newinsn); success = validate_change (newinsn, &SET_DEST (set), other_reg, 0); gcc_assert (success); if (dump_file) fprintf (dump_file, " %d) rather than keep unallocated replacement %d\n", INSN_UID (newinsn), i); - delete_insn (move_insn); - delete_insn (def_insn); SET_REG_N_REFS (i, 0); } }