This patch just handles some obvious cases where END_REGNO could be used.
gcc/ * cfgcleanup.c (mentions_nonequal_regs): Use END_REGNO. * dse.c (note_add_store): Likewise. * ira-lives.c (mark_hard_reg_dead): Likewise. * loop-invariant.c (mark_reg_store): Likewise. (mark_reg_death): Likewise. * postreload.c (reload_combine): Likewise. (reload_combine_note_store): Likewise. (reload_combine_note_use): Likewise. * recog.c (peep2_reg_dead_p): Likewise. Index: gcc/cfgcleanup.c =================================================================== --- gcc/cfgcleanup.c 2015-05-18 08:19:38.719489341 +0100 +++ gcc/cfgcleanup.c 2015-05-18 08:19:52.000000000 +0100 @@ -267,26 +267,20 @@ mark_effect (rtx exp, regset nonequal) mentions_nonequal_regs (const_rtx x, regset nonequal) { subrtx_iterator::array_type array; FOR_EACH_SUBRTX (iter, array, x, NONCONST) { const_rtx x = *iter; if (REG_P (x)) { - unsigned int regno = REGNO (x); - if (REGNO_REG_SET_P (nonequal, regno)) - return true; - if (regno < FIRST_PSEUDO_REGISTER) - { - int n = hard_regno_nregs[regno][GET_MODE (x)]; - while (--n > 0) - if (REGNO_REG_SET_P (nonequal, regno + n)) - return true; - } + unsigned int end_regno = END_REGNO (x); + for (unsigned int regno = REGNO (x); regno < end_regno; ++regno) + if (REGNO_REG_SET_P (nonequal, regno)) + return true; } } return false; } /* Attempt to prove that the basic block B will have no side effects and always continues in the same edge if reached via E. Return the edge if exist, NULL otherwise. */ Index: gcc/dse.c =================================================================== --- gcc/dse.c 2015-05-18 08:19:38.719489341 +0100 +++ gcc/dse.c 2015-05-18 08:19:52.000000000 +0100 @@ -850,17 +850,16 @@ typedef struct /* Callback for emit_inc_dec_insn_before via note_stores. Check if a register is clobbered which is live afterwards. */ static void note_add_store (rtx loc, const_rtx expr ATTRIBUTE_UNUSED, void *data) { rtx_insn *insn; note_add_store_info *info = (note_add_store_info *) data; - int r, n; if (!REG_P (loc)) return; /* If this register is referenced by the current or an earlier insn, that's OK. E.g. this applies to the register that is being incremented with this addition. */ for (insn = info->first; @@ -869,25 +868,24 @@ note_add_store (rtx loc, const_rtx expr if (reg_referenced_p (loc, PATTERN (insn))) return; /* If we come here, we have a clobber of a register that's only OK if that register is not live. If we don't have liveness information available, fail now. */ if (!info->fixed_regs_live) { - info->failure = true; + info->failure = true; return; } /* Now check if this is a live fixed register. */ - r = REGNO (loc); - n = hard_regno_nregs[r][GET_MODE (loc)]; - while (--n >= 0) - if (REGNO_REG_SET_P (info->fixed_regs_live, r+n)) - info->failure = true; + unsigned int end_regno = END_REGNO (loc); + for (unsigned int regno = REGNO (loc); regno < end_regno; ++regno) + if (REGNO_REG_SET_P (info->fixed_regs_live, regno)) + info->failure = true; } /* Callback for for_each_inc_dec that emits an INSN that sets DEST to SRC + SRCOFF before insn ARG. */ static int emit_inc_dec_insn_before (rtx mem ATTRIBUTE_UNUSED, rtx op ATTRIBUTE_UNUSED, Index: gcc/ira-lives.c =================================================================== --- gcc/ira-lives.c 2015-05-18 08:19:38.719489341 +0100 +++ gcc/ira-lives.c 2015-05-18 08:19:52.000000000 +0100 @@ -473,17 +473,17 @@ mark_pseudo_regno_subword_dead (int regn register. */ static void mark_hard_reg_dead (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)) { aclass = ira_hard_regno_allocno_class[regno]; pclass = ira_pressure_class_translate[aclass]; Index: gcc/loop-invariant.c =================================================================== --- gcc/loop-invariant.c 2015-05-18 08:19:38.719489341 +0100 +++ gcc/loop-invariant.c 2015-05-18 08:19:38.719489341 +0100 @@ -1802,68 +1802,44 @@ mark_regno_death (int regno) change_pressure (regno, false); } /* Mark setting register REG. */ static void mark_reg_store (rtx reg, const_rtx setter ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED) { - int regno; - if (GET_CODE (reg) == SUBREG) reg = SUBREG_REG (reg); if (! REG_P (reg)) return; regs_set[n_regs_set++] = reg; - regno = REGNO (reg); - - if (regno >= FIRST_PSEUDO_REGISTER) + unsigned int end_regno = END_REGNO (reg); + for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno) mark_regno_live (regno); - else - { - int last = regno + hard_regno_nregs[regno][GET_MODE (reg)]; - - while (regno < last) - { - mark_regno_live (regno); - regno++; - } - } } /* Mark clobbering register REG. */ static void mark_reg_clobber (rtx reg, const_rtx setter, void *data) { if (GET_CODE (setter) == CLOBBER) mark_reg_store (reg, setter, data); } /* Mark register REG death. */ static void mark_reg_death (rtx reg) { - int regno = REGNO (reg); - - if (regno >= FIRST_PSEUDO_REGISTER) + unsigned int end_regno = END_REGNO (reg); + for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno) mark_regno_death (regno); - else - { - int last = regno + hard_regno_nregs[regno][GET_MODE (reg)]; - - while (regno < last) - { - mark_regno_death (regno); - regno++; - } - } } /* Mark occurrence of registers in X for the current loop. */ static void mark_ref_regs (rtx x) { RTX_CODE code; int i; Index: gcc/postreload.c =================================================================== --- gcc/postreload.c 2015-05-18 08:19:38.719489341 +0100 +++ gcc/postreload.c 2015-05-18 08:19:52.000000000 +0100 @@ -1372,22 +1372,18 @@ reload_combine (void) for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1)) { rtx setuse = XEXP (link, 0); rtx usage_rtx = XEXP (setuse, 0); if ((GET_CODE (setuse) == USE || GET_CODE (setuse) == CLOBBER) && REG_P (usage_rtx)) { - unsigned int i; - unsigned int start_reg = REGNO (usage_rtx); - unsigned int num_regs - = hard_regno_nregs[start_reg][GET_MODE (usage_rtx)]; - unsigned int end_reg = start_reg + num_regs - 1; - for (i = start_reg; i <= end_reg; i++) + unsigned int end_regno = END_REGNO (usage_rtx); + for (unsigned int i = REGNO (usage_rtx); i < end_regno; ++i) if (GET_CODE (XEXP (link, 0)) == CLOBBER) { reg_state[i].use_index = RELOAD_COMBINE_MAX_USES; reg_state[i].store_ruid = reload_combine_ruid; } else reg_state[i].use_index = -1; } @@ -1459,19 +1455,18 @@ reload_combine_note_store (rtx dst, cons if (MEM_P (dst)) { dst = XEXP (dst, 0); if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC || GET_CODE (dst) == PRE_MODIFY || GET_CODE (dst) == POST_MODIFY) { - regno = REGNO (XEXP (dst, 0)); - mode = GET_MODE (XEXP (dst, 0)); - for (i = hard_regno_nregs[regno][mode] - 1 + regno; i >= regno; i--) + unsigned int end_regno = END_REGNO (XEXP (dst, 0)); + for (unsigned int i = REGNO (XEXP (dst, 0)); i < end_regno; ++i) { /* We could probably do better, but for now mark the register as used in an unknown fashion and set/clobbered at this insn. */ reg_state[i].use_index = -1; reg_state[i].store_ruid = reload_combine_ruid; reg_state[i].real_store_ruid = reload_combine_ruid; } @@ -1531,23 +1526,21 @@ reload_combine_note_use (rtx *xp, rtx_in return; } break; case USE: /* If this is the USE of a return value, we can't change it. */ if (REG_P (XEXP (x, 0)) && REG_FUNCTION_VALUE_P (XEXP (x, 0))) { - /* Mark the return register as used in an unknown fashion. */ + /* Mark the return register as used in an unknown fashion. */ rtx reg = XEXP (x, 0); - int regno = REGNO (reg); - int nregs = hard_regno_nregs[regno][GET_MODE (reg)]; - - while (--nregs >= 0) - reg_state[regno + nregs].use_index = -1; + unsigned int end_regno = END_REGNO (reg); + for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno) + reg_state[regno].use_index = -1; return; } break; case CLOBBER: if (REG_P (SET_DEST (x))) { /* No spurious CLOBBERs of pseudo registers may remain. */ Index: gcc/recog.c =================================================================== --- gcc/recog.c 2015-05-18 08:19:38.719489341 +0100 +++ gcc/recog.c 2015-05-18 08:19:38.719489341 +0100 @@ -3123,28 +3123,25 @@ peep2_regno_dead_p (int ofs, int regno) return ! REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno); } /* Similarly for a REG. */ int peep2_reg_dead_p (int ofs, rtx reg) { - int regno, n; - gcc_assert (ofs < MAX_INSNS_PER_PEEP2 + 1); ofs = peep2_buf_position (peep2_current + ofs); gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX); - regno = REGNO (reg); - n = hard_regno_nregs[regno][GET_MODE (reg)]; - while (--n >= 0) - if (REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno + n)) + unsigned int end_regno = END_REGNO (reg); + for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno) + if (REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno)) return 0; return 1; } /* Regno offset to be used in the register search. */ static int search_ofs; /* Try to find a hard register of mode MODE, matching the register class in