From patchwork Mon Oct 15 17:45:43 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 191618 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 71CFE2C00BD for ; Tue, 16 Oct 2012 04:49:28 +1100 (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=1350928168; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:From:To:Subject:Date:Message-ID:User-Agent:MIME-Version: Content-Type:Content-Transfer-Encoding:Mailing-List:Precedence: List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=G1RLdS991sZFJgPtlGIdWLASVEU=; b=N/GgxffKXsVe5Pe csbZmYZeRQ3apNMOQvW/YgMPgIzZTVx6wTkANAXKq+hVTgUyPaOYnvhk/OYJAV+m fvUXLxEV3MDN2arFBy2Rf82cNZM+UQAZzJpxBjwxMu9lRFKpefdlI0AKikbgazS/ Mduc8LqFs+nM/6lc9MsV0JxhlOx0= 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:Subject:Date:Message-ID:User-Agent:MIME-Version:Content-Type:Content-Transfer-Encoding:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=k1HASQwxzYjyCHO2UKjw6Lv/KU+NfKQszYztlodce42A+bywctK3nOo+WRtqtG DP5elX0M9SgeiVbID5v49gCEtNiG3OSNVmY+JuQZWWPAVDlc43XRSQHlEr62mgpV 3rk/7VL14CiJ1Os/pyGvkyTiTIxK07kvA/FqyO2IiJmX8=; Received: (qmail 29457 invoked by alias); 15 Oct 2012 17:49:21 -0000 Received: (qmail 29444 invoked by uid 22791); 15 Oct 2012 17:49:19 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (194.98.77.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 15 Oct 2012 17:49:15 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 428CE29000F for ; Mon, 15 Oct 2012 19:49:26 +0200 (CEST) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id p0Abzy0EQ9HQ for ; Mon, 15 Oct 2012 19:49:26 +0200 (CEST) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id 0BBAE29000D for ; Mon, 15 Oct 2012 19:49:26 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [RFC] Fix spill failure at -O on 64-bit Windows Date: Mon, 15 Oct 2012 19:45:43 +0200 Message-ID: <2808912.mi0B0sGudI@polaris> User-Agent: KMail/4.7.2 (Linux/3.1.10-1.16-desktop; KDE/4.7.2; x86_64; ; ) 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 For the attached Ada testcase, the compiler aborts with a spill failure at -O: p.adb: In function 'P.F': p.adb:16:7: error: unable to find a register to spill in class 'DREG' p.adb:16:7: error: this is the insn: (insn 141 140 142 17 (parallel [ (set (reg:SI 0 ax [174]) (div:SI (subreg:SI (reg:DI 43 r14 [orig:81 iftmp.6 ] [81]) 0) (reg:SI 41 r12 [orig:140 q__l.7 ] [140]))) (set (reg:SI 43 r14 [175]) (mod:SI (subreg:SI (reg:DI 43 r14 [orig:81 iftmp.6 ] [81]) 0) (reg:SI 41 r12 [orig:140 q__l.7 ] [140]))) (clobber (reg:CC 17 flags)) ]) p.adb:6 349 {*divmodsi4} (expr_list:REG_DEAD (reg:SI 41 r12 [orig:140 q__l.7 ] [140]) (expr_list:REG_DEAD (reg:DI 43 r14 [orig:81 iftmp.6 ] [81]) (expr_list:REG_UNUSED (reg:SI 43 r14 [175]) (expr_list:REG_UNUSED (reg:CC 17 flags) (nil)))))) +===========================GNAT BUG DETECTED==============================+ | 4.8.0 20121015 (experimental) [trunk revision 192447] (x86_64-pc-mingw32) GCC error:| | in spill_failure, at reload1.c:2124 The problem is that LIM hoists instructions preparing an argument register for a call out of a loop, without moving the associated clobber: (insn 249 248 250 33 (clobber (reg:SC 2 cx)) p.adb:12 -1 (nil)) [...] (insn 253 251 254 33 (parallel [ (set (reg:DI 204) (and:DI (reg:DI 2 cx) (reg:DI 195))) (clobber (reg:CC 17 flags)) ]) p.adb:12 375 {*anddi_1} (expr_list:REG_EQUAL (and:DI (reg:DI 2 cx) (const_int -4294967296 [0xffffffff00000000])) (expr_list:REG_DEAD (reg:DI 2 cx) (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))))) Set in insn 253 is invariant (8), cost 8, depends on 6 Decided to move invariant 8 -- gain 8 This extends the lifetime of the hard register up to the beginning of the function, causing reload to die on the complex division instruction. The attached patch prevents the invariant from being hoisted in this very particular case. Any better idea? Tested on x86_64-suse-linux. 2012-10-15 Eric Botcazou * loop-invariant.c: Include target.h. (check_dependency): Return false for an uninitialized argument register that is likely to be spilled. * Makefile.in (loop-invariant.o): Add $(TARGET_H). 2012-10-15 Eric Botcazou * gnat.dg/loop_optimization13.ad[sb]: New test. * gnat.dg/loop_optimization13_pkg.ads: New helper. Index: Makefile.in =================================================================== --- Makefile.in (revision 192447) +++ Makefile.in (working copy) @@ -3101,7 +3101,7 @@ loop-iv.o : loop-iv.c $(CONFIG_H) $(SYST intl.h $(DIAGNOSTIC_CORE_H) $(DF_H) $(HASHTAB_H) loop-invariant.o : loop-invariant.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \ $(RTL_H) $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) $(RECOG_H) \ - $(TM_H) $(TM_P_H) $(FUNCTION_H) $(FLAGS_H) $(DF_H) \ + $(TM_H) $(TM_P_H) $(FUNCTION_H) $(FLAGS_H) $(DF_H) $(TARGET_H) \ $(OBSTACK_H) $(HASHTAB_H) $(EXCEPT_H) $(PARAMS_H) $(REGS_H) ira.h cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \ $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) \ Index: loop-invariant.c =================================================================== --- loop-invariant.c (revision 192447) +++ loop-invariant.c (working copy) @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. #include "cfgloop.h" #include "expr.h" #include "recog.h" +#include "target.h" #include "function.h" #include "flags.h" #include "df.h" @@ -784,7 +785,22 @@ check_dependency (basic_block bb, df_ref defs = DF_REF_CHAIN (use); if (!defs) - return true; + { + unsigned int regno = DF_REF_REGNO (use); + + /* If this is the use of an uninitialized argument register that is + likely to be spilled, do not move it lest this might extend its + lifetime and cause reload to die. This can occur for a call to + a function taking complex number arguments and moving the insns + preparing the arguments without moving the call itself wouldn't + gain much in practice. */ + if ((DF_REF_FLAGS (use) & DF_HARD_REG_LIVE) + && FUNCTION_ARG_REGNO_P (regno) + && targetm.class_likely_spilled_p (REGNO_REG_CLASS (regno))) + return false; + + return true; + } if (defs->next) return false;