From patchwork Thu Mar 1 18:05:39 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Makarov X-Patchwork-Id: 144083 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 B48A21007D5 for ; Fri, 2 Mar 2012 05:06:08 +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=1331229969; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Message-ID:Date:From:User-Agent:MIME-Version:To:Subject: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=sx7hHBZ yx6bAHyvIm0TMbwoRDoc=; b=WrBf57lHHI159n4gAyept0XcfWoDCbvmO4KF0mK aNxiz5wqOWIr9tpmiWgX13eVfv+pOxE8/29PqYCJ3Z5dse1bY2NE0Ekm4pYbfiWZ chlv/iTtqAliFFp/3VZnJGSwbSicW3Dc2CHgvmSTOvRDYgjwt7RZV1CRMSxZMc2x PUOI= 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:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=fiSf+TB2NNvvuMS4v+4tSw/ENBVsAi9Sr0gz5B9mXmYPgjp2FZf+lk6OmwRZ1j rXQA97E9vWBl3b3K8gdW3klM0rprSk6VOJcf/ntFaiXMBC2+0W6oTejNv6FAFp3T rOqAYOuX/K4OcID+P6BsjzRO7RPb7+9jndH18Sp5r5Anc=; Received: (qmail 14839 invoked by alias); 1 Mar 2012 18:06:04 -0000 Received: (qmail 14730 invoked by uid 22791); 1 Mar 2012 18:06:01 -0000 X-SWARE-Spam-Status: No, hits=-6.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_TJ, 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; Thu, 01 Mar 2012 18:05:42 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q21I5eUj007492 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 1 Mar 2012 13:05:41 -0500 Received: from toll.yyz.redhat.com (unused [10.15.16.165] (may be forged)) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q21I5eEK005110 for ; Thu, 1 Mar 2012 13:05:40 -0500 Message-ID: <4F4FBA73.1010305@redhat.com> Date: Thu, 01 Mar 2012 13:05:39 -0500 From: Vladimir Makarov User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.24) Gecko/20111108 Fedora/3.1.16-1.fc14 Thunderbird/3.1.16 MIME-Version: 1.0 To: gcc-patches Subject: [lra] a patch to fix s390 bootstrap 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 The following patch finally fixes s390 bootstrap. The patch was successfully bootstrapped on s390x, x86/x86-64, power7, arm, sparc64, and ia64. Committed as rev. 184749. 2012-03-01 Vladimir Makarov * lra-lives.c (pseudos_live_through_calls): New sparseset. (pseudos_live_through_setjumps): Ditto. (check_pseudos_live_through_calls): New function. (process_bb_lives): Use the sparsesets and the function. (lra_create_live_ranges): Allocate and free sparsesets pseudos_live_through_calls and pseudos_live_through_setjumps. * lra-constraints.c (check_and_process_move): Try secondary reload for source and destination. * jump.c (true_regnum): Use hard_regno for subreg_get_info when lra is in progress. Index: lra-lives.c =================================================================== --- lra-lives.c (revision 184177) +++ lra-lives.c (working copy) @@ -69,6 +69,16 @@ static int curr_point; /* Pseudos live at current point in the scan. */ static sparseset pseudos_live; +/* Pseudos probably living through calls and setjumps. As setjump is + a call too, if a bit in PSEUDOS_LIVE_THROUGH_SETJUMPS is set up + then the corresponding bit in PSEUDOS_LIVE_THROUGH_CALLS is set up + too. These data are necessary for cases when only one subreg of a + multi-reg pseudo is set up after a call. So we decide it is + probably live when traversing bb backward. We are sure about + living when we see its usage or definition of the pseudo. */ +static sparseset pseudos_live_through_calls; +static sparseset pseudos_live_through_setjumps; + /* Set of hard regs (except eliminable ones) currently live. */ static HARD_REG_SET hard_regs_live; @@ -466,6 +476,28 @@ lra_setup_reload_pseudo_preferenced_hard } } +/* Check that REGNO living through calls and setjumps, set up conflict + regs, and clear corresponding bits in PSEUDOS_LIVE_THROUGH_CALLS and + PSEUDOS_LIVE_THROUGH_SETJUMPS. */ +static inline void +check_pseudos_live_through_calls (int regno) +{ + if (! sparseset_bit_p (pseudos_live_through_calls, regno)) + return; + sparseset_clear_bit (pseudos_live_through_calls, regno); + IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, + call_used_reg_set); +#ifdef ENABLE_CHECKING + lra_reg_info[regno].call_p = true; +#endif + if (! sparseset_bit_p (pseudos_live_through_setjumps, regno)) + return; + sparseset_clear_bit (pseudos_live_through_setjumps, regno); + /* Don't allocate pseudos that cross setjmps or any call, if this + function receives a nonlocal goto. */ + SET_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs); +} + /* Process insns of the basic block BB to update pseudo live ranges, pseudo hard register conflicts. */ static void @@ -480,6 +512,8 @@ process_bb_lives (basic_block bb) reg_live_out = DF_LR_OUT (bb); sparseset_clear (pseudos_live); + sparseset_clear (pseudos_live_through_calls); + sparseset_clear (pseudos_live_through_setjumps); REG_SET_TO_HARD_REG_SET (hard_regs_live, reg_live_out); AND_COMPL_HARD_REG_SET (hard_regs_live, eliminable_regset); AND_COMPL_HARD_REG_SET (hard_regs_live, lra_no_alloc_regs); @@ -571,7 +605,10 @@ process_bb_lives (basic_block bb) that are live at the time of the definition. */ for (reg = curr_id->regs; reg != NULL; reg = reg->next) if (reg->type != OP_IN) - mark_regno_live (reg->regno, reg->biggest_mode); + { + mark_regno_live (reg->regno, reg->biggest_mode); + check_pseudos_live_through_calls (reg->regno); + } for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type != OP_IN) @@ -596,22 +633,13 @@ process_bb_lives (basic_block bb) if (call_p) { - /* The current set of live pseudos are live across the - call. */ - EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i) - { - /* Don't allocate pseudos that cross setjmps or any - call, if this function receives a nonlocal goto. */ - if (cfun->has_nonlocal_label - || find_reg_note (curr_insn, REG_SETJMP, - NULL_RTX) != NULL_RTX) - SET_HARD_REG_SET (lra_reg_info[i].conflict_hard_regs); - IOR_HARD_REG_SET (lra_reg_info[i].conflict_hard_regs, - call_used_reg_set); -#ifdef ENABLE_CHECKING - lra_reg_info[i].call_p = true; -#endif - } + sparseset_ior (pseudos_live_through_calls, + pseudos_live_through_calls, pseudos_live); + if (cfun->has_nonlocal_label + || find_reg_note (curr_insn, REG_SETJMP, + NULL_RTX) != NULL_RTX) + sparseset_ior (pseudos_live_through_setjumps, + pseudos_live_through_setjumps, pseudos_live); } incr_curr_point (freq); @@ -621,7 +649,10 @@ process_bb_lives (basic_block bb) /* Mark each used value as live. */ for (reg = curr_id->regs; reg != NULL; reg = reg->next) if (reg->type == OP_IN) - mark_regno_live (reg->regno, reg->biggest_mode); + { + mark_regno_live (reg->regno, reg->biggest_mode); + check_pseudos_live_through_calls (reg->regno); + } for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type == OP_IN) @@ -711,6 +742,10 @@ process_bb_lives (basic_block bb) EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i) mark_pseudo_dead (i); + + EXECUTE_IF_SET_IN_SPARSESET (pseudos_live_through_calls, i) + if (bitmap_bit_p (DF_LR_IN (bb), i)) + check_pseudos_live_through_calls (i); incr_curr_point (freq); } @@ -943,6 +978,8 @@ lra_create_live_ranges (bool all_p) } lra_free_copies (); pseudos_live = sparseset_alloc (max_regno); + pseudos_live_through_calls = sparseset_alloc (max_regno); + pseudos_live_through_setjumps = sparseset_alloc (max_regno); start_living = sparseset_alloc (max_regno); start_dying = sparseset_alloc (max_regno); dead_set = sparseset_alloc (max_regno); @@ -961,6 +998,8 @@ lra_create_live_ranges (bool all_p) sparseset_free (dead_set); sparseset_free (start_dying); sparseset_free (start_living); + sparseset_free (pseudos_live_through_calls); + sparseset_free (pseudos_live_through_setjumps); sparseset_free (pseudos_live); compress_live_ranges (); } Index: lra-constraints.c =================================================================== --- lra-constraints.c (revision 184637) +++ lra-constraints.c (working copy) @@ -1042,11 +1042,11 @@ emit_spill_move (bool to_p, rtx mem_pseu static bool check_and_process_move (bool *change_p, bool *sec_mem_p) { - int regno; - rtx set, dest, src, dreg, sr, dr, sreg, new_reg, before, x, scratch_reg; - enum reg_class dclass, sclass, xclass, rclass, secondary_class; + int sregno, dregno; + rtx set, dest, src, dreg, sr, dr, sreg, new_reg, before, scratch_reg; + enum reg_class dclass, sclass, secondary_class; + enum machine_mode sreg_mode; secondary_reload_info sri; - bool in_p, temp_assign_p; *sec_mem_p = *change_p = false; if ((set = single_set (curr_insn)) == NULL || side_effects_p (set)) @@ -1081,6 +1081,7 @@ check_and_process_move (bool *change_p, work with such classes through their implementation of machine-dependent hooks like secondary_memory_needed. */ return false; + sreg_mode = GET_MODE (sreg); sr = get_equiv_substitution (sreg); if (sr != sreg) sreg = copy_rtx (sr); @@ -1100,44 +1101,44 @@ check_and_process_move (bool *change_p, sri.prev_sri = NULL; sri.icode = CODE_FOR_nothing; sri.extra_cost = 0; - if (sclass != NO_REGS) - { - in_p = false; - rclass = sclass; - x = dreg; - xclass = dclass; - } - else if (dclass != NO_REGS) - { - in_p = true; - rclass = dclass; - x = sreg; - xclass = sclass; - } - else - return false; - temp_assign_p = false; + secondary_class = NO_REGS; /* Set up hard register for a reload pseudo for hook secondary_reload because some targets just ignore pseudos in the hook. */ - if (xclass != NO_REGS - && REG_P (x) && (regno = REGNO (x)) >= new_regno_start - && lra_get_regno_hard_regno (regno) < 0) - { - reg_renumber[regno] = ira_class_hard_regs[xclass][0]; - temp_assign_p = true; - } - secondary_class - = (enum reg_class) targetm.secondary_reload (in_p, x, (reg_class_t) rclass, - GET_MODE (src), &sri); - if (temp_assign_p) - reg_renumber [REGNO (x)] = -1; + if (dclass != NO_REGS + && REG_P (dreg) && (dregno = REGNO (dreg)) >= new_regno_start + && lra_get_regno_hard_regno (dregno) < 0) + reg_renumber[dregno] = ira_class_hard_regs[dclass][0]; + else + dregno = -1; + if (sclass != NO_REGS + && REG_P (sreg) && (sregno = REGNO (sreg)) >= new_regno_start + && lra_get_regno_hard_regno (sregno) < 0) + reg_renumber[sregno] = ira_class_hard_regs[sclass][0]; + else + sregno = -1; + if (sclass != NO_REGS) + secondary_class + = (enum reg_class) targetm.secondary_reload (false, dest, + (reg_class_t) sclass, + GET_MODE (src), &sri); + if (sclass == NO_REGS + || ((secondary_class != NO_REGS || sri.icode != CODE_FOR_nothing) + && dclass != NO_REGS)) + secondary_class + = (enum reg_class) targetm.secondary_reload (true, sreg, + (reg_class_t) dclass, + sreg_mode, &sri); + if (sregno >= 0) + reg_renumber [sregno] = -1; + if (dregno >= 0) + reg_renumber [dregno] = -1; if (secondary_class == NO_REGS && sri.icode == CODE_FOR_nothing) return false; *change_p = true; new_reg = NULL_RTX; if (secondary_class != NO_REGS) - new_reg = lra_create_new_reg_with_unique_value (GET_MODE (sreg), NULL_RTX, + new_reg = lra_create_new_reg_with_unique_value (sreg_mode, NULL_RTX, secondary_class, "secondary"); start_sequence (); @@ -1160,8 +1161,8 @@ check_and_process_move (bool *change_p, lra_process_new_insns (curr_insn, before, NULL_RTX, "Inserting the move"); if (new_reg != NULL_RTX) { - if (GET_CODE (SET_SRC (set)) == SUBREG) - SUBREG_REG (SET_SRC (set)) = new_reg; + if (GET_CODE (src) == SUBREG) + SUBREG_REG (src) = new_reg; else SET_SRC (set) = new_reg; } Index: jump.c =================================================================== --- jump.c (revision 184146) +++ jump.c (working copy) @@ -1866,7 +1866,8 @@ true_regnum (const_rtx x) { struct subreg_info info; - subreg_get_info (REGNO (SUBREG_REG (x)), + subreg_get_info (lra_in_progress + ? (unsigned) base : REGNO (SUBREG_REG (x)), GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x), GET_MODE (x), &info);