From patchwork Fri Jan 15 19:37:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Makarov X-Patchwork-Id: 568409 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.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id ED85B140B04 for ; Sat, 16 Jan 2016 06:37:46 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=vIKkU5EN; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=UlWc4nNwuwi+4ByEc+nwIunr26CG5U1K3wXm74tPDGEFMlKXsJ R6J54mhZnCKNq++1P7l3Ljssuu+EQZz2bTg0u91r5CoKZ9p9xdkvHliIwMf5WHhW cH0DO0amukJcvK1w4gcCX6Yhr/Hdf8dfGn/I+xlMU/YgJEx4HC6NxH3/g= 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:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=24VfDCm8kZAECNaFQxOKdOzQMRE=; b=vIKkU5ENodjStQCngolj 0IbPk3sQolIulNoathoHrHHJNLK+AxqzTYCy7Vz/j9fPNshuRE8thfVX9VNTNZAt V7eeNZ8QMw9Kh71n6gPQ8lvkb9LF62bzlOVaD/J/2QWmhIGrp2y81/E7byPjEves zHYuD/Ko6dEGgqU8917ygcY= Received: (qmail 107421 invoked by alias); 15 Jan 2016 19:37:38 -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 107411 invoked by uid 89); 15 Jan 2016 19:37:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=BAYES_00, KAM_ASCII_DIVIDERS, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=no version=3.3.2 spammy=REGNO, xveclen, XVECLEN, Sort X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 15 Jan 2016 19:37:36 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 6AF4BA8D for ; Fri, 15 Jan 2016 19:37:35 +0000 (UTC) Received: from [10.3.112.2] ([10.3.112.2]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u0FJbXec005176 for ; Fri, 15 Jan 2016 14:37:34 -0500 To: gcc-patches From: Vladimir Makarov Subject: Patch to fix PR69030 Message-ID: <56994A7D.7030709@redhat.com> Date: Fri, 15 Jan 2016 14:37:33 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.1.0 MIME-Version: 1.0 X-IsSubscribed: yes The following patch fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69030 The patch was bootstrapped and tested on x86 and x86-64. Committed as rev. 232445. 2016-01-15 Vladimir Makarov PR rtl-optimization/69030 * lra-spills.c (remove_pseudos): Check nrefs and make the function returning bool. (spill_pseudos): Delete debug insn for dead pseudo. (lra_spill): Initiate spill_hard_reg and slots memory separately. 2016-01-15 Vladimir Makarov PR rtl-optimization/69030 * lra-spills.c (remove_pseudos): Check nrefs and make the function returning bool. (spill_pseudos): Delete debug insn for dead pseudo. (lra_spill): Initiate spill_hard_reg and slots memory separately. Index: lra-spills.c =================================================================== --- lra-spills.c (revision 232143) +++ lra-spills.c (working copy) @@ -396,17 +396,19 @@ assign_stack_slot_num_and_sort_pseudos ( /* Recursively process LOC in INSN and change spilled pseudos to the corresponding memory or spilled hard reg. Ignore spilled pseudos - created from the scratches. */ -static void + created from the scratches. Return true if the pseudo nrefs equal + to 0 (don't change the pseudo in this case). Otherwise return false. */ +static bool remove_pseudos (rtx *loc, rtx_insn *insn) { int i; rtx hard_reg; const char *fmt; enum rtx_code code; - + bool res = false; + if (*loc == NULL_RTX) - return; + return res; code = GET_CODE (*loc); if (code == REG && (i = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER && lra_get_regno_hard_regno (i) < 0 @@ -416,6 +418,9 @@ remove_pseudos (rtx *loc, rtx_insn *insn into scratches back. */ && ! lra_former_scratch_p (i)) { + if (lra_reg_info[i].nrefs == 0 + && pseudo_slots[i].mem == NULL && spill_hard_reg[i] == NULL) + return true; if ((hard_reg = spill_hard_reg[i]) != NULL_RTX) *loc = copy_rtx (hard_reg); else @@ -425,22 +430,23 @@ remove_pseudos (rtx *loc, rtx_insn *insn false, false, 0, true); *loc = x != pseudo_slots[i].mem ? x : copy_rtx (x); } - return; + return res; } fmt = GET_RTX_FORMAT (code); for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') - remove_pseudos (&XEXP (*loc, i), insn); + res = remove_pseudos (&XEXP (*loc, i), insn) || res; else if (fmt[i] == 'E') { int j; for (j = XVECLEN (*loc, i) - 1; j >= 0; j--) - remove_pseudos (&XVECEXP (*loc, i, j), insn); + res = remove_pseudos (&XVECEXP (*loc, i, j), insn) || res; } } + return res; } /* Convert spilled pseudos into their stack slots or spill hard regs, @@ -450,7 +456,7 @@ static void spill_pseudos (void) { basic_block bb; - rtx_insn *insn; + rtx_insn *insn, *curr; int i; bitmap_head spilled_pseudos, changed_insns; @@ -467,52 +473,70 @@ spill_pseudos (void) } FOR_EACH_BB_FN (bb, cfun) { - FOR_BB_INSNS (bb, insn) - if (bitmap_bit_p (&changed_insns, INSN_UID (insn))) - { - rtx *link_loc, link; - remove_pseudos (&PATTERN (insn), insn); - if (CALL_P (insn)) - remove_pseudos (&CALL_INSN_FUNCTION_USAGE (insn), insn); - for (link_loc = ®_NOTES (insn); - (link = *link_loc) != NULL_RTX; - link_loc = &XEXP (link, 1)) - { - switch (REG_NOTE_KIND (link)) - { - case REG_FRAME_RELATED_EXPR: - case REG_CFA_DEF_CFA: - case REG_CFA_ADJUST_CFA: - case REG_CFA_OFFSET: - case REG_CFA_REGISTER: - case REG_CFA_EXPRESSION: - case REG_CFA_RESTORE: - case REG_CFA_SET_VDRAP: - remove_pseudos (&XEXP (link, 0), insn); - break; - default: - break; - } - } - if (lra_dump_file != NULL) - fprintf (lra_dump_file, - "Changing spilled pseudos to memory in insn #%u\n", - INSN_UID (insn)); - lra_push_insn (insn); - if (lra_reg_spill_p || targetm.different_addr_displacement_p ()) - lra_set_used_insn_alternative (insn, -1); - } - else if (CALL_P (insn)) - /* Presence of any pseudo in CALL_INSN_FUNCTION_USAGE does - not affect value of insn_bitmap of the corresponding - lra_reg_info. That is because we don't need to reload - pseudos in CALL_INSN_FUNCTION_USAGEs. So if we process - only insns in the insn_bitmap of given pseudo here, we - can miss the pseudo in some - CALL_INSN_FUNCTION_USAGEs. */ - remove_pseudos (&CALL_INSN_FUNCTION_USAGE (insn), insn); - bitmap_and_compl_into (df_get_live_in (bb), &spilled_pseudos); - bitmap_and_compl_into (df_get_live_out (bb), &spilled_pseudos); + FOR_BB_INSNS_SAFE (bb, insn, curr) + { + bool removed_pseudo_p = false; + + if (bitmap_bit_p (&changed_insns, INSN_UID (insn))) + { + rtx *link_loc, link; + + removed_pseudo_p = remove_pseudos (&PATTERN (insn), insn); + if (CALL_P (insn) + && remove_pseudos (&CALL_INSN_FUNCTION_USAGE (insn), insn)) + removed_pseudo_p = true; + for (link_loc = ®_NOTES (insn); + (link = *link_loc) != NULL_RTX; + link_loc = &XEXP (link, 1)) + { + switch (REG_NOTE_KIND (link)) + { + case REG_FRAME_RELATED_EXPR: + case REG_CFA_DEF_CFA: + case REG_CFA_ADJUST_CFA: + case REG_CFA_OFFSET: + case REG_CFA_REGISTER: + case REG_CFA_EXPRESSION: + case REG_CFA_RESTORE: + case REG_CFA_SET_VDRAP: + if (remove_pseudos (&XEXP (link, 0), insn)) + removed_pseudo_p = true; + break; + default: + break; + } + } + if (lra_dump_file != NULL) + fprintf (lra_dump_file, + "Changing spilled pseudos to memory in insn #%u\n", + INSN_UID (insn)); + lra_push_insn (insn); + if (lra_reg_spill_p || targetm.different_addr_displacement_p ()) + lra_set_used_insn_alternative (insn, -1); + } + else if (CALL_P (insn) + /* Presence of any pseudo in CALL_INSN_FUNCTION_USAGE + does not affect value of insn_bitmap of the + corresponding lra_reg_info. That is because we + don't need to reload pseudos in + CALL_INSN_FUNCTION_USAGEs. So if we process only + insns in the insn_bitmap of given pseudo here, we + can miss the pseudo in some + CALL_INSN_FUNCTION_USAGEs. */ + && remove_pseudos (&CALL_INSN_FUNCTION_USAGE (insn), insn)) + removed_pseudo_p = true; + if (removed_pseudo_p) + { + lra_assert (DEBUG_INSN_P (insn)); + lra_set_insn_deleted (insn); + if (lra_dump_file != NULL) + fprintf (lra_dump_file, + "Debug insn #%u is deleted as containing removed pseudo\n", + INSN_UID (insn)); + } + bitmap_and_compl_into (df_get_live_in (bb), &spilled_pseudos); + bitmap_and_compl_into (df_get_live_out (bb), &spilled_pseudos); + } } bitmap_clear (&spilled_pseudos); bitmap_clear (&changed_insns); @@ -548,12 +572,14 @@ lra_spill (void) if (lra_reg_info[i].nrefs != 0 && lra_get_regno_hard_regno (i) < 0 /* We do not want to assign memory for former scratches. */ && ! lra_former_scratch_p (i)) - { - spill_hard_reg[i] = NULL_RTX; - pseudo_regnos[n++] = i; - } + pseudo_regnos[n++] = i; lra_assert (n > 0); pseudo_slots = XNEWVEC (struct pseudo_slot, regs_num); + for (i = FIRST_PSEUDO_REGISTER; i < regs_num; i++) + { + spill_hard_reg[i] = NULL_RTX; + pseudo_slots[i].mem = NULL_RTX; + } slots = XNEWVEC (struct slot, regs_num); /* Sort regnos according their usage frequencies. */ qsort (pseudo_regnos, n, sizeof (int), regno_freq_compare); Index: testsuite/gcc.target/i386/pr69030.c =================================================================== --- testsuite/gcc.target/i386/pr69030.c (revision 0) +++ testsuite/gcc.target/i386/pr69030.c (working copy) @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -g -w" } */ + +int a, b, c = 7, d; +static unsigned e, g; +char f; +static unsigned fn1() { + unsigned h = e - b ^ c; + int i = h / c & a * g, j = g * h; + if (h) { + if (d) + h = e; + j = a; + a = (a && (g % f && i) % h) | c | ~2; + if (b) + printf("", 1); + } + c = i; + a = j; + return 2; +} + +int main() { + for (; b < -18; --b) + g = 0; + fn1(); + return 0; +}