From patchwork Fri Jun 1 14:49:58 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Makarov X-Patchwork-Id: 162324 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 1315CB700A for ; Sat, 2 Jun 2012 00:50:26 +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=1339167027; 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=189ew4O 9qdKXPKpPnV9oA0wy+wM=; b=YfvYpqYa39o4yPzNfQrYsYHInSTO4KajnqMzSn1 3k7H0NWKD6DcWX5kqK4E4EnPLHt7Fy0kkTsMcvc0PNyqvc/v7XckWmf8vJ6zADep 14QhZKVvUbvi0mXN4d9cATQFAmHsP1d/HkeI2iaBk8NRXZBRCdzjLfUqIZ8/shNP GjNE= 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=c/SJcpTr3d6X+lzyDsJiGgTT/jict3m745cBp2J4LX5Dc2UUWA919yvlwYBd9b 3cQl/GUcqqSpySG/ryZmElKzWgwZorrZKX6xSdmWi7MIuuR6ja/qY42RgUUkHBzD Gwx2PzTmcaAMay6i8wS3PXiLmM1KWM0FkBQbpkU19OyAQ=; Received: (qmail 30941 invoked by alias); 1 Jun 2012 14:50:20 -0000 Received: (qmail 30924 invoked by uid 22791); 1 Jun 2012 14:50:15 -0000 X-SWARE-Spam-Status: No, hits=-5.4 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, SARE_MLB_Stock6, 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; Fri, 01 Jun 2012 14:49:59 +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 q51Enx5h015915 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 1 Jun 2012 10:49:59 -0400 Received: from ivy.local (ovpn-113-72.phx2.redhat.com [10.3.113.72]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q51EnwHE005874 for ; Fri, 1 Jun 2012 10:49:58 -0400 Message-ID: <4FC8D696.1070904@redhat.com> Date: Fri, 01 Jun 2012 10:49:58 -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] hard reg splitting 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 Register-pressure sensitive scheduling decreased greatly probability of a long standing bug when 1st insn scheduling may result in reload pass failure of finding a hard reg for a reload. Still the bug is present. The following patch adds hard-reg splitting to LRA which should finally solve the bug (or course if LRA is used instead of reload). I hope the patch can also improve the code for some targets on which 1st insn scheduling is used and ABI requires hard regs usage for parameter passing. The patch was successfully bootstrapped on x86-64. Committed as rev. 188109. 2012-06-01 Vladimir Makarov * lra-constraints.c (struct usage_insns): Use registers instead pseudos in comments about splitting. (check_only_pseudos): Rename to check_only_regs. (need_for_call_save_p): Assert that argument is a pseudo regno. (need_for_split_p): Process hard reg too. (split_pseudo): Rename to split_reg, process hard reg too. (live_pseudos): Rename to live_regs. (inherit_in_ebb): Process hard regs too for splitting. (get_pseudo_regno): Rename to get_regno. Process hard reg too. (remove_inheritance_pseudos): Process hard regs too. (lra_undo_inheritance): Ditto. Index: lra-constraints.c =================================================================== --- lra-constraints.c (revision 188108) +++ lra-constraints.c (working copy) @@ -3654,15 +3654,15 @@ static int calls_num; USAGE_INSNS. */ static int curr_usage_insns_check; -/* Info about last usage of pseudos in EBB to do inheritance/split +/* Info about last usage of registers in EBB to do inheritance/split transformation. Inheritance transformation is done from a spilled - pseudo and split transformations from a pseudo to assigned to a - hard register. */ + pseudo and split transformations from a hard register or a pseudo + assigned to a hard register. */ struct usage_insns { /* If the value is equal to the above variable value, then the INSNS is valid. The insns is chain of optional debug insns and a - finishing non-debug insn using the corresponding pseudo. */ + finishing non-debug insn using the corresponding reg. */ int check; /* Value of global reloads_num at the corresponding next insns. */ int reloads_num; @@ -3671,12 +3671,11 @@ struct usage_insns /* It can be true only for splitting. And it means that the restore insn should be put after insn give by the following member. */ bool after_p; - /* Next insns in the current EBB which use the original pseudo and - the original pseudo value is not changed between the current insn - and the next insns. In order words, if we need to use the - original pseudo value again in the next insns we can try to use - the value in a hard register from a reload insn of the current - insn. */ + /* Next insns in the current EBB which use the original reg and the + original reg value is not changed between the current insn and + the next insns. In order words, if we need to use the original + reg value again in the next insns we can try to use the value in + a hard register from a reload insn of the current insn. */ rtx insns; }; @@ -3723,9 +3722,9 @@ substitute_pseudo (rtx *loc, int old_reg return result; } -/* Pseudos involved in inheritance/split in the current EBB - (inheritance/split and original pseudos). */ -static bitmap_head check_only_pseudos; +/* Registers involved in inheritance/split in the current EBB + (inheritance/split pseudos and original registers). */ +static bitmap_head check_only_regs; /* Do inheritance transformation for insn INSN defining (if DEF_P) or using ORIGINAL_REGNO where the subsequent insn(s) in EBB (remember @@ -3827,8 +3826,8 @@ inherit_reload_reg (bool def_p, bool uni fprintf (lra_dump_file, " Original reg change %d->%d:\n", original_regno, REGNO (new_reg)); lra_reg_info[REGNO (new_reg)].restore_regno = original_regno; - bitmap_set_bit (&check_only_pseudos, REGNO (new_reg)); - bitmap_set_bit (&check_only_pseudos, original_regno); + bitmap_set_bit (&check_only_regs, REGNO (new_reg)); + bitmap_set_bit (&check_only_regs, original_regno); bitmap_set_bit (&lra_inheritance_pseudos, REGNO (new_reg)); if (def_p) lra_process_new_insns (insn, NULL_RTX, new_insns, @@ -3871,31 +3870,36 @@ inherit_reload_reg (bool def_p, bool uni static inline bool need_for_call_save_p (int regno) { - gcc_assert (reg_renumber[regno] >= 0); + gcc_assert (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0); return (usage_insns[regno].calls_num < calls_num && (lra_hard_reg_set_intersection_p (reg_renumber[regno], PSEUDO_REGNO_MODE (regno), call_used_reg_set))); } -/* Return true if we need a split for pseudo REGNO which was assigned - to a hard register. POTENTIAL_RELOAD_HARD_REGS contains hard - registers which might be used for reloads since the EBB end. It is - an approximation of the used hard registers in the split range. - The exact value would require expensive calculations. If we were - aggressive with splitting because of the approximation, the split - pseudo will save the same hard register assignment and will be - removed in the undo pass. We still need the approximation because - too aggressive splitting would result in too inaccurate cost - calculation in the assignment pass because of too many generated - moves which will be probably removed in the undo pass. */ +/* Return true if we need a split for hard register REGNO or pseudo + REGNO which was assigned to a hard register. + POTENTIAL_RELOAD_HARD_REGS contains hard registers which might be + used for reloads since the EBB end. It is an approximation of the + used hard registers in the split range. The exact value would + require expensive calculations. If we were aggressive with + splitting because of the approximation, the split pseudo will save + the same hard register assignment and will be removed in the undo + pass. We still need the approximation because too aggressive + splitting would result in too inaccurate cost calculation in the + assignment pass because of too many generated moves which will be + probably removed in the undo pass. */ static inline bool need_for_split_p (HARD_REG_SET potential_reload_hard_regs, int regno) { - gcc_assert (reg_renumber[regno] >= 0); - return ((TEST_HARD_REG_BIT (potential_reload_hard_regs, reg_renumber[regno]) - && usage_insns[regno].reloads_num + 2 < reloads_num) - || need_for_call_save_p (regno)); + int hard_regno = regno < FIRST_PSEUDO_REGISTER ? regno : reg_renumber[regno]; + + gcc_assert (hard_regno >= 0); + return ((TEST_HARD_REG_BIT (potential_reload_hard_regs, hard_regno) + && ! TEST_HARD_REG_BIT (lra_no_alloc_regs, hard_regno) + && (usage_insns[regno].reloads_num + + (regno < FIRST_PSEUDO_REGISTER ? 0 : 2) < reloads_num)) + || (regno >= FIRST_PSEUDO_REGISTER && need_for_call_save_p (regno))); } /* Return class for the split pseudo created from original pseudo with @@ -3954,15 +3958,30 @@ choose_split_class (enum reg_class alloc split pseudo. The save is put before INSN if BEFORE_P is true. Return true if we succeed in such transformation. */ static bool -split_pseudo (bool before_p, int original_regno, rtx insn, rtx next_usage_insns) +split_reg (bool before_p, int original_regno, rtx insn, rtx next_usage_insns) { - enum reg_class rclass = lra_get_allocno_class (original_regno); - rtx original_reg = regno_reg_rtx[original_regno]; + enum reg_class rclass; + rtx original_reg; + int hard_regno; rtx new_reg, save, restore, usage_insn; bool after_p; - bool call_save_p = need_for_call_save_p (original_regno); + bool call_save_p; - gcc_assert (reg_renumber[original_regno] >= 0); + if (original_regno < FIRST_PSEUDO_REGISTER) + { + rclass = ira_allocno_class_translate[REGNO_REG_CLASS (original_regno)]; + hard_regno = original_regno; + call_save_p = false; + } + else + { + hard_regno = reg_renumber[original_regno]; + rclass = lra_get_allocno_class (original_regno); + original_reg = regno_reg_rtx[original_regno]; + call_save_p = need_for_call_save_p (original_regno); + } + original_reg = regno_reg_rtx[original_regno]; + gcc_assert (hard_regno >= 0); if (lra_dump_file != NULL) fprintf (lra_dump_file, " ((((((((((((((((((((((((((((((((((((((((((((((((\n"); @@ -3980,9 +3999,7 @@ split_pseudo (bool before_p, int origina } else { - rclass = choose_split_class (rclass, - reg_renumber[original_regno], - GET_MODE (original_reg)); + rclass = choose_split_class (rclass, hard_regno, GET_MODE (original_reg)); if (rclass == NO_REGS) { if (lra_dump_file != NULL) @@ -3992,9 +4009,8 @@ split_pseudo (bool before_p, int origina "no good reg class for %d(%s)\n", original_regno, reg_class_names[lra_get_allocno_class (original_regno)], - reg_renumber[original_regno], - reg_class_names[REGNO_REG_CLASS - (reg_renumber[original_regno])]); + hard_regno, + reg_class_names[REGNO_REG_CLASS (hard_regno)]); fprintf (lra_dump_file, " ))))))))))))))))))))))))))))))))))))))))))))))))\n"); } @@ -4002,7 +4018,7 @@ split_pseudo (bool before_p, int origina } new_reg = lra_create_new_reg (GET_MODE (original_reg), original_reg, rclass, "split"); - reg_renumber[REGNO (new_reg)] = reg_renumber[original_regno]; + reg_renumber[REGNO (new_reg)] = hard_regno; } if (call_save_p) save = emit_spill_move (true, new_reg, original_reg, -1); @@ -4053,8 +4069,8 @@ split_pseudo (bool before_p, int origina } after_p = usage_insns[original_regno].after_p; lra_reg_info[REGNO (new_reg)].restore_regno = original_regno; - bitmap_set_bit (&check_only_pseudos, REGNO (new_reg)); - bitmap_set_bit (&check_only_pseudos, original_regno); + bitmap_set_bit (&check_only_regs, REGNO (new_reg)); + bitmap_set_bit (&check_only_regs, original_regno); bitmap_set_bit (&lra_split_pseudos, REGNO (new_reg)); for (;;) { @@ -4092,9 +4108,9 @@ split_pseudo (bool before_p, int origina return true; } -/* Check only pseudos living at the current program point in the +/* Check only registers living at the current program point in the current EBB. */ -static bitmap_head live_pseudos; +static bitmap_head live_regs; /* Update live info in EBB given by its HEAD and TAIL insns after inheritance/split transformation. The function removes dead moves @@ -4128,8 +4144,8 @@ update_ebb_live_info (rtx head, rtx tail if (prev_bb != NULL) { /* Udpate DF_LR_IN (prev_bb): */ - EXECUTE_IF_SET_IN_BITMAP (&check_only_pseudos, 0, j, bi) - if (bitmap_bit_p (&live_pseudos, j)) + EXECUTE_IF_SET_IN_BITMAP (&check_only_regs, 0, j, bi) + if (bitmap_bit_p (&live_regs, j)) bitmap_set_bit (DF_LR_IN (prev_bb), j); else bitmap_clear_bit (DF_LR_IN (prev_bb), j); @@ -4137,9 +4153,9 @@ update_ebb_live_info (rtx head, rtx tail if (curr_bb != last_bb) { /* Update DF_LR_OUT (curr_bb): */ - EXECUTE_IF_SET_IN_BITMAP (&check_only_pseudos, 0, j, bi) + EXECUTE_IF_SET_IN_BITMAP (&check_only_regs, 0, j, bi) { - live_p = bitmap_bit_p (&live_pseudos, j); + live_p = bitmap_bit_p (&live_regs, j); if (! live_p) FOR_EACH_EDGE (e, ei, curr_bb->succs) if (bitmap_bit_p (DF_LR_IN (e->dest), j)) @@ -4154,31 +4170,30 @@ update_ebb_live_info (rtx head, rtx tail } } prev_bb = curr_bb; - bitmap_and (&live_pseudos, - &check_only_pseudos, DF_LR_OUT (curr_bb)); + bitmap_and (&live_regs, &check_only_regs, DF_LR_OUT (curr_bb)); } curr_id = lra_get_insn_recog_data (curr_insn); remove_p = false; if ((set = single_set (curr_insn)) != NULL_RTX && REG_P (SET_DEST (set)) && (regno = REGNO (SET_DEST (set))) >= FIRST_PSEUDO_REGISTER - && bitmap_bit_p (&check_only_pseudos, regno) - && ! bitmap_bit_p (&live_pseudos, regno)) + && bitmap_bit_p (&check_only_regs, regno) + && ! bitmap_bit_p (&live_regs, regno)) remove_p = true; /* See which defined values die here. */ for (reg = curr_id->regs; reg != NULL; reg = reg->next) if (reg->type == OP_OUT && ! reg->early_clobber && (! reg->subreg_p || bitmap_bit_p (&lra_bound_pseudos, reg->regno))) - bitmap_clear_bit (&live_pseudos, reg->regno); + bitmap_clear_bit (&live_regs, reg->regno); /* Mark each used value as live. */ for (reg = curr_id->regs; reg != NULL; reg = reg->next) if (reg->type == OP_IN - && bitmap_bit_p (&check_only_pseudos, reg->regno)) - bitmap_set_bit (&live_pseudos, reg->regno); + && bitmap_bit_p (&check_only_regs, reg->regno)) + bitmap_set_bit (&live_regs, reg->regno); /* Mark early clobber outputs dead. */ for (reg = curr_id->regs; reg != NULL; reg = reg->next) if (reg->type == OP_OUT && reg->early_clobber && ! reg->subreg_p) - bitmap_clear_bit (&live_pseudos, reg->regno); + bitmap_clear_bit (&live_regs, reg->regno); /* It is quite important to remove dead move insns because it means removing dead store, we don't need to process them for constraints, and unfortunately some subsequent optimizations @@ -4337,7 +4352,7 @@ inherit_in_ebb (rtx head, rtx tail) curr_usage_insns_check++; reloads_num = calls_num = 0; /* Remeber: we can remove the current insn. */ - bitmap_clear (&check_only_pseudos); + bitmap_clear (&check_only_regs); last_processed_bb = NULL; CLEAR_HARD_REG_SET (potential_reload_hard_regs); CLEAR_HARD_REG_SET (live_hard_regs); @@ -4368,20 +4383,25 @@ inherit_in_ebb (rtx head, rtx tail) IOR_HARD_REG_SET (live_hard_regs, eliminable_regset); IOR_HARD_REG_SET (live_hard_regs, lra_no_alloc_regs); CLEAR_HARD_REG_SET (potential_reload_hard_regs); - EXECUTE_IF_SET_IN_BITMAP (to_process, - FIRST_PSEUDO_REGISTER, j, bi) - if ((int) j < lra_constraint_new_regno_start - && reg_renumber[j] >= 0) - { - lra_add_hard_reg_set (reg_renumber[j], - PSEUDO_REGNO_MODE (j), - &live_hard_regs); - usage_insns[j].check = curr_usage_insns_check; - usage_insns[j].insns = last_insn; - usage_insns[j].reloads_num = reloads_num; - usage_insns[j].calls_num = calls_num; - usage_insns[j].after_p = after_p; - } + EXECUTE_IF_SET_IN_BITMAP (to_process, 0, j, bi) + { + if ((int) j >= lra_constraint_new_regno_start) + break; + if (j < FIRST_PSEUDO_REGISTER || reg_renumber[j] >= 0) + { + if (j < FIRST_PSEUDO_REGISTER) + SET_HARD_REG_BIT (live_hard_regs, j); + else + lra_add_hard_reg_set (reg_renumber[j], + PSEUDO_REGNO_MODE (j), + &live_hard_regs); + usage_insns[j].check = curr_usage_insns_check; + usage_insns[j].insns = last_insn; + usage_insns[j].reloads_num = reloads_num; + usage_insns[j].calls_num = calls_num; + usage_insns[j].after_p = after_p; + } + } } src_regno = dst_regno = -1; if (NONDEBUG_INSN_P (curr_insn) @@ -4451,13 +4471,12 @@ inherit_in_ebb (rtx head, rtx tail) /* Process insn definitions. */ for (reg = curr_id->regs; reg != NULL; reg = reg->next) if (reg->type != OP_IN - && (dst_regno = reg->regno) >= FIRST_PSEUDO_REGISTER - && dst_regno < lra_constraint_new_regno_start + && (dst_regno = reg->regno) < lra_constraint_new_regno_start && usage_insns[dst_regno].check == curr_usage_insns_check && (next_usage_insns = usage_insns[dst_regno].insns) != NULL_RTX) { - if (reg->type == OP_OUT + if (dst_regno >= FIRST_PSEUDO_REGISTER && reg->type == OP_OUT && reg_renumber[dst_regno] < 0 && ! reg->subreg_p) { struct lra_insn_reg *r; @@ -4473,21 +4492,25 @@ inherit_in_ebb (rtx head, rtx tail) regs) can change after that. */ add_to_inherit (dst_regno, next_usage_insns); } - /* We can not process one pseudo twice here - because of usage_insns invalidation. */ - if (reg_renumber[dst_regno] >= 0 && ! reg->subreg_p - && reg->type == OP_OUT) + /* We can not process one reg twice here because of + usage_insns invalidation. */ + if ((dst_regno < FIRST_PSEUDO_REGISTER + || reg_renumber[dst_regno] >= 0) + && ! reg->subreg_p && reg->type == OP_OUT) { HARD_REG_SET s; if (need_for_split_p (potential_reload_hard_regs, dst_regno) - && split_pseudo (false, dst_regno, curr_insn, - next_usage_insns)) + && split_reg (false, dst_regno, curr_insn, + next_usage_insns)) change_p = true; CLEAR_HARD_REG_SET (s); - lra_add_hard_reg_set (reg_renumber[dst_regno], - PSEUDO_REGNO_MODE (dst_regno), &s); + if (dst_regno < FIRST_PSEUDO_REGISTER) + SET_HARD_REG_BIT (s, dst_regno); + else + lra_add_hard_reg_set (reg_renumber[dst_regno], + PSEUDO_REGNO_MODE (dst_regno), &s); AND_COMPL_HARD_REG_SET (live_hard_regs, s); } if (reg_renumber[dst_regno] < 0 @@ -4508,10 +4531,10 @@ inherit_in_ebb (rtx head, rtx tail) for (reg = curr_id->regs; reg != NULL; reg = reg->next) if ((reg->type != OP_OUT || (reg->type == OP_OUT && reg->subreg_p)) - && (src_regno = reg->regno) >= FIRST_PSEUDO_REGISTER - && src_regno < lra_constraint_new_regno_start) + && (src_regno = reg->regno) < lra_constraint_new_regno_start) { - if (reg_renumber[src_regno] < 0 && reg->type == OP_IN) + if (src_regno >= FIRST_PSEUDO_REGISTER + && reg_renumber[src_regno] < 0 && reg->type == OP_IN) { if (usage_insns[src_regno].check == curr_usage_insns_check && (next_usage_insns @@ -4522,7 +4545,8 @@ inherit_in_ebb (rtx head, rtx tail) /* Add usages. */ add_next_usage_insn (src_regno, curr_insn, reloads_num); } - else if (reg_renumber[src_regno] >= 0) + else if (src_regno < FIRST_PSEUDO_REGISTER + || reg_renumber[src_regno] >= 0) { bool before_p; rtx use_insn = curr_insn; @@ -4542,8 +4566,8 @@ inherit_in_ebb (rtx head, rtx tail) && need_for_split_p (potential_reload_hard_regs, src_regno) && NONDEBUG_INSN_P (curr_insn) - && split_pseudo (before_p, src_regno, curr_insn, - next_usage_insns)) + && split_reg (before_p, src_regno, curr_insn, + next_usage_insns)) { if (reg->subreg_p) lra_risky_transformations_p = true; @@ -4554,10 +4578,15 @@ inherit_in_ebb (rtx head, rtx tail) use_insn = PREV_INSN (curr_insn); } if (NONDEBUG_INSN_P (curr_insn)) - lra_add_hard_reg_set (reg_renumber[src_regno], - PSEUDO_REGNO_MODE (src_regno), - &live_hard_regs); - add_next_usage_insn (src_regno, use_insn, reloads_num); + { + if (src_regno < FIRST_PSEUDO_REGISTER) + SET_HARD_REG_BIT (live_hard_regs, src_regno); + else + lra_add_hard_reg_set (reg_renumber[src_regno], + PSEUDO_REGNO_MODE (src_regno), + &live_hard_regs); + } + add_next_usage_insn (src_regno, use_insn, reloads_num); } } for (i = 0; i < to_inherit_num; i++) @@ -4592,28 +4621,29 @@ inherit_in_ebb (rtx head, rtx tail) to_process = &temp_bitmap; } head_p = true; - EXECUTE_IF_SET_IN_BITMAP (to_process, - FIRST_PSEUDO_REGISTER, j, bi) - if ((int) j < lra_constraint_new_regno_start - && reg_renumber[j] >= 0 - && usage_insns[j].check == curr_usage_insns_check - && (next_usage_insns = usage_insns[j].insns) != NULL_RTX) - { - if (first_insn != NULL_RTX - && need_for_split_p (potential_reload_hard_regs, j)) - { - if (lra_dump_file != NULL && head_p) - { - fprintf (lra_dump_file, - " ----------------------------------\n"); - head_p = false; - } - if (split_pseudo (true, j, first_insn, - next_usage_insns)) - change_p = true; - } - usage_insns[j].check = 0; - } + EXECUTE_IF_SET_IN_BITMAP (to_process, 0, j, bi) + { + if ((int) j >= lra_constraint_new_regno_start) + break; + if (((int) j < FIRST_PSEUDO_REGISTER || reg_renumber[j] >= 0) + && usage_insns[j].check == curr_usage_insns_check + && (next_usage_insns = usage_insns[j].insns) != NULL_RTX) + { + if (first_insn != NULL_RTX + && need_for_split_p (potential_reload_hard_regs, j)) + { + if (lra_dump_file != NULL && head_p) + { + fprintf (lra_dump_file, + " ----------------------------------\n"); + head_p = false; + } + if (split_reg (true, j, first_insn, next_usage_insns)) + change_p = true; + } + usage_insns[j].check = 0; + } + } } } return change_p; @@ -4645,8 +4675,8 @@ lra_inheritance (void) * lra_constraint_new_regno_start); for (i = 0; i < lra_constraint_new_regno_start; i++) usage_insns[i].check = 0; - bitmap_initialize (&check_only_pseudos, ®_obstack); - bitmap_initialize (&live_pseudos, ®_obstack); + bitmap_initialize (&check_only_regs, ®_obstack); + bitmap_initialize (&live_regs, ®_obstack); bitmap_initialize (&temp_bitmap, ®_obstack); FOR_EACH_BB (bb) { @@ -4675,8 +4705,8 @@ lra_inheritance (void) update_ebb_live_info (BB_HEAD (start_bb), BB_END (bb)); } bitmap_clear (&temp_bitmap); - bitmap_clear (&live_pseudos); - bitmap_clear (&check_only_pseudos); + bitmap_clear (&live_regs); + bitmap_clear (&check_only_regs); free (usage_insns); } @@ -4707,18 +4737,15 @@ fix_bb_live_info (bitmap live, bitmap re } } -/* Return regno of the (subreg of) pseudo REG. Otherise, return - a negative number. */ +/* Return regno of the (subreg of) REG. Otherise, return a negative + number. */ static int -get_pseudo_regno (rtx reg) +get_regno (rtx reg) { - int regno; - if (GET_CODE (reg) == SUBREG) reg = SUBREG_REG (reg); - if (REG_P (reg) - && (regno = REGNO (reg)) >= FIRST_PSEUDO_REGISTER) - return regno; + if (REG_P (reg)) + return REGNO (reg); return -1; } @@ -4757,8 +4784,8 @@ remove_inheritance_pseudos (bitmap remov if (change_p && NONDEBUG_INSN_P (curr_insn) && (set = single_set (curr_insn)) != NULL_RTX) { - dregno = get_pseudo_regno (SET_DEST (set)); - sregno = get_pseudo_regno (SET_SRC (set)); + dregno = get_regno (SET_DEST (set)); + sregno = get_regno (SET_SRC (set)); } if (sregno >= 0 && dregno >= 0) @@ -4775,8 +4802,8 @@ remove_inheritance_pseudos (bitmap remov removed inherit pseudo <- another removed inherit pseudo removed inherit pseudo <- original pseudo Or - removed_split_pseudo <- original_pseudo - original_pseudo <- removed_split_pseudo */ + removed_split_pseudo <- original_reg + original_reg <- removed_split_pseudo */ { if (lra_dump_file != NULL) { @@ -4850,7 +4877,6 @@ remove_inheritance_pseudos (bitmap remov if (change_p && bitmap_bit_p (remove_pseudos, regno)) { restore_regno = lra_reg_info[regno].restore_regno; - gcc_assert (restore_regno >= FIRST_PSEUDO_REGISTER); substitute_pseudo (&curr_insn, regno, regno_reg_rtx[restore_regno]); insn_change_p = true; @@ -4885,7 +4911,7 @@ bool lra_undo_inheritance (void) { unsigned int regno; - int restore_regno; + int restore_regno, hard_regno; int n_all_inherit, n_inherit, n_all_split, n_split; bitmap_head remove_pseudos; bitmap_iterator bi; @@ -4916,8 +4942,9 @@ lra_undo_inheritance (void) if ((restore_regno = lra_reg_info[regno].restore_regno) >= 0) { n_all_split++; - if (reg_renumber[restore_regno] < 0 - || reg_renumber[regno] == reg_renumber[restore_regno]) + hard_regno = (restore_regno >= FIRST_PSEUDO_REGISTER + ? reg_renumber[restore_regno] : restore_regno); + if (hard_regno < 0 || reg_renumber[regno] == hard_regno) bitmap_set_bit (&remove_pseudos, regno); else {