From patchwork Thu Oct 3 20:23:13 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joern Rennecke X-Patchwork-Id: 280415 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]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 7F0BE2C0094 for ; Fri, 4 Oct 2013 06:23:23 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:to:subject:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=bocE4hfATSbFaOfP JQp38O/9sdVCw9vURY53S4mANRbqCr4OjgDJ7qd4Kkk9leq7nXcZ4ss2ZRvkl/RS fKSYy7wP+5iZ3YN0gVGhVvy8wLtCV1xAwvquLDymsUvXXVMtipDV5VM16Scwhc30 ImkOWTZLxM83B4voZotnXAhrJiw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:to:subject:mime-version:content-type :content-transfer-encoding; s=default; bh=8j5NwzHVkhHIp2w9slRJ1P 3R5t4=; b=d4jIfLULMAQh1eucXB3FHF4d6D1AIRYRIZyZyi4XuhEPRlhxOwmuD3 5bWCAeatMfjrZh/q+mLcCnCRMQ/LIzPb1Z3Wt2HjgoNhb2Jookmyv06YOVrKhA8o qItVtSRuY8d7tfJKHfhZfqXNNUQUKMEX+vHDvu8SH0EiPcm5eI658= Received: (qmail 30457 invoked by alias); 3 Oct 2013 20:23:16 -0000 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 Received: (qmail 30447 invoked by uid 89); 3 Oct 2013 20:23:16 -0000 Received: from c62.cesmail.net (HELO c62.cesmail.net) (216.154.195.54) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Thu, 03 Oct 2013 20:23:16 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL, BAYES_00, FSL_HELO_NON_FQDN_1, RDNS_NONE autolearn=no version=3.3.2 X-HELO: c62.cesmail.net Received: from unknown (HELO delta2) ([192.168.1.50]) by c62.cesmail.net with ESMTP; 03 Oct 2013 16:23:13 -0400 Received: from cust213-dsl91-135-11.idnet.net (cust213-dsl91-135-11.idnet.net [91.135.11.213]) by webmail.spamcop.net (Horde MIME library) with HTTP; Thu, 03 Oct 2013 16:23:13 -0400 Message-ID: <20131003162313.00ny1vjalss8sskw-nzlynne@webmail.spamcop.net> Date: Thu, 03 Oct 2013 16:23:13 -0400 From: Joern Rennecke To: gcc-patches@gcc.gnu.org Subject: RFA [reload]: Fix PR other/58545 MIME-Version: 1.0 User-Agent: Internet Messaging Program (IMP) H3 (4.1.4) To make sure that reloading is done with up-to-date register eliminations, I call update_eliminables also in the code path that continues for a frame size change. Not directly, since I need the code to spill the no longer eliminated registers; I've factored out this code into a new function update_eliminables_and_spill. Also, I move the frame size alignment code before the code that tests for a frame size change so that this is also covered with the enhanced check. In principle, we could inline update_eliminables into update_eliminables_and_spill now, since the former is only called from the latter, but I leave this to the bootstrap compiler so as not to break the connection between init_elim_table and update_eliminables. Regression tested on avr atmega128-sim. Bootstrapped and regtested on i686-pc-linux-gnu. OK to apply? 2013-10-02 Joern Rennecke PR other/58545 * reload1.c (update_eliminables_and_spill): New function, broken out of reload. (reload): Use it. Check for frame size change after frame size alignment, and call update_eliminables_and_spill first if continue-ing. Index: reload1.c =================================================================== --- reload1.c (revision 203159) +++ reload1.c (working copy) @@ -373,6 +373,7 @@ static void init_eliminable_invariants ( static void init_elim_table (void); static void free_reg_equiv (void); static void update_eliminables (HARD_REG_SET *); +static bool update_eliminables_and_spill (void); static void elimination_costs_in_insn (rtx); static void spill_hard_reg (unsigned int, int); static int finish_spills (int); @@ -913,9 +914,6 @@ reload (rtx first, int global) if (caller_save_needed) setup_save_areas (); - /* If we allocated another stack slot, redo elimination bookkeeping. */ - if (something_was_spilled || starting_frame_size != get_frame_size ()) - continue; if (starting_frame_size && crtl->stack_alignment_needed) { /* If we have a stack frame, we must align it now. The @@ -927,8 +925,12 @@ reload (rtx first, int global) STARTING_FRAME_OFFSET not be already aligned to STACK_BOUNDARY. */ assign_stack_local (BLKmode, 0, crtl->stack_alignment_needed); - if (starting_frame_size != get_frame_size ()) - continue; + } + /* If we allocated another stack slot, redo elimination bookkeeping. */ + if (something_was_spilled || starting_frame_size != get_frame_size ()) + { + update_eliminables_and_spill (); + continue; } if (caller_save_needed) @@ -962,30 +964,11 @@ reload (rtx first, int global) else if (!verify_initial_elim_offsets ()) something_changed = 1; - { - HARD_REG_SET to_spill; - CLEAR_HARD_REG_SET (to_spill); - update_eliminables (&to_spill); - AND_COMPL_HARD_REG_SET (used_spill_regs, to_spill); - - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (TEST_HARD_REG_BIT (to_spill, i)) - { - spill_hard_reg (i, 1); - did_spill = 1; - - /* Regardless of the state of spills, if we previously had - a register that we thought we could eliminate, but now can - not eliminate, we must run another pass. - - Consider pseudos which have an entry in reg_equiv_* which - reference an eliminable register. We must make another pass - to update reg_equiv_* so that we do not substitute in the - old value from when we thought the elimination could be - performed. */ - something_changed = 1; - } - } + if (update_eliminables_and_spill ()) + { + did_spill = 1; + something_changed = 1; + } select_reload_regs (); if (failure) @@ -4031,6 +4014,38 @@ update_eliminables (HARD_REG_SET *pset) SET_HARD_REG_BIT (*pset, HARD_FRAME_POINTER_REGNUM); } +/* Call update_eliminables an spill any registers we can't eliminate anymore. + Return true iff a register was spilled. */ + +static bool +update_eliminables_and_spill (void) +{ + int i; + bool did_spill = false; + HARD_REG_SET to_spill; + CLEAR_HARD_REG_SET (to_spill); + update_eliminables (&to_spill); + AND_COMPL_HARD_REG_SET (used_spill_regs, to_spill); + + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + if (TEST_HARD_REG_BIT (to_spill, i)) + { + spill_hard_reg (i, 1); + did_spill = true; + + /* Regardless of the state of spills, if we previously had + a register that we thought we could eliminate, but now can + not eliminate, we must run another pass. + + Consider pseudos which have an entry in reg_equiv_* which + reference an eliminable register. We must make another pass + to update reg_equiv_* so that we do not substitute in the + old value from when we thought the elimination could be + performed. */ + } + return did_spill; +} + /* Return true if X is used as the target register of an elimination. */ bool