From patchwork Fri Jul 29 19:34:23 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Makarov X-Patchwork-Id: 107447 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 0D687B6F18 for ; Sat, 30 Jul 2011 05:34:36 +1000 (EST) Received: (qmail 6809 invoked by alias); 29 Jul 2011 19:34:34 -0000 Received: (qmail 6472 invoked by uid 22791); 29 Jul 2011 19:34:31 -0000 X-SWARE-Spam-Status: No, hits=-6.9 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, SPF_HELO_PASS 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; Fri, 29 Jul 2011 19:34:15 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p6TJYExM000389 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 29 Jul 2011 15:34:15 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p6TJYENT007862 for ; Fri, 29 Jul 2011 15:34:14 -0400 Received: from localhost.localdomain (ovpn-113-167.phx2.redhat.com [10.3.113.167]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id p6TJYDTu003874 for ; Fri, 29 Jul 2011 15:34:13 -0400 Message-ID: <4E330B3F.1080806@redhat.com> Date: Fri, 29 Jul 2011 15:34:23 -0400 From: Vladimir Makarov User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.18) Gecko/20110621 Fedora/3.1.11-1.fc14 Thunderbird/3.1.11 MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org Subject: [lra] another patch to decrease ARM code size degradation. 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 patch decrease code size degradation on ARM (SPEC2000 was used) by improving hard regno preferences for reload and inheritance pseudos, more accurate cost evaluation of alternatives with early clobbers, fixing missed copies for shuffling reload and inheritance pseudos, fixing missed removal of reversed equiv insns (i.e. EQUIV_MEM <- pseudo). The patch was successfully bootstrapped on x86-64 and ppc64 (unfortunately, i64 is broken on the branch). 2011-07-29 Vladimir Makarov * lra-constraints.c (LOSER_COST_FACTOR, MAX_OVERALL_COST_BOUND): New macros. (process_alt_operands): Use the macros. Adjust losers and overall for reloads becuase of early clobbers. (curr_insn_transform): Use MAX_OVERALL_COST_BOUND. (lra_constraints): Fix typo with parentheses. * lra-lives.c (process_bb_lives): Permit creation of copies involving all new pseudos. * lra-assigns.c (curr_update_hard_regno_preference_check): New variable. (update_hard_regno_preference_check): Ditto. (update_hard_regno_preference): New function. (lra_setup_reg_renumber): Use update_hard_regno_preference. (assign_by_spills): Initialize update_hard_regno_preference_check and curr_update_hard_regno_preference_check. Index: lra-lives.c =================================================================== --- lra-lives.c (revision 176797) +++ lra-lives.c (working copy) @@ -533,13 +533,14 @@ process_bb_lives (basic_block bb) /* Check that source regno does not conflict with destination regno to exclude most impossible preferences. */ - && (((((src_regno = REGNO (SET_SRC (set))) >= FIRST_PSEUDO_REGISTER - && ! sparseset_bit_p (pseudos_live, src_regno)) - || (src_regno < FIRST_PSEUDO_REGISTER - && ! TEST_HARD_REG_BIT (hard_regs_live, src_regno))) - /* It might be 'inheritance pseudo <- reload pseudo'. */ - || (src_regno >= lra_constraint_new_regno_start - && (int) ORIGINAL_REGNO (SET_DEST (set)) == src_regno)))) + && ((((src_regno = REGNO (SET_SRC (set))) >= FIRST_PSEUDO_REGISTER + && ! sparseset_bit_p (pseudos_live, src_regno)) + || (src_regno < FIRST_PSEUDO_REGISTER + && ! TEST_HARD_REG_BIT (hard_regs_live, src_regno))) + /* It might be 'inheritance pseudo <- reload pseudo'. */ + || (src_regno >= lra_constraint_new_regno_start + && ((int) REGNO (SET_DEST (set)) + >= lra_constraint_new_regno_start)))) { int hard_regno = -1, regno = -1; Index: lra-constraints.c =================================================================== --- lra-constraints.c (revision 176806) +++ lra-constraints.c (working copy) @@ -1313,6 +1313,13 @@ uses_hard_regs_p (rtx *loc, HARD_REG_SET return false; } +/* Cost factor for each additional reload and maximal cost bound for + insn reloads. One might ask about such strange numbers. Their + values occured historically from former reload pass. In some way, + even machine descriptions. */ +#define LOSER_COST_FACTOR 6 +#define MAX_OVERALL_COST_BOUND 600 + /* Major function to choose the current insn alternative and what operands should be reload and how. If ONLY_ALTERNATIVE is not negative we should consider only this alternative. Return false if @@ -1915,12 +1922,12 @@ process_alt_operands (int only_alternati { if (targetm.preferred_reload_class (op, this_alternative) == NO_REGS) - reject = 600; + reject = MAX_OVERALL_COST_BOUND; if (curr_static_id->operand[nop].type == OP_OUT && (targetm.preferred_output_reload_class (op, this_alternative) == NO_REGS)) - reject = 600; + reject = MAX_OVERALL_COST_BOUND; } /* We prefer to reload pseudos over reloading other @@ -1958,7 +1965,7 @@ process_alt_operands (int only_alternati /* ??? Should we update the cost because early clobber register reloads or it is a rare thing to be worth to do it. */ - overall = losers * 6 + reject; + overall = losers * LOSER_COST_FACTOR + reject; if ((best_losers == 0 || losers != 0) && best_overall < overall) goto fail; @@ -2027,7 +2034,11 @@ process_alt_operands (int only_alternati /* We need to reload early clobbered register. */ for (j = 0; j < n_operands; j++) if (curr_alt_matches[j] == i) - curr_alt_match_win[j] = false; + { + curr_alt_match_win[j] = false; + losers++; + overall += LOSER_COST_FACTOR; + } if (! curr_alt_match_win[i]) curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] = i; else @@ -2038,7 +2049,7 @@ process_alt_operands (int only_alternati } curr_alt_win[i] = curr_alt_match_win[i] = false; losers++; - overall += 6; + overall += LOSER_COST_FACTOR; } small_class_operands_num = 0; for (nop = 0; nop < n_operands; nop++) @@ -2584,7 +2595,7 @@ curr_insn_transform (void) got the wrong kind of hard reg. For this, we must consider all the operands together against the register constraints. */ - best_losers = best_overall = MAX_RECOG_OPERANDS * 2 + 600; + best_losers = best_overall = MAX_RECOG_OPERANDS * 2 + MAX_OVERALL_COST_BOUND; best_small_class_operands_num = best_reload_sum = 0; curr_swapped = false; @@ -3186,30 +3197,29 @@ lra_constraints (bool first_p) different from the pseudo mode. */ if (GET_CODE (dest_reg) == SUBREG) dest_reg = SUBREG_REG (dest_reg); - if (REG_P (dest_reg) - && ((((x = get_equiv_substitution (dest_reg)) != dest_reg) - /* Remove insns which set up a pseudo whose - value can not be changed. Such insns might - be not in init_insns because we don't update - equiv data during insn transformations. + if ((REG_P (dest_reg) + && (x = get_equiv_substitution (dest_reg)) != dest_reg + /* Remove insns which set up a pseudo whose value + can not be changed. Such insns might be not in + init_insns because we don't update equiv data + during insn transformations. - As an example, let suppose that a pseudo got - hard register and on the 1st pass was not - changed to equivalent constant. We generate - an additional insn setting up the pseudo - because of secondary memory movement. Then - the pseudo is spilled and we use the equiv - constant. In this case we should remove the - additional insn and this insn is not - init_insns list. */ - && (! MEM_P (x) || MEM_READONLY_P (x) - || in_list_p (curr_insn, - ira_reg_equiv - [REGNO (dest_reg)].init_insns))) - || (SET_SRC (set) != get_equiv_substitution (SET_SRC (set)) - && in_list_p (curr_insn, - ira_reg_equiv - [REGNO (SET_SRC (set))].init_insns)))) + As an example, let suppose that a pseudo got + hard register and on the 1st pass was not + changed to equivalent constant. We generate an + additional insn setting up the pseudo because of + secondary memory movement. Then the pseudo is + spilled and we use the equiv constant. In this + case we should remove the additional insn and + this insn is not init_insns list. */ + && (! MEM_P (x) || MEM_READONLY_P (x) + || in_list_p (curr_insn, + ira_reg_equiv + [REGNO (dest_reg)].init_insns))) + || (SET_SRC (set) != get_equiv_substitution (SET_SRC (set)) + && in_list_p (curr_insn, + ira_reg_equiv + [REGNO (SET_SRC (set))].init_insns))) { /* This is equiv init insn of pseudo which did not get a hard register -- remove the insn. */