From patchwork Wed Jul 4 20:48:40 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Makarov X-Patchwork-Id: 169048 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 568922C0089 for ; Thu, 5 Jul 2012 06:49:17 +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=1342039758; 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=STt8XFS 2uWlgMUDz6qG1Kdcm3f4=; b=Jjjet8OiDlzEQveBOHfzWDPvkDkb2cVZlotXZbj b0j9LjzaM7DrulAnviAq9DFqMbuY5M1dgIqhROJAsdKfrJeADKtrNRi0kgw6fYgC sYoWRaSkSdW4QRn/AxopEDglCK8yo9ix1DKkfPeqh1W/dje4hi5ua/6fs2TbbPpQ hLFE= 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=aNflvjVavQY7o+91EkCA4PfAIBz/5ezkyjMoo15pEjifnGAmJHVwTd5VdZg0Vy 3iYVdJJ1hiGCAEn6r1yFoEiD54+RV4NizJn3ReFPuEfRbqL818M5Fb/TkDo2XRl/ tXYBS/FG+dTgHQivDGm7DihCe1j1uWxsCZMl8+CowwGFw=; Received: (qmail 28521 invoked by alias); 4 Jul 2012 20:49:13 -0000 Received: (qmail 28512 invoked by uid 22791); 4 Jul 2012 20:49:10 -0000 X-SWARE-Spam-Status: No, hits=-6.0 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, MAY_BE_FORGED, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, SPF_HELO_PASS, 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; Wed, 04 Jul 2012 20:48:48 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q64Kmlt5029652 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 4 Jul 2012 16:48:48 -0400 Received: from toll.usersys.redhat.com (unused [10.15.16.165] (may be forged)) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q64Kmlgf004479 for ; Wed, 4 Jul 2012 16:48:47 -0400 Message-ID: <4FF4AC28.7030705@redhat.com> Date: Wed, 04 Jul 2012 16:48:40 -0400 From: Vladimir Makarov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20120430 Thunderbird/12.0.1 MIME-Version: 1.0 To: gcc-patches Subject: [lra] a patch to fix a ppc testsuite regression 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 fixes one testsuite regression on ppc64. LRA removed two insns setting asm reg variable assigned to eliminable hard regnos. It should be not done. The patch was successfully bootstrapped on x86-64, ppc64, ia64. Committed as rev. 189264. 2012-07-04 Vladimir Makarov * lra-eliminations.c (get_elimination): Change prototype. (lra_eliminate_regs_1, eliminate_regs_in_insn): Transfer reg instead of regno to get_elimination. (lra_eliminate_reg_if_possible): Ditto. Index: lra-eliminations.c =================================================================== --- lra-eliminations.c (revision 189236) +++ lra-eliminations.c (working copy) @@ -225,18 +225,22 @@ lra_get_elimation_hard_regno (int hard_r return ep->to; } -/* Return elimination which will be used for HARD_REGNO, NULL otherwise. */ +/* Return elimination which will be used for hard reg REG, NULL + otherwise. */ static struct elim_table * -get_elimination (int hard_regno) +get_elimination (rtx reg) { + int hard_regno; struct elim_table *ep; HOST_WIDE_INT offset; - if (hard_regno < 0 || hard_regno >= FIRST_PSEUDO_REGISTER) + lra_assert (REG_P (reg)); + if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER) + return NULL; + if ((ep = elimination_map[hard_regno]) != NULL) + return ep->from_rtx != reg ? NULL : ep; + if ((offset = self_elim_offsets[hard_regno]) == 0) return NULL; - if ((ep = elimination_map[hard_regno]) != NULL - || (offset = self_elim_offsets[hard_regno]) == 0) - return ep; /* This is an iteration to restore offsets just after HARD_REGNO stopped to be eliminable. */ self_elim_table.from = self_elim_table.to = hard_regno; @@ -268,7 +272,6 @@ lra_eliminate_regs_1 (rtx x, enum machin { enum rtx_code code = GET_CODE (x); struct elim_table *ep; - int regno; rtx new_rtx; int i, j; const char *fmt; @@ -295,24 +298,18 @@ lra_eliminate_regs_1 (rtx x, enum machin return x; case REG: - regno = REGNO (x); - /* First handle the case where we encounter a bare register that is eliminable. Replace it with a PLUS. */ - if (regno < FIRST_PSEUDO_REGISTER) + if ((ep = get_elimination (x)) != NULL) { - if ((ep = get_elimination (regno)) != NULL) - { - rtx to = subst_p ? ep->to_rtx : ep->from_rtx; - - if (update_p) - return plus_constant (Pmode, to, - ep->offset - ep->previous_offset); - else if (full_p) - return plus_constant (Pmode, to, ep->offset); - else - return to; - } + rtx to = subst_p ? ep->to_rtx : ep->from_rtx; + + if (update_p) + return plus_constant (Pmode, to, ep->offset - ep->previous_offset); + else if (full_p) + return plus_constant (Pmode, to, ep->offset); + else + return to; } return x; @@ -333,11 +330,9 @@ lra_eliminate_regs_1 (rtx x, enum machin case PLUS: /* If this is the sum of an eliminable register and a constant, rework the sum. */ - if (REG_P (XEXP (x, 0)) - && (regno = REGNO (XEXP (x, 0))) < FIRST_PSEUDO_REGISTER - && CONSTANT_P (XEXP (x, 1))) + if (REG_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1))) { - if ((ep = get_elimination (regno)) != NULL) + if ((ep = get_elimination (XEXP (x, 0))) != NULL) { HOST_WIDE_INT offset; rtx to = subst_p ? ep->to_rtx : ep->from_rtx; @@ -407,27 +402,25 @@ lra_eliminate_regs_1 (rtx x, enum machin so that we have (plus (mult ..) ..). This is needed in order to keep load-address insns valid. This case is pathological. We ignore the possibility of overflow here. */ - if (REG_P (XEXP (x, 0)) - && (regno = REGNO (XEXP (x, 0))) < FIRST_PSEUDO_REGISTER - && CONST_INT_P (XEXP (x, 1))) - if ((ep = get_elimination (regno)) != NULL) - { - rtx to = subst_p ? ep->to_rtx : ep->from_rtx; - - if (update_p) - return - plus_constant (Pmode, - gen_rtx_MULT (Pmode, to, XEXP (x, 1)), - (ep->offset - ep->previous_offset) - * INTVAL (XEXP (x, 1))); - else if (full_p) - return - plus_constant (Pmode, - gen_rtx_MULT (Pmode, to, XEXP (x, 1)), - ep->offset * INTVAL (XEXP (x, 1))); - else - return gen_rtx_MULT (Pmode, to, XEXP (x, 1)); - } + if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)) + && (ep = get_elimination (XEXP (x, 0))) != NULL) + { + rtx to = subst_p ? ep->to_rtx : ep->from_rtx; + + if (update_p) + return + plus_constant (Pmode, + gen_rtx_MULT (Pmode, to, XEXP (x, 1)), + (ep->offset - ep->previous_offset) + * INTVAL (XEXP (x, 1))); + else if (full_p) + return + plus_constant (Pmode, + gen_rtx_MULT (Pmode, to, XEXP (x, 1)), + ep->offset * INTVAL (XEXP (x, 1))); + else + return gen_rtx_MULT (Pmode, to, XEXP (x, 1)); + } /* ... fall through ... */ @@ -769,7 +762,7 @@ eliminate_regs_in_insn (rtx insn, bool r int icode = recog_memoized (insn); rtx old_set = single_set (insn); bool val; - int i, regno; + int i; rtx substed_operand[MAX_RECOG_OPERANDS]; rtx orig_operand[MAX_RECOG_OPERANDS]; struct elim_table *ep; @@ -787,93 +780,88 @@ eliminate_regs_in_insn (rtx insn, bool r return; } + /* Check for setting an eliminable register. */ if (old_set != 0 && REG_P (SET_DEST (old_set)) - && (regno = REGNO (SET_DEST (old_set))) < FIRST_PSEUDO_REGISTER) + && (ep = get_elimination (SET_DEST (old_set))) != NULL) { - /* Check for setting an eliminable register. */ - if ((ep = get_elimination (regno)) != NULL) - { - bool delete_p = replace_p; - + bool delete_p = replace_p; + #ifdef HARD_FRAME_POINTER_REGNUM - /* If this is setting the frame pointer register to the - hardware frame pointer register and this is an - elimination that will be done (tested above), this insn - is really adjusting the frame pointer downward to - compensate for the adjustment done before a nonlocal - goto. */ - if (ep->from == FRAME_POINTER_REGNUM - && ep->to == HARD_FRAME_POINTER_REGNUM) + /* If this is setting the frame pointer register to the hardware + frame pointer register and this is an elimination that will + be done (tested above), this insn is really adjusting the + frame pointer downward to compensate for the adjustment done + before a nonlocal goto. */ + if (ep->from == FRAME_POINTER_REGNUM + && ep->to == HARD_FRAME_POINTER_REGNUM) + { + if (replace_p) { - if (replace_p) - { - SET_DEST (old_set) = ep->to_rtx; - lra_update_insn_recog_data (insn); - return; - } - else + SET_DEST (old_set) = ep->to_rtx; + lra_update_insn_recog_data (insn); + return; + } + else + { + rtx base = SET_SRC (old_set); + HOST_WIDE_INT offset = 0; + rtx base_insn = insn; + + while (base != ep->to_rtx) { - rtx base = SET_SRC (old_set); - HOST_WIDE_INT offset = 0; - rtx base_insn = insn; - - while (base != ep->to_rtx) + rtx prev_insn, prev_set; + + if (GET_CODE (base) == PLUS && CONST_INT_P (XEXP (base, 1))) { - rtx prev_insn, prev_set; - - if (GET_CODE (base) == PLUS - && CONST_INT_P (XEXP (base, 1))) - { - offset += INTVAL (XEXP (base, 1)); - base = XEXP (base, 0); - } - else if ((prev_insn = prev_nonnote_insn (base_insn)) != 0 - && (prev_set = single_set (prev_insn)) != 0 - && rtx_equal_p (SET_DEST (prev_set), base)) - { - base = SET_SRC (prev_set); - base_insn = prev_insn; - } - else - break; + offset += INTVAL (XEXP (base, 1)); + base = XEXP (base, 0); } - - if (base == ep->to_rtx) + else if ((prev_insn = prev_nonnote_insn (base_insn)) != 0 + && (prev_set = single_set (prev_insn)) != 0 + && rtx_equal_p (SET_DEST (prev_set), base)) { - rtx src; - - offset -= (ep->offset - ep->previous_offset); - src = plus_constant (Pmode, ep->to_rtx, offset); - - /* First see if this insn remains valid when we - make the change. If not, keep the INSN_CODE - the same and let reload fit it up. */ - validate_change (insn, &SET_SRC (old_set), src, 1); - validate_change (insn, &SET_DEST (old_set), - ep->from_rtx, 1); - if (! apply_change_group ()) - { - SET_SRC (old_set) = src; - SET_DEST (old_set) = ep->from_rtx; - } - lra_update_insn_recog_data (insn); - return; + base = SET_SRC (prev_set); + base_insn = prev_insn; } + else + break; + } + + if (base == ep->to_rtx) + { + rtx src; + + offset -= (ep->offset - ep->previous_offset); + src = plus_constant (Pmode, ep->to_rtx, offset); + + /* First see if this insn remains valid when we + make the change. If not, keep the INSN_CODE + the same and let reload fit it up. */ + validate_change (insn, &SET_SRC (old_set), src, 1); + validate_change (insn, &SET_DEST (old_set), + ep->from_rtx, 1); + if (! apply_change_group ()) + { + SET_SRC (old_set) = src; + SET_DEST (old_set) = ep->from_rtx; + } + lra_update_insn_recog_data (insn); + return; } - - - /* We can't delete this insn, but needn't process it - since it won't be used unless something changes. */ - delete_p = false; } -#endif - /* This insn isn't serving a useful purpose. We delete it - when REPLACE is set. */ - if (delete_p) - lra_delete_dead_insn (insn); - return; + + /* We can't delete this insn, but needn't process it + since it won't be used unless something changes. */ + delete_p = false; } +#endif + + /* This insn isn't serving a useful purpose. We delete it + when REPLACE is set. */ + if (delete_p) + lra_delete_dead_insn (insn); + return; } /* We allow one special case which happens to work on all machines we @@ -909,8 +897,7 @@ eliminate_regs_in_insn (rtx insn, bool r if (GET_CODE (reg) == SUBREG) reg = SUBREG_REG (reg); - if (REG_P (reg) && (regno = REGNO (reg)) < FIRST_PSEUDO_REGISTER - && (ep = get_elimination (regno)) != NULL) + if (REG_P (reg) && (ep = get_elimination (reg)) != NULL) { rtx to_rtx = replace_p ? ep->to_rtx : ep->from_rtx; @@ -1234,7 +1221,7 @@ lra_eliminate_reg_if_possible (rtx *loc) /* Virtual registers are not allocatable. ??? */ || ! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno)) return; - if ((ep = get_elimination (regno)) != NULL) + if ((ep = get_elimination (*loc)) != NULL) *loc = ep->to_rtx; }