From patchwork Mon May 18 18:13:33 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 473539 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 A53DB14027F for ; Tue, 19 May 2015 04:13:50 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=YVb5v+wh; 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:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type:content-transfer-encoding; q=dns; s=default; b=Dwn Wdmk6aduZuQGUt7yaI4zpPWskjm3Zs1K3HahgqLhAxRgijg+UMmHxuX/aOh83J6t vkMLZteOgDzkzHvrJWVvKE2R0WwdjgE9aRYJ5HHvxuYBIeKCoT5QL+QR6UuM/vSx bQ092g0Gm+i+dk7O9xK7N73T37UtqJ5F0C+wk6NA= 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:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type:content-transfer-encoding; s=default; bh=ii5dEfWCq Qpfd+lku1wgGdhoQMs=; b=YVb5v+whHANzTkTPm65lIQWXwO2MPKH5U9Ro4bGDu UsVeoWIuMnPC334Xz2TsLNz/b/42phPlbiNOZNzGU1mlFtpsrQtmYblnqblamMDb qXyBUqmSpp4mgzTmCqOIzLHgVlJkHA1ryTDWH8MgrP/ghWRq7+mVS2HeqvUUkW6n Ec= Received: (qmail 54854 invoked by alias); 18 May 2015 18:13:41 -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 54821 invoked by uid 89); 18 May 2015 18:13:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.0 required=5.0 tests=AWL, BAYES_50, KAM_ASCII_DIVIDERS, SPF_PASS autolearn=no version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (207.82.80.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 18 May 2015 18:13:36 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by uk-mta-2.uk.mimecast.lan; Mon, 18 May 2015 19:13:34 +0100 Received: from localhost ([10.1.2.79]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Mon, 18 May 2015 19:13:33 +0100 From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [2/9] Add a REG_NREGS macro References: <87oalhu59s.fsf@e105548-lin.cambridge.arm.com> Date: Mon, 18 May 2015 19:13:33 +0100 In-Reply-To: <87oalhu59s.fsf@e105548-lin.cambridge.arm.com> (Richard Sandiford's message of "Mon, 18 May 2015 19:09:19 +0100") Message-ID: <87fv6tu52q.fsf@e105548-lin.cambridge.arm.com> User-Agent: Gnus/5.130012 (Ma Gnus v0.12) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 X-MC-Unique: 4G15nREoTty8WmGqigp9hw-1 This patch adds a REG_NREGS macro that by the end of the series will simply be an rtx field access. The definition in this patch is just a placeholder (and so I haven't tried to avoid the double evaluation of the parameter). The diff has extra context because in most cases it makes it obvious that we really are looking at hard_regno_nregs[REGNO (x)][GET_MODE (x)] for some rtx x. There are a couple of sites where it's more indirect though. gcc/ * rtl.h (REG_NREGS): New macro * alias.c (record_set): Use it. * cfgcleanup.c (mark_effect): Likewise. * combine.c (likely_spilled_retval_1): Likewise. (likely_spilled_retval_p, can_change_dest_mode): Likewise. (move_deaths, distribute_notes): Likewise. * cselib.c (cselib_record_set): Likewise. * df-problems.c (df_simulate_one_insn_forwards): Likewise. * df-scan.c (df_mark_reg): Likewise. * dse.c (look_for_hardregs): Likewise. * dwarf2out.c (reg_loc_descriptor): Likewise. (multiple_reg_loc_descriptor): Likewise. * expr.c (write_complex_part, read_complex_part): Likewise. (emit_move_complex): Likewise. * haifa-sched.c (setup_ref_regs): Likewise. * ira-lives.c (mark_hard_reg_live): Likewise. * lra.c (lra_set_insn_recog_data): Likewise. * mode-switching.c (create_pre_exit): Likewise. * postreload.c (reload_combine_recognize_const_pattern): Likewise. (reload_combine_recognize_pattern): Likewise. (reload_combine_note_use, move2add_record_mode): Likewise. (reload_cse_move2add): Likewise. * reg-stack.c (subst_stack_regs_pat): Likewise. * regcprop.c (kill_value, copy_value): Likewise. (copyprop_hardreg_forward_1): Likewise. * regrename.c (verify_reg_in_set, scan_rtx_reg): Likewise. (build_def_use): Likewise. * sched-deps.c (mark_insn_reg_birth, mark_reg_death): Likewise. (deps_analyze_insn): Likewise. * sched-rgn.c (check_live_1, update_live_1): Likewise. * sel-sched.c (count_occurrences_equiv): Likewise. * valtrack.c (dead_debug_insert_temp): Likewise. Index: gcc/rtl.h =================================================================== --- gcc/rtl.h 2015-05-18 08:19:43.475431381 +0100 +++ gcc/rtl.h 2015-05-18 08:19:43.459431568 +0100 @@ -1692,16 +1692,24 @@ #define LABEL_REF_LABEL(LABREF) XCEXP (L /* For a REG rtx, REGNO extracts the register number. REGNO can only be used on RHS. Use SET_REGNO to change the value. */ #define REGNO(RTX) (rhs_regno(RTX)) #define SET_REGNO(RTX,N) \ (df_ref_change_reg_with_loc (REGNO (RTX), N, RTX), XCUINT (RTX, 0, REG) = N) #define SET_REGNO_RAW(RTX,N) (XCUINT (RTX, 0, REG) = N) +/* Return the number of consecutive registers in a REG. This is always + 1 for pseudo registers and is determined by HARD_REGNO_NREGS for + hard registers. */ +#define REG_NREGS(RTX) \ + (REGNO (RTX) < FIRST_PSEUDO_REGISTER \ + ? (unsigned int) hard_regno_nregs[REGNO (RTX)][GET_MODE (RTX)] \ + : 1) + /* ORIGINAL_REGNO holds the number the register originally had; for a pseudo register turned into a hard reg this will hold the old pseudo register number. */ #define ORIGINAL_REGNO(RTX) \ (RTL_FLAG_CHECK1 ("ORIGINAL_REGNO", (RTX), REG)->u2.original_regno) /* Force the REGNO macro to only be used on the lhs. */ static inline unsigned int Index: gcc/alias.c =================================================================== --- gcc/alias.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/alias.c 2015-05-18 08:19:43.455431618 +0100 @@ -1295,22 +1295,17 @@ record_set (rtx dest, const_rtx set, voi if (!REG_P (dest)) return; regno = REGNO (dest); gcc_checking_assert (regno < reg_base_value->length ()); - /* If this spans multiple hard registers, then we must indicate that every - register has an unusable value. */ - if (regno < FIRST_PSEUDO_REGISTER) - n = hard_regno_nregs[regno][GET_MODE (dest)]; - else - n = 1; + n = REG_NREGS (dest); if (n != 1) { while (--n >= 0) { bitmap_set_bit (reg_seen, regno + n); new_reg_base_value[regno + n] = 0; } return; Index: gcc/cfgcleanup.c =================================================================== --- gcc/cfgcleanup.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/cfgcleanup.c 2015-05-18 08:19:43.455431618 +0100 @@ -229,35 +229,33 @@ mark_effect (rtx exp, regset nonequal) /* In case we do clobber the register, mark it as equal, as we know the value is dead so it don't have to match. */ case CLOBBER: if (REG_P (XEXP (exp, 0))) { dest = XEXP (exp, 0); regno = REGNO (dest); if (HARD_REGISTER_NUM_P (regno)) - bitmap_clear_range (nonequal, regno, - hard_regno_nregs[regno][GET_MODE (dest)]); + bitmap_clear_range (nonequal, regno, REG_NREGS (dest)); else bitmap_clear_bit (nonequal, regno); } return false; case SET: if (rtx_equal_for_cselib_p (SET_DEST (exp), SET_SRC (exp))) return false; dest = SET_DEST (exp); if (dest == pc_rtx) return false; if (!REG_P (dest)) return true; regno = REGNO (dest); if (HARD_REGISTER_NUM_P (regno)) - bitmap_set_range (nonequal, regno, - hard_regno_nregs[regno][GET_MODE (dest)]); + bitmap_set_range (nonequal, regno, REG_NREGS (dest)); else bitmap_set_bit (nonequal, regno); return false; default: return false; } } Index: gcc/combine.c =================================================================== --- gcc/combine.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/combine.c 2015-05-18 08:19:43.459431568 +0100 @@ -2329,17 +2329,17 @@ likely_spilled_retval_1 (rtx x, const_rt unsigned regno, nregs; unsigned new_mask; if (!REG_P (XEXP (set, 0))) return; regno = REGNO (x); if (regno >= info->regno + info->nregs) return; - nregs = hard_regno_nregs[regno][GET_MODE (x)]; + nregs = REG_NREGS (x); if (regno + nregs <= info->regno) return; new_mask = (2U << (nregs - 1)) - 1; if (regno < info->regno) new_mask >>= info->regno - regno; else new_mask <<= regno - info->regno; info->mask &= ~new_mask; @@ -2364,17 +2364,17 @@ likely_spilled_retval_p (rtx_insn *insn) struct likely_spilled_retval_info info; if (!NONJUMP_INSN_P (use) || GET_CODE (PATTERN (use)) != USE || insn == use) return 0; reg = XEXP (PATTERN (use), 0); if (!REG_P (reg) || !targetm.calls.function_value_regno_p (REGNO (reg))) return 0; regno = REGNO (reg); - nregs = hard_regno_nregs[regno][GET_MODE (reg)]; + nregs = REG_NREGS (reg); if (nregs == 1) return 0; mask = (2U << (nregs - 1)) - 1; /* Disregard parts of the return value that are set later. */ info.regno = regno; info.nregs = nregs; info.mask = mask; @@ -2436,18 +2436,17 @@ can_change_dest_mode (rtx x, int added_s if (!REG_P (x)) return false; regno = REGNO (x); /* Allow hard registers if the new mode is legal, and occupies no more registers than the old mode. */ if (regno < FIRST_PSEUDO_REGISTER) return (HARD_REGNO_MODE_OK (regno, mode) - && (hard_regno_nregs[regno][GET_MODE (x)] - >= hard_regno_nregs[regno][mode])); + && REG_NREGS (x) >= hard_regno_nregs[regno][mode]); /* Or a pseudo that is only used once. */ return (regno < reg_n_sets_max && REG_N_SETS (regno) == 1 && !added_sets && !REG_USERVAR_P (x)); } @@ -13331,17 +13330,17 @@ move_deaths (rtx x, rtx maybe_kill_insn, register, then to be safe we must check for REG_DEAD notes for each register other than the first. They could have their own REG_DEAD notes lying around. */ else if ((note == 0 || (note != 0 && (GET_MODE_SIZE (GET_MODE (XEXP (note, 0))) < GET_MODE_SIZE (GET_MODE (x))))) && regno < FIRST_PSEUDO_REGISTER - && hard_regno_nregs[regno][GET_MODE (x)] > 1) + && REG_NREGS (x) > 1) { unsigned int ourend = END_HARD_REGNO (x); unsigned int i, offset; rtx oldnotes = 0; if (note) offset = hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))]; else @@ -13926,18 +13925,17 @@ distribute_notes (rtx notes, rtx_insn *f multiple registers, ensure that we are still using all parts of the object. If we find a piece of the object that is unused, we must arrange for an appropriate REG_DEAD note to be added for it. However, we can't just emit a USE and tag the note to it, since the register might actually be dead; so we recourse, and the recursive call then finds the previous insn that used this register. */ - if (place && regno < FIRST_PSEUDO_REGISTER - && hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))] > 1) + if (place && REG_NREGS (XEXP (note, 0)) > 1) { unsigned int endregno = END_HARD_REGNO (XEXP (note, 0)); bool all_used = true; unsigned int i; for (i = regno; i < endregno; i++) if ((! refers_to_regno_p (i, PATTERN (place)) && ! find_regno_fusage (place, USE, i)) Index: gcc/cselib.c =================================================================== --- gcc/cselib.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/cselib.c 2015-05-18 08:19:43.459431568 +0100 @@ -2366,26 +2366,25 @@ cselib_invalidate_rtx_note_stores (rtx d /* Record the result of a SET instruction. DEST is being set; the source contains the value described by SRC_ELT. If DEST is a MEM, DEST_ADDR_ELT describes its address. */ static void cselib_record_set (rtx dest, cselib_val *src_elt, cselib_val *dest_addr_elt) { - int dreg = REG_P (dest) ? (int) REGNO (dest) : -1; - if (src_elt == 0 || side_effects_p (dest)) return; - if (dreg >= 0) + if (REG_P (dest)) { + unsigned int dreg = REGNO (dest); if (dreg < FIRST_PSEUDO_REGISTER) { - unsigned int n = hard_regno_nregs[dreg][GET_MODE (dest)]; + unsigned int n = REG_NREGS (dest); if (n > max_value_regs) max_value_regs = n; } if (REG_VALUES (dreg) == 0) { used_regs[n_used_regs++] = dreg; Index: gcc/df-problems.c =================================================================== --- gcc/df-problems.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/df-problems.c 2015-05-18 08:19:43.459431568 +0100 @@ -3571,18 +3571,17 @@ df_simulate_one_insn_forwards (basic_blo switch (REG_NOTE_KIND (link)) { case REG_DEAD: case REG_UNUSED: { rtx reg = XEXP (link, 0); int regno = REGNO (reg); if (HARD_REGISTER_NUM_P (regno)) - bitmap_clear_range (live, regno, - hard_regno_nregs[regno][GET_MODE (reg)]); + bitmap_clear_range (live, regno, REG_NREGS (reg)); else bitmap_clear_bit (live, regno); } break; default: break; } } Index: gcc/df-scan.c =================================================================== --- gcc/df-scan.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/df-scan.c 2015-05-18 08:19:43.459431568 +0100 @@ -3511,20 +3511,17 @@ df_get_eh_block_artificial_uses (bitmap df_mark_reg (rtx reg, void *vset) { bitmap set = (bitmap) vset; int regno = REGNO (reg); gcc_assert (GET_MODE (reg) != BLKmode); if (regno < FIRST_PSEUDO_REGISTER) - { - int n = hard_regno_nregs[regno][GET_MODE (reg)]; - bitmap_set_range (set, regno, n); - } + bitmap_set_range (set, regno, REG_NREGS (reg)); else bitmap_set_bit (set, regno); } /* Set the bit for regs that are considered being defined at the entry. */ static void Index: gcc/dse.c =================================================================== --- gcc/dse.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/dse.c 2015-05-18 08:19:43.471431430 +0100 @@ -1871,21 +1871,17 @@ find_shift_sequence (int access_size, static void look_for_hardregs (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data) { bitmap regs_set = (bitmap) data; if (REG_P (x) && HARD_REGISTER_P (x)) - { - unsigned int regno = REGNO (x); - bitmap_set_range (regs_set, regno, - hard_regno_nregs[regno][GET_MODE (x)]); - } + bitmap_set_range (regs_set, REGNO (x), REG_NREGS (x)); } /* Helper function for replace_read and record_store. Attempt to return a value stored in STORE_INFO, from READ_BEGIN to one before READ_END bytes read in READ_MODE. Return NULL if not successful. If REQUIRE_CST is true, return always constant. */ static rtx Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/dwarf2out.c 2015-05-18 08:19:43.463431525 +0100 @@ -11142,17 +11142,17 @@ reg_loc_descriptor (rtx rtl, enum var_in add_loc_descr (&result, new_loc_descr (DW_OP_stack_value, 0, 0)); } return result; } regs = targetm.dwarf_register_span (rtl); - if (hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)] > 1 || regs) + if (REG_NREGS (rtl) > 1 || regs) return multiple_reg_loc_descriptor (rtl, regs, initialized); else { unsigned int dbx_regnum = dbx_reg_number (rtl); if (dbx_regnum == IGNORED_DWARF_REGNUM) return 0; return one_reg_loc_descriptor (dbx_regnum, initialized); } @@ -11199,17 +11199,17 @@ multiple_reg_loc_descriptor (rtx rtl, rt { int leaf_reg = LEAF_REG_REMAP (reg); if (leaf_reg != -1) reg = (unsigned) leaf_reg; } #endif gcc_assert ((unsigned) DBX_REGISTER_NUMBER (reg) == dbx_reg_number (rtl)); - nregs = hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)]; + nregs = REG_NREGS (rtl); size = GET_MODE_SIZE (GET_MODE (rtl)) / nregs; loc_result = NULL; while (nregs--) { dw_loc_descr_ref t; Index: gcc/expr.c =================================================================== --- gcc/expr.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/expr.c 2015-05-18 08:19:43.463431525 +0100 @@ -3046,17 +3046,17 @@ write_complex_part (rtx cplx, rtx val, b correspond to TCmode. */ if (ibitsize >= BITS_PER_WORD /* For hard regs we have exact predicates. Assume we can split the original object if it spans an even number of hard regs. This special case is important for SCmode on 64-bit platforms where the natural size of floating-point regs is 32-bit. */ || (REG_P (cplx) && REGNO (cplx) < FIRST_PSEUDO_REGISTER - && hard_regno_nregs[REGNO (cplx)][cmode] % 2 == 0)) + && REG_NREGS (cplx) % 2 == 0)) { rtx part = simplify_gen_subreg (imode, cplx, cmode, imag_p ? GET_MODE_SIZE (imode) : 0); if (part) { emit_move_insn (part, val); return; } @@ -3111,17 +3111,17 @@ read_complex_part (rtx cplx, bool imag_p correspond to TCmode. */ if (ibitsize >= BITS_PER_WORD /* For hard regs we have exact predicates. Assume we can split the original object if it spans an even number of hard regs. This special case is important for SCmode on 64-bit platforms where the natural size of floating-point regs is 32-bit. */ || (REG_P (cplx) && REGNO (cplx) < FIRST_PSEUDO_REGISTER - && hard_regno_nregs[REGNO (cplx)][cmode] % 2 == 0)) + && REG_NREGS (cplx) % 2 == 0)) { rtx ret = simplify_gen_subreg (imode, cplx, cmode, imag_p ? GET_MODE_SIZE (imode) : 0); if (ret) return ret; else /* simplify_gen_subreg may fail for sub-word MEMs. */ gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD); @@ -3341,20 +3341,20 @@ emit_move_complex (machine_mode mode, rt return emit_move_complex_push (mode, x, y); /* See if we can coerce the target into moving both values at once, except for floating point where we favor moving as parts if this is easy. */ if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT && optab_handler (mov_optab, GET_MODE_INNER (mode)) != CODE_FOR_nothing && !(REG_P (x) && HARD_REGISTER_P (x) - && hard_regno_nregs[REGNO (x)][mode] == 1) + && REG_NREGS (x) == 1) && !(REG_P (y) && HARD_REGISTER_P (y) - && hard_regno_nregs[REGNO (y)][mode] == 1)) + && REG_NREGS (y) == 1)) try_int = false; /* Not possible if the values are inherently not adjacent. */ else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT) try_int = false; /* Is possible if both are registers (or subregs of registers). */ else if (register_operand (x, mode) && register_operand (y, mode)) try_int = true; /* If one of the operands is a memory, and alignment constraints Index: gcc/haifa-sched.c =================================================================== --- gcc/haifa-sched.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/haifa-sched.c 2015-05-18 08:19:43.467431478 +0100 @@ -1035,18 +1035,17 @@ setup_ref_regs (rtx x) int i, j, regno; const RTX_CODE code = GET_CODE (x); const char *fmt; if (REG_P (x)) { regno = REGNO (x); if (HARD_REGISTER_NUM_P (regno)) - bitmap_set_range (region_ref_regs, regno, - hard_regno_nregs[regno][GET_MODE (x)]); + bitmap_set_range (region_ref_regs, regno, REG_NREGS (x)); else bitmap_set_bit (region_ref_regs, REGNO (x)); return; } fmt = GET_RTX_FORMAT (code); for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) if (fmt[i] == 'e') setup_ref_regs (XEXP (x, i)); Index: gcc/ira-lives.c =================================================================== --- gcc/ira-lives.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/ira-lives.c 2015-05-18 08:19:43.467431478 +0100 @@ -347,17 +347,17 @@ mark_pseudo_regno_subword_live (int regn actually needs. */ static void mark_hard_reg_live (rtx reg) { int regno = REGNO (reg); if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno)) { - int last = regno + hard_regno_nregs[regno][GET_MODE (reg)]; + int last = END_REGNO (reg); enum reg_class aclass, pclass; while (regno < last) { if (! TEST_HARD_REG_BIT (hard_regs_live, regno) && ! TEST_HARD_REG_BIT (eliminable_regset, regno)) { aclass = ira_hard_regno_allocno_class[regno]; Index: gcc/lra.c =================================================================== --- gcc/lra.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/lra.c 2015-05-18 08:19:43.467431478 +0100 @@ -1099,20 +1099,17 @@ lra_set_insn_recog_data (rtx_insn *insn) link != NULL_RTX; link = XEXP (link, 1)) if (GET_CODE (XEXP (link, 0)) == USE && REG_P (XEXP (XEXP (link, 0), 0))) { regno = REGNO (XEXP (XEXP (link, 0), 0)); lra_assert (regno < FIRST_PSEUDO_REGISTER); /* It is an argument register. */ - for (i = (hard_regno_nregs - [regno][GET_MODE (XEXP (XEXP (link, 0), 0))]) - 1; - i >= 0; - i--) + for (i = REG_NREGS (XEXP (XEXP (link, 0), 0)) - 1; i >= 0; i--) arg_hard_regs[n_hard_regs++] = regno + i; } if (n_hard_regs != 0) { arg_hard_regs[n_hard_regs++] = -1; data->arg_hard_regs = XNEWVEC (int, n_hard_regs); memcpy (data->arg_hard_regs, arg_hard_regs, sizeof (int) * n_hard_regs); Index: gcc/mode-switching.c =================================================================== --- gcc/mode-switching.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/mode-switching.c 2015-05-18 08:19:43.467431478 +0100 @@ -262,17 +262,17 @@ create_pre_exit (int n_entities, int *en insert the final mode switch before the return value copy to its hard register. */ if (EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) == 1 && NONJUMP_INSN_P ((last_insn = BB_END (src_bb))) && GET_CODE (PATTERN (last_insn)) == USE && GET_CODE ((ret_reg = XEXP (PATTERN (last_insn), 0))) == REG) { int ret_start = REGNO (ret_reg); - int nregs = hard_regno_nregs[ret_start][GET_MODE (ret_reg)]; + int nregs = REG_NREGS (ret_reg); int ret_end = ret_start + nregs; bool short_block = false; bool multi_reg_return = false; bool forced_late_switch = false; rtx_insn *before_return_copy; do { Index: gcc/postreload.c =================================================================== --- gcc/postreload.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/postreload.c 2015-05-18 08:19:43.455431618 +0100 @@ -969,17 +969,17 @@ reload_combine_recognize_const_pattern ( set = single_set (insn); if (set == NULL_RTX) return false; reg = SET_DEST (set); src = SET_SRC (set); if (!REG_P (reg) - || hard_regno_nregs[REGNO (reg)][GET_MODE (reg)] != 1 + || REG_NREGS (reg) != 1 || GET_MODE (reg) != Pmode || reg == stack_pointer_rtx) return false; regno = REGNO (reg); /* We look for a REG1 = REG2 + CONSTANT insn, followed by either uses of REG1 inside an address, or inside another add insn. If @@ -1104,18 +1104,17 @@ reload_combine_recognize_pattern (rtx_in unsigned int regno; set = single_set (insn); if (set == NULL_RTX) return false; reg = SET_DEST (set); src = SET_SRC (set); - if (!REG_P (reg) - || hard_regno_nregs[REGNO (reg)][GET_MODE (reg)] != 1) + if (!REG_P (reg) || REG_NREGS (reg) != 1) return false; regno = REGNO (reg); /* Look for (set (REGX) (CONST_INT)) (set (REGX) (PLUS (REGX) (REGY))) ... ... (MEM (REGX)) ... @@ -1561,17 +1560,17 @@ reload_combine_note_use (rtx *xp, rtx_in { int regno = REGNO (x); int use_index; int nregs; /* No spurious USEs of pseudo registers may remain. */ gcc_assert (regno < FIRST_PSEUDO_REGISTER); - nregs = hard_regno_nregs[regno][GET_MODE (x)]; + nregs = REG_NREGS (x); /* We can't substitute into multi-hard-reg uses. */ if (nregs > 1) { while (--nregs >= 0) reg_state[regno + nregs].use_index = -1; return; } @@ -1693,17 +1692,17 @@ move2add_record_mode (rtx reg) if (GET_CODE (reg) == SUBREG) { regno = subreg_regno (reg); nregs = subreg_nregs (reg); } else if (REG_P (reg)) { regno = REGNO (reg); - nregs = hard_regno_nregs[regno][mode]; + nregs = REG_NREGS (reg); } else gcc_unreachable (); for (int i = nregs - 1; i > 0; i--) reg_mode[regno + i] = BLKmode; reg_mode[regno] = mode; } @@ -2133,17 +2132,17 @@ reload_cse_move2add (rtx_insn *first) && GET_CODE (cnd) == NE && REG_P (XEXP (cnd, 0)) && !reg_set_p (XEXP (cnd, 0), insn) /* The following two checks, which are also in move2add_note_store, are intended to reduce the number of calls to gen_rtx_SET to avoid memory allocation if possible. */ && SCALAR_INT_MODE_P (GET_MODE (XEXP (cnd, 0))) - && hard_regno_nregs[REGNO (XEXP (cnd, 0))][GET_MODE (XEXP (cnd, 0))] == 1 + && REG_NREGS (XEXP (cnd, 0)) == 1 && CONST_INT_P (XEXP (cnd, 1))) { rtx implicit_set = gen_rtx_SET (XEXP (cnd, 0), XEXP (cnd, 1)); move2add_note_store (SET_DEST (implicit_set), implicit_set, insn); } } Index: gcc/reg-stack.c =================================================================== --- gcc/reg-stack.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/reg-stack.c 2015-05-18 08:19:43.467431478 +0100 @@ -1475,18 +1475,17 @@ subst_stack_regs_pat (rtx_insn *insn, st { case COMPARE: compare_for_stack_reg (insn, regstack, pat_src); break; case CALL: { int count; - for (count = hard_regno_nregs[REGNO (*dest)][GET_MODE (*dest)]; - --count >= 0;) + for (count = REG_NREGS (*dest); --count >= 0;) { regstack->reg[++regstack->top] = REGNO (*dest) + count; SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest) + count); } } replace_reg (dest, FIRST_STACK_REG); break; Index: gcc/regcprop.c =================================================================== --- gcc/regcprop.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/regcprop.c 2015-05-18 08:19:43.467431478 +0100 @@ -202,22 +202,17 @@ kill_value (const_rtx x, struct value_da { if (GET_CODE (x) == SUBREG) { rtx tmp = simplify_subreg (GET_MODE (x), SUBREG_REG (x), GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x)); x = tmp ? tmp : SUBREG_REG (x); } if (REG_P (x)) - { - unsigned int regno = REGNO (x); - unsigned int n = hard_regno_nregs[regno][GET_MODE (x)]; - - kill_value_regno (regno, n, vd); - } + kill_value_regno (REGNO (x), REG_NREGS (x), vd); } /* Remember that REGNO is valid in MODE. */ static void set_value_regno (unsigned int regno, machine_mode mode, struct value_data *vd) { @@ -328,18 +323,18 @@ copy_value (rtx dest, rtx src, struct va /* Do not propagate copies to fixed or global registers, patterns can be relying to see particular fixed register or users can expect the chosen global register in asm. */ if (fixed_regs[dr] || global_regs[dr]) return; /* If SRC and DEST overlap, don't record anything. */ - dn = hard_regno_nregs[dr][GET_MODE (dest)]; - sn = hard_regno_nregs[sr][GET_MODE (dest)]; + dn = REG_NREGS (dest); + sn = REG_NREGS (src); if ((dr > sr && dr < sr + sn) || (sr > dr && sr < dr + dn)) return; /* If SRC had no assigned mode (i.e. we didn't know it was live) assign it now and assume the value came from an input argument or somesuch. */ if (vd->e[sr].mode == VOIDmode) @@ -1030,18 +1025,17 @@ copyprop_hardreg_forward_1 (basic_block if (GET_CODE (x) == SET) { rtx dest = SET_DEST (x); kill_value (dest, vd); set_value_regno (REGNO (dest), GET_MODE (dest), vd); copy_value (dest, SET_SRC (x), vd); ksvd.ignore_set_reg = dest; set_regno = REGNO (dest); - set_nregs - = hard_regno_nregs[set_regno][GET_MODE (dest)]; + set_nregs = REG_NREGS (dest); break; } } get_call_reg_set_usage (insn, ®s_invalidated_by_this_call, regs_invalidated_by_call); for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) Index: gcc/regrename.c =================================================================== --- gcc/regrename.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/regrename.c 2015-05-18 08:19:43.467431478 +0100 @@ -978,17 +978,17 @@ regrename_do_replace (struct du_head *he verify_reg_in_set (rtx op, HARD_REG_SET *pset) { unsigned regno, nregs; bool all_live, all_dead; if (!REG_P (op)) return false; regno = REGNO (op); - nregs = hard_regno_nregs[regno][GET_MODE (op)]; + nregs = REG_NREGS (op); all_live = all_dead = true; while (nregs-- > 0) if (TEST_HARD_REG_BIT (*pset, regno + nregs)) all_dead = false; else all_live = false; if (!all_dead && !all_live) { @@ -1031,19 +1031,18 @@ note_sets_clobbers (rtx x, const_rtx set } static void scan_rtx_reg (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action, enum op_type type) { struct du_head **p; rtx x = *loc; - machine_mode mode = GET_MODE (x); unsigned this_regno = REGNO (x); - int this_nregs = hard_regno_nregs[this_regno][mode]; + int this_nregs = REG_NREGS (x); if (action == mark_write) { if (type == OP_OUT) create_new_chain (this_regno, this_nregs, loc, insn, cl); return; } @@ -1619,23 +1618,18 @@ build_def_use (basic_block bb) } } /* If there's an in-out operand with a register that is not being tracked at all yet, open a chain. */ if (recog_data.operand_type[i] == OP_INOUT && !(untracked_operands & (1 << i)) && REG_P (op) && !verify_reg_tracked (op)) - { - machine_mode mode = GET_MODE (op); - unsigned this_regno = REGNO (op); - unsigned this_nregs = hard_regno_nregs[this_regno][mode]; - create_new_chain (this_regno, this_nregs, NULL, NULL, - NO_REGS); - } + create_new_chain (REGNO (op), REG_NREGS (op), NULL, NULL, + NO_REGS); } if (fail_current_block) break; /* Step 1a: Mark hard registers that are clobbered in this insn, outside an operand, as live. */ hide_operands (n_ops, old_operands, old_dups, untracked_operands, Index: gcc/sched-deps.c =================================================================== --- gcc/sched-deps.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/sched-deps.c 2015-05-18 08:19:43.467431478 +0100 @@ -2120,18 +2120,17 @@ mark_insn_reg_birth (rtx insn, rtx reg, if (GET_CODE (reg) == SUBREG) reg = SUBREG_REG (reg); if (! REG_P (reg)) return; regno = REGNO (reg); if (regno < FIRST_PSEUDO_REGISTER) - mark_insn_hard_regno_birth (insn, regno, - hard_regno_nregs[regno][GET_MODE (reg)], + mark_insn_hard_regno_birth (insn, regno, REG_NREGS (reg), clobber_p, unused_p); else mark_insn_pseudo_birth (insn, regno, clobber_p, unused_p); } /* Update the register pressure info after death of pseudo register REGNO. */ static void @@ -2180,17 +2179,17 @@ mark_reg_death (rtx reg) if (GET_CODE (reg) == SUBREG) reg = SUBREG_REG (reg); if (! REG_P (reg)) return; regno = REGNO (reg); if (regno < FIRST_PSEUDO_REGISTER) - mark_hard_regno_death (regno, hard_regno_nregs[regno][GET_MODE (reg)]); + mark_hard_regno_death (regno, REG_NREGS (reg)); else mark_pseudo_death (regno); } /* Process SETTER of REG. DATA is an insn containing the setter. */ static void mark_insn_reg_store (rtx reg, const_rtx setter, void *data) { @@ -3640,17 +3639,17 @@ deps_analyze_insn (struct deps_desc *dep && REG_P (XEXP (t, 0)) && CONSTANT_P (XEXP (t, 1))) { unsigned int regno; int nregs; rtx_insn_list *cond_deps = NULL; t = XEXP (t, 0); regno = REGNO (t); - nregs = hard_regno_nregs[regno][GET_MODE (t)]; + nregs = REG_NREGS (t); while (nregs-- > 0) { struct deps_reg *reg_last = &deps->reg_last[regno + nregs]; cond_deps = concat_INSN_LIST (reg_last->sets, cond_deps); cond_deps = concat_INSN_LIST (reg_last->clobbers, cond_deps); cond_deps = concat_INSN_LIST (reg_last->implicit_sets, cond_deps); } INSN_COND_DEPS (insn) = cond_deps; Index: gcc/sched-rgn.c =================================================================== --- gcc/sched-rgn.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/sched-rgn.c 2015-05-18 08:19:43.467431478 +0100 @@ -1715,17 +1715,17 @@ check_live_1 (int src, rtx x) /* Global registers are assumed live. */ return 0; } else { if (regno < FIRST_PSEUDO_REGISTER) { /* Check for hard registers. */ - int j = hard_regno_nregs[regno][GET_MODE (reg)]; + int j = REG_NREGS (reg); while (--j >= 0) { for (i = 0; i < candidate_table[src].split_bbs.nr_members; i++) { basic_block b = candidate_table[src].split_bbs.first_member[i]; int t = bitmap_bit_p (¬_in_df, b->index); /* We can have split blocks, that were recently generated. @@ -1798,18 +1798,17 @@ update_live_1 (int src, rtx x) if (! HARD_REGISTER_NUM_P (regno) || !global_regs[regno]) { for (i = 0; i < candidate_table[src].update_bbs.nr_members; i++) { basic_block b = candidate_table[src].update_bbs.first_member[i]; if (HARD_REGISTER_NUM_P (regno)) - bitmap_set_range (df_get_live_in (b), regno, - hard_regno_nregs[regno][GET_MODE (reg)]); + bitmap_set_range (df_get_live_in (b), regno, REG_NREGS (reg)); else bitmap_set_bit (df_get_live_in (b), regno); } } } /* Return 1 if insn can be speculatively moved from block src to trg, otherwise return 0. Called before first insertion of insn to Index: gcc/sel-sched.c =================================================================== --- gcc/sel-sched.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/sel-sched.c 2015-05-18 08:19:43.471431430 +0100 @@ -820,19 +820,17 @@ count_occurrences_equiv (const_rtx what, subrtx_iterator::array_type array; FOR_EACH_SUBRTX (iter, array, where, NONCONST) { const_rtx x = *iter; if (REG_P (x) && REGNO (x) == REGNO (what)) { /* Bail out if mode is different or more than one register is used. */ - if (GET_MODE (x) != GET_MODE (what) - || (HARD_REGISTER_P (x) - && hard_regno_nregs[REGNO (x)][GET_MODE (x)] > 1)) + if (GET_MODE (x) != GET_MODE (what) || REG_NREGS (x) > 1) return 0; count += 1; } else if (GET_CODE (x) == SUBREG && (!REG_P (SUBREG_REG (x)) || REGNO (SUBREG_REG (x)) == REGNO (what))) /* ??? Do not support substituting regs inside subregs. In that case, simplify_subreg will be called by validate_replace_rtx, and Index: gcc/valtrack.c =================================================================== --- gcc/valtrack.c 2015-05-18 08:19:43.475431381 +0100 +++ gcc/valtrack.c 2015-05-18 08:19:43.471431430 +0100 @@ -666,19 +666,17 @@ dead_debug_insert_temp (struct dead_debu /* Hmm... Something's fishy, we should be setting REG here. */ if (REGNO (dest) != REGNO (reg)) breg = NULL; /* If we're not overwriting all the hardware registers that setting REG in its mode would, we won't know what to bind the debug temp to. ??? We could bind the debug_expr to a CONCAT or PARALLEL with the split multi-registers, and replace them as we found the corresponding sets. */ - else if (REGNO (reg) < FIRST_PSEUDO_REGISTER - && (hard_regno_nregs[REGNO (reg)][GET_MODE (reg)] - != hard_regno_nregs[REGNO (reg)][GET_MODE (dest)])) + else if (REG_NREGS (reg) != REG_NREGS (dest)) breg = NULL; /* Ok, it's the same (hardware) REG, but with a different mode, so SUBREG it. */ else breg = debug_lowpart_subreg (GET_MODE (reg), cleanup_auto_inc_dec (src, VOIDmode), GET_MODE (dest)); } @@ -690,17 +688,17 @@ dead_debug_insert_temp (struct dead_debu /* Lose if we're setting something other than the lowpart of REG. */ else if (!subreg_lowpart_p (dest)) breg = NULL; /* If we're not overwriting all the hardware registers that setting REG in its mode would, we won't know what to bind the debug temp to. */ else if (REGNO (reg) < FIRST_PSEUDO_REGISTER - && (hard_regno_nregs[REGNO (reg)][GET_MODE (reg)] + && (REG_NREGS (reg) != hard_regno_nregs[REGNO (reg)][GET_MODE (dest)])) breg = NULL; /* Yay, we can use SRC, just adjust its mode. */ else breg = debug_lowpart_subreg (GET_MODE (reg), cleanup_auto_inc_dec (src, VOIDmode), GET_MODE (dest)); }