Convert hard_regno_nregs to a function

Message ID 87ingpcfyt.fsf@linaro.org
State New
Headers show
Series
  • Convert hard_regno_nregs to a function
Related show

Commit Message

Richard Sandiford Sept. 11, 2017, 5:17 p.m.
This patch converts hard_regno_nregs into an inline function, which
in turn allows hard_regno_nregs to be used as the name of a targetm
field.  This is just a mechanical change.

Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu.
Also tested by comparing the testsuite assembly output on at least one
target per CPU directory.  OK to install?

Richard


2017-09-11  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	* regs.h (hard_regno_nregs): Turn into a function.
	(end_hard_regno): Update accordingly.
	* caller-save.c (setup_save_areas): Likewise.
	(save_call_clobbered_regs): Likewise.
	(replace_reg_with_saved_mem): Likewise.
	(insert_restore): Likewise.
	(insert_save): Likewise.
	* combine.c (can_change_dest_mode): Likewise.
	(move_deaths): Likewise.
	(distribute_notes): Likewise.
	* config/mips/mips.c (mips_hard_regno_call_part_clobbered): Likewise.
	* config/powerpcspe/powerpcspe.c (rs6000_cannot_change_mode_class)
	(rs6000_split_multireg_move): Likewise.
	(rs6000_register_move_cost): Likewise.
	(rs6000_memory_move_cost): Likewise.
	* config/rs6000/rs6000.c (rs6000_cannot_change_mode_class): Likewise.
	(rs6000_split_multireg_move): Likewise.
	(rs6000_register_move_cost): Likewise.
	(rs6000_memory_move_cost): Likewise.
	* cselib.c (cselib_reset_table): Likewise.
	(cselib_lookup_1): Likewise.
	* emit-rtl.c (set_mode_and_regno): Likewise.
	* function.c (aggregate_value_p): Likewise.
	* ira-color.c (setup_profitable_hard_regs): Likewise.
	(check_hard_reg_p): Likewise.
	(calculate_saved_nregs): Likewise.
	(assign_hard_reg): Likewise.
	(improve_allocation): Likewise.
	(calculate_spill_cost): Likewise.
	* ira-emit.c (modify_move_list): Likewise.
	* ira-int.h (ira_hard_reg_set_intersection_p): Likewise.
	(ira_hard_reg_in_set_p): Likewise.
	* ira.c (setup_reg_mode_hard_regset): Likewise.
	(clarify_prohibited_class_mode_regs): Likewise.
	(check_allocation): Likewise.
	* lra-assigns.c (find_hard_regno_for_1): Likewise.
	(lra_setup_reg_renumber): Likewise.
	(setup_try_hard_regno_pseudos): Likewise.
	(spill_for): Likewise.
	(assign_hard_regno): Likewise.
	(setup_live_pseudos_and_spill_after_risky_transforms): Likewise.
	* lra-constraints.c (in_class_p): Likewise.
	(lra_constraint_offset): Likewise.
	(simplify_operand_subreg): Likewise.
	(lra_constraints): Likewise.
	(split_reg): Likewise.
	(split_if_necessary): Likewise.
	(invariant_p): Likewise.
	(inherit_in_ebb): Likewise.
	* lra-lives.c (process_bb_lives): Likewise.
	* lra-remat.c (reg_overlap_for_remat_p): Likewise.
	(get_hard_regs): Likewise.
	(do_remat): Likewise.
	* lra-spills.c (assign_spill_hard_regs): Likewise.
	* mode-switching.c (create_pre_exit): Likewise.
	* postreload.c (reload_combine_recognize_pattern): Likewise.
	* recog.c (peep2_find_free_register): Likewise.
	* regcprop.c (kill_value_regno): Likewise.
	(set_value_regno): Likewise.
	(copy_value): Likewise.
	(maybe_mode_change): Likewise.
	(find_oldest_value_reg): Likewise.
	(copyprop_hardreg_forward_1): Likewise.
	* regrename.c (check_new_reg_p): Likewise.
	(regrename_do_replace): Likewise.
	* reload.c (push_reload): Likewise.
	(combine_reloads): Likewise.
	(find_dummy_reload): Likewise.
	(operands_match_p): Likewise.
	(find_reloads): Likewise.
	(find_equiv_reg): Likewise.
	(reload_adjust_reg_for_mode): Likewise.
	* reload1.c (count_pseudo): Likewise.
	(count_spilled_pseudo): Likewise.
	(find_reg): Likewise.
	(clear_reload_reg_in_use): Likewise.
	(free_for_value_p): Likewise.
	(allocate_reload_reg): Likewise.
	(choose_reload_regs): Likewise.
	(reload_adjust_reg_for_temp): Likewise.
	(emit_reload_insns): Likewise.
	(delete_output_reload): Likewise.
	* rtlanal.c (subreg_get_info): Likewise.
	* sched-deps.c (sched_analyze_reg): Likewise.
	* sel-sched.c (init_regs_for_mode): Likewise.
	(mark_unavailable_hard_regs): Likewise.
	(choose_best_reg_1): Likewise.
	(verify_target_availability): Likewise.
	* valtrack.c (dead_debug_insert_temp): Likewise.
	* var-tracking.c (track_loc_p): Likewise.
	(emit_note_insn_var_location): Likewise.
	* varasm.c (make_decl_rtl): Likewise.
	* reginfo.c (choose_hard_reg_mode): Likewise.
	(init_reg_modes_target): Refer directly to
	this_target_regs->x_hard_regno_nregs.

Comments

Jeff Law Sept. 11, 2017, 10:27 p.m. | #1
On 09/11/2017 11:17 AM, Richard Sandiford wrote:
> This patch converts hard_regno_nregs into an inline function, which
> in turn allows hard_regno_nregs to be used as the name of a targetm
> field.  This is just a mechanical change.
> 
> Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu.
> Also tested by comparing the testsuite assembly output on at least one
> target per CPU directory.  OK to install?
> 
> Richard
> 
> 
> 2017-09-11  Richard Sandiford  <richard.sandiford@linaro.org>
> 
> gcc/
> 	* regs.h (hard_regno_nregs): Turn into a function.
> 	(end_hard_regno): Update accordingly.
> 	* caller-save.c (setup_save_areas): Likewise.
> 	(save_call_clobbered_regs): Likewise.
> 	(replace_reg_with_saved_mem): Likewise.
> 	(insert_restore): Likewise.
> 	(insert_save): Likewise.
> 	* combine.c (can_change_dest_mode): Likewise.
> 	(move_deaths): Likewise.
> 	(distribute_notes): Likewise.
> 	* config/mips/mips.c (mips_hard_regno_call_part_clobbered): Likewise.
> 	* config/powerpcspe/powerpcspe.c (rs6000_cannot_change_mode_class)
> 	(rs6000_split_multireg_move): Likewise.
> 	(rs6000_register_move_cost): Likewise.
> 	(rs6000_memory_move_cost): Likewise.
> 	* config/rs6000/rs6000.c (rs6000_cannot_change_mode_class): Likewise.
> 	(rs6000_split_multireg_move): Likewise.
> 	(rs6000_register_move_cost): Likewise.
> 	(rs6000_memory_move_cost): Likewise.
> 	* cselib.c (cselib_reset_table): Likewise.
> 	(cselib_lookup_1): Likewise.
> 	* emit-rtl.c (set_mode_and_regno): Likewise.
> 	* function.c (aggregate_value_p): Likewise.
> 	* ira-color.c (setup_profitable_hard_regs): Likewise.
> 	(check_hard_reg_p): Likewise.
> 	(calculate_saved_nregs): Likewise.
> 	(assign_hard_reg): Likewise.
> 	(improve_allocation): Likewise.
> 	(calculate_spill_cost): Likewise.
> 	* ira-emit.c (modify_move_list): Likewise.
> 	* ira-int.h (ira_hard_reg_set_intersection_p): Likewise.
> 	(ira_hard_reg_in_set_p): Likewise.
> 	* ira.c (setup_reg_mode_hard_regset): Likewise.
> 	(clarify_prohibited_class_mode_regs): Likewise.
> 	(check_allocation): Likewise.
> 	* lra-assigns.c (find_hard_regno_for_1): Likewise.
> 	(lra_setup_reg_renumber): Likewise.
> 	(setup_try_hard_regno_pseudos): Likewise.
> 	(spill_for): Likewise.
> 	(assign_hard_regno): Likewise.
> 	(setup_live_pseudos_and_spill_after_risky_transforms): Likewise.
> 	* lra-constraints.c (in_class_p): Likewise.
> 	(lra_constraint_offset): Likewise.
> 	(simplify_operand_subreg): Likewise.
> 	(lra_constraints): Likewise.
> 	(split_reg): Likewise.
> 	(split_if_necessary): Likewise.
> 	(invariant_p): Likewise.
> 	(inherit_in_ebb): Likewise.
> 	* lra-lives.c (process_bb_lives): Likewise.
> 	* lra-remat.c (reg_overlap_for_remat_p): Likewise.
> 	(get_hard_regs): Likewise.
> 	(do_remat): Likewise.
> 	* lra-spills.c (assign_spill_hard_regs): Likewise.
> 	* mode-switching.c (create_pre_exit): Likewise.
> 	* postreload.c (reload_combine_recognize_pattern): Likewise.
> 	* recog.c (peep2_find_free_register): Likewise.
> 	* regcprop.c (kill_value_regno): Likewise.
> 	(set_value_regno): Likewise.
> 	(copy_value): Likewise.
> 	(maybe_mode_change): Likewise.
> 	(find_oldest_value_reg): Likewise.
> 	(copyprop_hardreg_forward_1): Likewise.
> 	* regrename.c (check_new_reg_p): Likewise.
> 	(regrename_do_replace): Likewise.
> 	* reload.c (push_reload): Likewise.
> 	(combine_reloads): Likewise.
> 	(find_dummy_reload): Likewise.
> 	(operands_match_p): Likewise.
> 	(find_reloads): Likewise.
> 	(find_equiv_reg): Likewise.
> 	(reload_adjust_reg_for_mode): Likewise.
> 	* reload1.c (count_pseudo): Likewise.
> 	(count_spilled_pseudo): Likewise.
> 	(find_reg): Likewise.
> 	(clear_reload_reg_in_use): Likewise.
> 	(free_for_value_p): Likewise.
> 	(allocate_reload_reg): Likewise.
> 	(choose_reload_regs): Likewise.
> 	(reload_adjust_reg_for_temp): Likewise.
> 	(emit_reload_insns): Likewise.
> 	(delete_output_reload): Likewise.
> 	* rtlanal.c (subreg_get_info): Likewise.
> 	* sched-deps.c (sched_analyze_reg): Likewise.
> 	* sel-sched.c (init_regs_for_mode): Likewise.
> 	(mark_unavailable_hard_regs): Likewise.
> 	(choose_best_reg_1): Likewise.
> 	(verify_target_availability): Likewise.
> 	* valtrack.c (dead_debug_insert_temp): Likewise.
> 	* var-tracking.c (track_loc_p): Likewise.
> 	(emit_note_insn_var_location): Likewise.
> 	* varasm.c (make_decl_rtl): Likewise.
> 	* reginfo.c (choose_hard_reg_mode): Likewise.
> 	(init_reg_modes_target): Refer directly to
> 	this_target_regs->x_hard_regno_nregs.
OK.
jeff

Patch

Index: gcc/regs.h
===================================================================
--- gcc/regs.h	2017-09-04 11:48:57.532452460 +0100
+++ gcc/regs.h	2017-09-11 17:22:43.390274374 +0100
@@ -232,9 +232,6 @@  struct target_regs {
 #else
 #define this_target_regs (&default_target_regs)
 #endif
-
-#define hard_regno_nregs \
-  (this_target_regs->x_hard_regno_nregs)
 #define reg_raw_mode \
   (this_target_regs->x_reg_raw_mode)
 #define have_regs_of_mode \
@@ -250,13 +247,21 @@  #define direct_store \
 #define float_extend_from_mem \
   (this_target_regs->x_float_extend_from_mem)
 
+/* Return the number of hard registers in (reg:MODE REGNO).  */
+
+ALWAYS_INLINE unsigned char
+hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+  return this_target_regs->x_hard_regno_nregs[regno][mode];
+}
+
 /* Return an exclusive upper bound on the registers occupied by hard
    register (reg:MODE REGNO).  */
 
 static inline unsigned int
 end_hard_regno (machine_mode mode, unsigned int regno)
 {
-  return regno + hard_regno_nregs[regno][(int) mode];
+  return regno + hard_regno_nregs (regno, mode);
 }
 
 /* Add to REGS all the registers required to store a value of mode MODE
Index: gcc/caller-save.c
===================================================================
--- gcc/caller-save.c	2017-09-11 17:16:57.862552768 +0100
+++ gcc/caller-save.c	2017-09-11 17:22:43.339284035 +0100
@@ -480,7 +480,7 @@  setup_save_areas (void)
 	  if (r < 0 || regno_reg_rtx[regno] == cheap)
 	    continue;
 
-	  bound = r + hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)];
+	  bound = r + hard_regno_nregs (r, PSEUDO_REGNO_MODE (regno));
 	  for (; r < bound; r++)
 	    if (TEST_HARD_REG_BIT (used_regs, r))
 	      {
@@ -559,7 +559,7 @@  setup_save_areas (void)
 	      if (r < 0 || regno_reg_rtx[regno] == cheap)
 		continue;
 
-	      bound = r + hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)];
+	      bound = r + hard_regno_nregs (r, PSEUDO_REGNO_MODE (regno));
 	      for (; r < bound; r++)
 		if (TEST_HARD_REG_BIT (used_regs, r))
 		  call_saved_regs[call_saved_regs_num++] = hard_reg_map[r];
@@ -835,7 +835,7 @@  save_call_clobbered_regs (void)
 
 		  if (r < 0 || regno_reg_rtx[regno] == cheap)
 		    continue;
-		  nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)];
+		  nregs = hard_regno_nregs (r, PSEUDO_REGNO_MODE (regno));
 		  mode = HARD_REGNO_CALLER_SAVE_MODE
 		    (r, nregs, PSEUDO_REGNO_MODE (regno));
 		  if (partial_subreg_p (save_mode[r], mode))
@@ -1100,7 +1100,7 @@  replace_reg_with_saved_mem (rtx *loc,
 			    int regno,
 			    void *arg)
 {
-  unsigned int i, nregs = hard_regno_nregs [regno][mode];
+  unsigned int i, nregs = hard_regno_nregs (regno, mode);
   rtx mem;
   machine_mode *save_mode = (machine_mode *)arg;
 
@@ -1122,7 +1122,7 @@  replace_reg_with_saved_mem (rtx *loc,
     {
       mem = copy_rtx (regno_save_mem[regno][nregs]);
 
-      if (nregs == (unsigned int) hard_regno_nregs[regno][save_mode[regno]])
+      if (nregs == hard_regno_nregs (regno, save_mode[regno]))
 	mem = adjust_address_nv (mem, save_mode[regno], 0);
 
       if (GET_MODE (mem) != mode)
@@ -1146,7 +1146,7 @@  replace_reg_with_saved_mem (rtx *loc,
 	  {
 	    machine_mode smode = save_mode[regno];
 	    gcc_assert (smode != VOIDmode);
-	    if (hard_regno_nregs [regno][smode] > 1)
+	    if (hard_regno_nregs (regno, smode) > 1)
 	      smode = mode_for_size (GET_MODE_SIZE (mode) / nregs,
 				     GET_MODE_CLASS (mode), 0).require ();
 	    XVECEXP (mem, 0, i) = gen_rtx_REG (smode, regno + i);
@@ -1219,7 +1219,7 @@  insert_restore (struct insn_chain *chain
   mem = regno_save_mem [regno][numregs];
   if (save_mode [regno] != VOIDmode
       && save_mode [regno] != GET_MODE (mem)
-      && numregs == (unsigned int) hard_regno_nregs[regno][save_mode [regno]]
+      && numregs == hard_regno_nregs (regno, save_mode [regno])
       /* Check that insn to restore REGNO in save_mode[regno] is
 	 correct.  */
       && reg_save_code (regno, save_mode[regno]) >= 0)
@@ -1298,7 +1298,7 @@  insert_save (struct insn_chain *chain, i
   mem = regno_save_mem [regno][numregs];
   if (save_mode [regno] != VOIDmode
       && save_mode [regno] != GET_MODE (mem)
-      && numregs == (unsigned int) hard_regno_nregs[regno][save_mode [regno]]
+      && numregs == hard_regno_nregs (regno, save_mode [regno])
       /* Check that insn to save REGNO in save_mode[regno] is
 	 correct.  */
       && reg_save_code (regno, save_mode[regno]) >= 0)
Index: gcc/combine.c
===================================================================
--- gcc/combine.c	2017-09-11 17:16:34.008890040 +0100
+++ gcc/combine.c	2017-09-11 17:22:43.344283088 +0100
@@ -2453,7 +2453,7 @@  can_change_dest_mode (rtx x, int added_s
      registers than the old mode.  */
   if (regno < FIRST_PSEUDO_REGISTER)
     return (targetm.hard_regno_mode_ok (regno, mode)
-	    && REG_NREGS (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
@@ -13910,7 +13910,7 @@  move_deaths (rtx x, rtx maybe_kill_insn,
 	      rtx oldnotes = 0;
 
 	      if (note)
-		offset = hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))];
+		offset = hard_regno_nregs (regno, GET_MODE (XEXP (note, 0)));
 	      else
 		offset = 1;
 
@@ -14519,7 +14519,7 @@  distribute_notes (rtx notes, rtx_insn *f
 			 not already dead or set.  */
 
 		      for (i = regno; i < endregno;
-			   i += hard_regno_nregs[i][reg_raw_mode[i]])
+			   i += hard_regno_nregs (i, reg_raw_mode[i]))
 			{
 			  rtx piece = regno_reg_rtx[i];
 			  basic_block bb = this_basic_block;
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	2017-09-05 20:56:49.755747022 +0100
+++ gcc/config/mips/mips.c	2017-09-11 17:22:43.351281762 +0100
@@ -12875,7 +12875,7 @@  mips_hard_regno_scratch_ok (unsigned int
 mips_hard_regno_call_part_clobbered (unsigned int regno, machine_mode mode)
 {
   if (TARGET_FLOATXX
-      && hard_regno_nregs[regno][mode] == 1
+      && hard_regno_nregs (regno, mode) == 1
       && FP_REG_P (regno)
       && (regno & 1) != 0)
     return true;
Index: gcc/config/powerpcspe/powerpcspe.c
===================================================================
--- gcc/config/powerpcspe/powerpcspe.c	2017-09-11 17:16:50.101975824 +0100
+++ gcc/config/powerpcspe/powerpcspe.c	2017-09-11 17:22:43.365279110 +0100
@@ -23306,8 +23306,8 @@  rs6000_cannot_change_mode_class (machine
 
       if (reg_classes_intersect_p (xclass, rclass))
 	{
-	  unsigned to_nregs = hard_regno_nregs[FIRST_FPR_REGNO][to];
-	  unsigned from_nregs = hard_regno_nregs[FIRST_FPR_REGNO][from];
+	  unsigned to_nregs = hard_regno_nregs (FIRST_FPR_REGNO, to);
+	  unsigned from_nregs = hard_regno_nregs (FIRST_FPR_REGNO, from);
 	  bool to_float128_vector_p = FLOAT128_VECTOR_P (to);
 	  bool from_float128_vector_p = FLOAT128_VECTOR_P (from);
 
@@ -23365,8 +23365,8 @@  rs6000_cannot_change_mode_class (machine
   if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
     {
       unsigned num_regs = (from_size + 15) / 16;
-      if (hard_regno_nregs[FIRST_FPR_REGNO][to] > num_regs
-	  || hard_regno_nregs[FIRST_FPR_REGNO][from] > num_regs)
+      if (hard_regno_nregs (FIRST_FPR_REGNO, to) > num_regs
+	  || hard_regno_nregs (FIRST_FPR_REGNO, from) > num_regs)
 	return true;
 
       return (from_size != 8 && from_size != 16);
@@ -26769,7 +26769,7 @@  rs6000_split_multireg_move (rtx dst, rtx
 
   reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
   mode = GET_MODE (dst);
-  nregs = hard_regno_nregs[reg][mode];
+  nregs = hard_regno_nregs (reg, mode);
   if (FP_REGNO_P (reg))
     reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : 
 	((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
@@ -37836,18 +37836,18 @@  rs6000_register_move_cost (machine_mode
 		|| rs6000_cpu == PROCESSOR_POWER8
 		|| rs6000_cpu == PROCESSOR_POWER9)
 	       && reg_classes_intersect_p (rclass, LINK_OR_CTR_REGS))
-        ret = 6 * hard_regno_nregs[0][mode];
+        ret = 6 * hard_regno_nregs (0, mode);
 
       else
 	/* A move will cost one instruction per GPR moved.  */
-	ret = 2 * hard_regno_nregs[0][mode];
+	ret = 2 * hard_regno_nregs (0, mode);
     }
 
   /* If we have VSX, we can easily move between FPR or Altivec registers.  */
   else if (VECTOR_MEM_VSX_P (mode)
 	   && reg_classes_intersect_p (to, VSX_REGS)
 	   && reg_classes_intersect_p (from, VSX_REGS))
-    ret = 2 * hard_regno_nregs[FIRST_FPR_REGNO][mode];
+    ret = 2 * hard_regno_nregs (FIRST_FPR_REGNO, mode);
 
   /* Moving between two similar registers is just one instruction.  */
   else if (reg_classes_intersect_p (to, from))
@@ -37884,12 +37884,12 @@  rs6000_memory_move_cost (machine_mode mo
     dbg_cost_ctrl++;
 
   if (reg_classes_intersect_p (rclass, GENERAL_REGS))
-    ret = 4 * hard_regno_nregs[0][mode];
+    ret = 4 * hard_regno_nregs (0, mode);
   else if ((reg_classes_intersect_p (rclass, FLOAT_REGS)
 	    || reg_classes_intersect_p (rclass, VSX_REGS)))
-    ret = 4 * hard_regno_nregs[32][mode];
+    ret = 4 * hard_regno_nregs (32, mode);
   else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
-    ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
+    ret = 4 * hard_regno_nregs (FIRST_ALTIVEC_REGNO, mode);
   else
     ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
 
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	2017-09-11 17:16:50.109975383 +0100
+++ gcc/config/rs6000/rs6000.c	2017-09-11 17:22:43.374277405 +0100
@@ -20644,8 +20644,8 @@  rs6000_cannot_change_mode_class (machine
 
       if (reg_classes_intersect_p (xclass, rclass))
 	{
-	  unsigned to_nregs = hard_regno_nregs[FIRST_FPR_REGNO][to];
-	  unsigned from_nregs = hard_regno_nregs[FIRST_FPR_REGNO][from];
+	  unsigned to_nregs = hard_regno_nregs (FIRST_FPR_REGNO, to);
+	  unsigned from_nregs = hard_regno_nregs (FIRST_FPR_REGNO, from);
 	  bool to_float128_vector_p = FLOAT128_VECTOR_P (to);
 	  bool from_float128_vector_p = FLOAT128_VECTOR_P (from);
 
@@ -20693,8 +20693,8 @@  rs6000_cannot_change_mode_class (machine
   if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
     {
       unsigned num_regs = (from_size + 15) / 16;
-      if (hard_regno_nregs[FIRST_FPR_REGNO][to] > num_regs
-	  || hard_regno_nregs[FIRST_FPR_REGNO][from] > num_regs)
+      if (hard_regno_nregs (FIRST_FPR_REGNO, to) > num_regs
+	  || hard_regno_nregs (FIRST_FPR_REGNO, from) > num_regs)
 	return true;
 
       return (from_size != 8 && from_size != 16);
@@ -23827,7 +23827,7 @@  rs6000_split_multireg_move (rtx dst, rtx
 
   reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
   mode = GET_MODE (dst);
-  nregs = hard_regno_nregs[reg][mode];
+  nregs = hard_regno_nregs (reg, mode);
   if (FP_REGNO_P (reg))
     reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : 
 	((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
@@ -34647,18 +34647,18 @@  rs6000_register_move_cost (machine_mode
 		|| rs6000_cpu == PROCESSOR_POWER8
 		|| rs6000_cpu == PROCESSOR_POWER9)
 	       && reg_classes_intersect_p (rclass, LINK_OR_CTR_REGS))
-        ret = 6 * hard_regno_nregs[0][mode];
+        ret = 6 * hard_regno_nregs (0, mode);
 
       else
 	/* A move will cost one instruction per GPR moved.  */
-	ret = 2 * hard_regno_nregs[0][mode];
+	ret = 2 * hard_regno_nregs (0, mode);
     }
 
   /* If we have VSX, we can easily move between FPR or Altivec registers.  */
   else if (VECTOR_MEM_VSX_P (mode)
 	   && reg_classes_intersect_p (to, VSX_REGS)
 	   && reg_classes_intersect_p (from, VSX_REGS))
-    ret = 2 * hard_regno_nregs[FIRST_FPR_REGNO][mode];
+    ret = 2 * hard_regno_nregs (FIRST_FPR_REGNO, mode);
 
   /* Moving between two similar registers is just one instruction.  */
   else if (reg_classes_intersect_p (to, from))
@@ -34695,12 +34695,12 @@  rs6000_memory_move_cost (machine_mode mo
     dbg_cost_ctrl++;
 
   if (reg_classes_intersect_p (rclass, GENERAL_REGS))
-    ret = 4 * hard_regno_nregs[0][mode];
+    ret = 4 * hard_regno_nregs (0, mode);
   else if ((reg_classes_intersect_p (rclass, FLOAT_REGS)
 	    || reg_classes_intersect_p (rclass, VSX_REGS)))
-    ret = 4 * hard_regno_nregs[32][mode];
+    ret = 4 * hard_regno_nregs (32, mode);
   else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
-    ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
+    ret = 4 * hard_regno_nregs (FIRST_ALTIVEC_REGNO, mode);
   else
     ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
 
Index: gcc/cselib.c
===================================================================
--- gcc/cselib.c	2017-09-04 11:48:57.528852460 +0100
+++ gcc/cselib.c	2017-09-11 17:22:43.374277405 +0100
@@ -530,7 +530,8 @@  cselib_reset_table (unsigned int num)
       n_used_regs = new_used_regs;
       used_regs[0] = regno;
       max_value_regs
-	= hard_regno_nregs[regno][GET_MODE (cfa_base_preserved_val->locs->loc)];
+	= hard_regno_nregs (regno,
+			    GET_MODE (cfa_base_preserved_val->locs->loc));
     }
   else
     {
@@ -2001,7 +2002,7 @@  cselib_lookup_1 (rtx x, machine_mode mod
 
       if (i < FIRST_PSEUDO_REGISTER)
 	{
-	  unsigned int n = hard_regno_nregs[i][mode];
+	  unsigned int n = hard_regno_nregs (i, mode);
 
 	  if (n > max_value_regs)
 	    max_value_regs = n;
@@ -2040,7 +2041,7 @@  cselib_lookup_1 (rtx x, machine_mode mod
 	      {
 		struct elt_loc_list *el;
 		if (i < FIRST_PSEUDO_REGISTER
-		    && hard_regno_nregs[i][lmode] != 1)
+		    && hard_regno_nregs (i, lmode) != 1)
 		  continue;
 		for (el = l->elt->locs; el; el = el->next)
 		  if (!REG_P (el->loc))
Index: gcc/emit-rtl.c
===================================================================
--- gcc/emit-rtl.c	2017-09-05 20:56:49.762986624 +0100
+++ gcc/emit-rtl.c	2017-09-11 17:22:43.376277026 +0100
@@ -419,7 +419,7 @@  gen_blockage (void)
 set_mode_and_regno (rtx x, machine_mode mode, unsigned int regno)
 {
   unsigned int nregs = (HARD_REGISTER_NUM_P (regno)
-			? hard_regno_nregs[regno][mode]
+			? hard_regno_nregs (regno, mode)
 			: 1);
   PUT_MODE_RAW (x, mode);
   set_regno_raw (x, regno, nregs);
Index: gcc/function.c
===================================================================
--- gcc/function.c	2017-09-05 20:56:49.763891574 +0100
+++ gcc/function.c	2017-09-11 17:22:43.378276647 +0100
@@ -2100,7 +2100,7 @@  aggregate_value_p (const_tree exp, const
     return 0;
 
   regno = REGNO (reg);
-  nregs = hard_regno_nregs[regno][TYPE_MODE (type)];
+  nregs = hard_regno_nregs (regno, TYPE_MODE (type));
   for (i = 0; i < nregs; i++)
     if (! call_used_regs[regno + i])
       return 1;
Index: gcc/ira-color.c
===================================================================
--- gcc/ira-color.c	2017-09-11 17:20:21.708282653 +0100
+++ gcc/ira-color.c	2017-09-11 17:22:43.379276458 +0100
@@ -1061,7 +1061,7 @@  setup_profitable_hard_regs (void)
 	  || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0)
 	continue;
       mode = ALLOCNO_MODE (a);
-      nregs = hard_regno_nregs[hard_regno][mode];
+      nregs = hard_regno_nregs (hard_regno, mode);
       nobj = ALLOCNO_NUM_OBJECTS (a);
       for (k = 0; k < nobj; k++)
 	{
@@ -1593,7 +1593,7 @@  check_hard_reg_p (ira_allocno_t a, int h
   /* Checking only profitable hard regs.  */
   if (! TEST_HARD_REG_BIT (profitable_regs, hard_regno))
     return false;
-  nregs = hard_regno_nregs[hard_regno][mode];
+  nregs = hard_regno_nregs (hard_regno, mode);
   nwords = ALLOCNO_NUM_OBJECTS (a);
   for (j = 0; j < nregs; j++)
     {
@@ -1627,7 +1627,7 @@  calculate_saved_nregs (int hard_regno, m
   int nregs = 0;
 
   ira_assert (hard_regno >= 0);
-  for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--)
+  for (i = hard_regno_nregs (hard_regno, mode) - 1; i >= 0; i--)
     if (!allocated_hardreg_p[hard_regno + i]
 	&& !TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + i)
 	&& !LOCAL_REGNO (hard_regno + i))
@@ -1760,7 +1760,7 @@  assign_hard_reg (ira_allocno_t a, bool r
 		  int conflict_nregs;
 
 		  mode = ALLOCNO_MODE (conflict_a);
-		  conflict_nregs = hard_regno_nregs[hard_regno][mode];
+		  conflict_nregs = hard_regno_nregs (hard_regno, mode);
 		  if (conflict_nregs == n_objects && conflict_nregs > 1)
 		    {
 		      int num = OBJECT_SUBWORD (conflict_obj);
@@ -1858,7 +1858,8 @@  assign_hard_reg (ira_allocno_t a, bool r
 	    rclass = REGNO_REG_CLASS (hard_regno);
 	    add_cost = ((ira_memory_move_cost[mode][rclass][0]
 		         + ira_memory_move_cost[mode][rclass][1])
-		        * saved_nregs / hard_regno_nregs[hard_regno][mode] - 1);
+		        * saved_nregs / hard_regno_nregs (hard_regno,
+							  mode) - 1);
 	    cost += add_cost;
 	    full_cost += add_cost;
 	  }
@@ -1885,7 +1886,7 @@  assign_hard_reg (ira_allocno_t a, bool r
  fail:
   if (best_hard_regno >= 0)
     {
-      for (i = hard_regno_nregs[best_hard_regno][mode] - 1; i >= 0; i--)
+      for (i = hard_regno_nregs (best_hard_regno, mode) - 1; i >= 0; i--)
 	allocated_hardreg_p[best_hard_regno + i] = true;
     }
   if (! retry_p)
@@ -2890,8 +2891,8 @@  improve_allocation (void)
 		spill_cost -= ALLOCNO_UPDATED_CLASS_COST (conflict_a);
 	      spill_cost
 		+= allocno_copy_cost_saving (conflict_a, conflict_hregno);
-	      conflict_nregs
-		= hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
+	      conflict_nregs = hard_regno_nregs (conflict_hregno,
+						 ALLOCNO_MODE (conflict_a));
 	      for (r = conflict_hregno;
 		   r >= 0 && (int) end_hard_regno (mode, r) > conflict_hregno;
 		   r--)
@@ -2926,7 +2927,7 @@  improve_allocation (void)
 	   by spilling some conflicting allocnos does not improve the
 	   allocation cost.  */
 	continue;
-      nregs = hard_regno_nregs[best][mode];
+      nregs = hard_regno_nregs (best, mode);
       /* Now spill conflicting allocnos which contain a hard register
 	 of A when we assign the best chosen hard register to it.  */
       for (word = 0; word < nwords; word++)
@@ -2941,8 +2942,8 @@  improve_allocation (void)
 
 	      if ((conflict_hregno = ALLOCNO_HARD_REGNO (conflict_a)) < 0)
 		continue;
-	      conflict_nregs
-		= hard_regno_nregs[conflict_hregno][ALLOCNO_MODE (conflict_a)];
+	      conflict_nregs = hard_regno_nregs (conflict_hregno,
+						 ALLOCNO_MODE (conflict_a));
 	      if (best + nregs <= conflict_hregno
 		  || conflict_hregno + conflict_nregs <= best)
 		/* No intersection.  */
@@ -4673,7 +4674,7 @@  calculate_spill_cost (int *regnos, rtx i
       a = ira_regno_allocno_map[regno];
       length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a);
       cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
-      nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (a)];
+      nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (a));
       for (j = 0; j < nregs; j++)
 	if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j))
 	  break;
Index: gcc/ira-emit.c
===================================================================
--- gcc/ira-emit.c	2017-02-23 19:54:15.000000000 +0000
+++ gcc/ira-emit.c	2017-09-11 17:22:43.380276269 +0100
@@ -783,7 +783,7 @@  modify_move_list (move_t list)
       to = move->to;
       if ((hard_regno = ALLOCNO_HARD_REGNO (to)) < 0)
 	continue;
-      nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (to)];
+      nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (to));
       for (i = 0; i < nregs; i++)
 	{
 	  hard_regno_last_set[hard_regno + i] = move;
@@ -796,7 +796,7 @@  modify_move_list (move_t list)
       to = move->to;
       if ((hard_regno = ALLOCNO_HARD_REGNO (from)) >= 0)
 	{
-	  nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (from)];
+	  nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (from));
 	  for (n = i = 0; i < nregs; i++)
 	    if (hard_regno_last_set_check[hard_regno + i] == curr_tick
 		&& (ALLOCNO_REGNO (hard_regno_last_set[hard_regno + i]->to)
@@ -834,7 +834,7 @@  modify_move_list (move_t list)
       to = move->to;
       if ((hard_regno = ALLOCNO_HARD_REGNO (from)) >= 0)
 	{
-	  nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (from)];
+	  nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (from));
 	  for (i = 0; i < nregs; i++)
 	    if (hard_regno_last_set_check[hard_regno + i] == curr_tick
 		&& ALLOCNO_HARD_REGNO
@@ -886,7 +886,7 @@  modify_move_list (move_t list)
 	}
       if ((hard_regno = ALLOCNO_HARD_REGNO (to)) < 0)
 	continue;
-      nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (to)];
+      nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (to));
       for (i = 0; i < nregs; i++)
 	{
 	  hard_regno_last_set[hard_regno + i] = move;
Index: gcc/ira-int.h
===================================================================
--- gcc/ira-int.h	2017-02-23 19:54:12.000000000 +0000
+++ gcc/ira-int.h	2017-09-11 17:22:43.380276269 +0100
@@ -1393,7 +1393,7 @@  ira_hard_reg_set_intersection_p (int har
   int i;
 
   gcc_assert (hard_regno >= 0);
-  for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--)
+  for (i = hard_regno_nregs (hard_regno, mode) - 1; i >= 0; i--)
     if (TEST_HARD_REG_BIT (hard_regset, hard_regno + i))
       return true;
   return false;
@@ -1421,7 +1421,7 @@  ira_hard_reg_in_set_p (int hard_regno, m
   int i;
 
   ira_assert (hard_regno >= 0);
-  for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--)
+  for (i = hard_regno_nregs (hard_regno, mode) - 1; i >= 0; i--)
     if (!TEST_HARD_REG_BIT (hard_regset, hard_regno + i))
       return false;
   return true;
Index: gcc/ira.c
===================================================================
--- gcc/ira.c	2017-09-04 11:49:42.938500723 +0100
+++ gcc/ira.c	2017-09-11 17:22:43.382275890 +0100
@@ -449,7 +449,8 @@  setup_reg_mode_hard_regset (void)
     for (hard_regno = 0; hard_regno < FIRST_PSEUDO_REGISTER; hard_regno++)
       {
 	CLEAR_HARD_REG_SET (ira_reg_mode_hard_regset[hard_regno][m]);
-	for (i = hard_regno_nregs[hard_regno][m] - 1; i >= 0; i--)
+	for (i = hard_regno_nregs (hard_regno, (machine_mode) m) - 1;
+	     i >= 0; i--)
 	  if (hard_regno + i < FIRST_PSEUDO_REGISTER)
 	    SET_HARD_REG_BIT (ira_reg_mode_hard_regset[hard_regno][m],
 			      hard_regno + i);
@@ -1540,7 +1541,7 @@  clarify_prohibited_class_mode_regs (void
 	    hard_regno = ira_class_hard_regs[cl][k];
 	    if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], hard_regno))
 	      continue;
-	    nregs = hard_regno_nregs[hard_regno][j];
+	    nregs = hard_regno_nregs (hard_regno, (machine_mode) j);
 	    if (hard_regno + nregs > FIRST_PSEUDO_REGISTER)
 	      {
 		SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j],
@@ -2509,7 +2510,7 @@  check_allocation (void)
       if (ALLOCNO_CAP_MEMBER (a) != NULL
 	  || (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0)
 	continue;
-      nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (a)];
+      nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (a));
       if (nregs == 1)
 	/* We allocated a single hard register.  */
 	n = 1;
@@ -2538,9 +2539,8 @@  check_allocation (void)
 	      if (conflict_hard_regno < 0)
 		continue;
 
-	      conflict_nregs
-		= (hard_regno_nregs
-		   [conflict_hard_regno][ALLOCNO_MODE (conflict_a)]);
+	      conflict_nregs = hard_regno_nregs (conflict_hard_regno,
+						 ALLOCNO_MODE (conflict_a));
 
 	      if (ALLOCNO_NUM_OBJECTS (conflict_a) > 1
 		  && conflict_nregs == ALLOCNO_NUM_OBJECTS (conflict_a))
Index: gcc/lra-assigns.c
===================================================================
--- gcc/lra-assigns.c	2017-09-11 17:20:21.708282653 +0100
+++ gcc/lra-assigns.c	2017-09-11 17:22:43.382275890 +0100
@@ -568,8 +568,8 @@  find_hard_regno_for_1 (int regno, int *c
       if (lra_reg_val_equal_p (conflict_regno, val, offset))
 	{
 	  conflict_hr = live_pseudos_reg_renumber[conflict_regno];
-	  nregs = (hard_regno_nregs[conflict_hr]
-		   [lra_reg_info[conflict_regno].biggest_mode]);
+	  nregs = hard_regno_nregs (conflict_hr,
+				    lra_reg_info[conflict_regno].biggest_mode);
 	  /* Remember about multi-register pseudos.  For example, 2
 	     hard register pseudos can start on the same hard register
 	     but can not start on HR and HR+1/HR-1.  */
@@ -587,12 +587,12 @@  find_hard_regno_for_1 (int regno, int *c
 	  machine_mode biggest_conflict_mode
 	    = lra_reg_info[conflict_regno].biggest_mode;
 	  int biggest_conflict_nregs
-	    = hard_regno_nregs[conflict_hr][biggest_conflict_mode];
+	    = hard_regno_nregs (conflict_hr, biggest_conflict_mode);
 	  
-	  nregs_diff = (biggest_conflict_nregs
-			- (hard_regno_nregs
-			   [conflict_hr]
-			   [PSEUDO_REGNO_MODE (conflict_regno)]));
+	  nregs_diff
+	    = (biggest_conflict_nregs
+	       - hard_regno_nregs (conflict_hr,
+				   PSEUDO_REGNO_MODE (conflict_regno)));
 	  add_to_hard_reg_set (&conflict_set,
 			       biggest_conflict_mode,
 			       conflict_hr
@@ -627,9 +627,9 @@  find_hard_regno_for_1 (int regno, int *c
   rclass_size = ira_class_hard_regs_num[rclass];
   best_hard_regno = -1;
   hard_regno = ira_class_hard_regs[rclass][0];
-  biggest_nregs = hard_regno_nregs[hard_regno][biggest_mode];
+  biggest_nregs = hard_regno_nregs (hard_regno, biggest_mode);
   nregs_diff = (biggest_nregs
-		- hard_regno_nregs[hard_regno][PSEUDO_REGNO_MODE (regno)]);
+		- hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (regno)));
   COPY_HARD_REG_SET (available_regs, reg_class_contents[rclass]);
   AND_COMPL_HARD_REG_SET (available_regs, lra_no_alloc_regs);
   for (i = 0; i < rclass_size; i++)
@@ -664,7 +664,7 @@  find_hard_regno_for_1 (int regno, int *c
 	      hard_regno_costs[hard_regno] = 0;
 	    }
 	  for (j = 0;
-	       j < hard_regno_nregs[hard_regno][PSEUDO_REGNO_MODE (regno)];
+	       j < hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (regno));
 	       j++)
 	    if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j)
 		&& ! df_regs_ever_live_p (hard_regno + j))
@@ -799,7 +799,7 @@  lra_setup_reg_renumber (int regno, int h
     hr = reg_renumber[regno];
   reg_renumber[regno] = hard_regno;
   lra_assert (hr >= 0);
-  for (i = 0; i < hard_regno_nregs[hr][PSEUDO_REGNO_MODE (regno)]; i++)
+  for (i = 0; i < hard_regno_nregs (hr, PSEUDO_REGNO_MODE (regno)); i++)
     if (hard_regno < 0)
       lra_hard_reg_usage[hr + i] -= lra_reg_info[regno].freq;
     else
@@ -851,7 +851,7 @@  setup_try_hard_regno_pseudos (int p, enu
       if (overlaps_hard_reg_set_p (reg_class_contents[rclass],
 				   mode, hard_regno))
 	{
-	  for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--)
+	  for (i = hard_regno_nregs (hard_regno, mode) - 1; i >= 0; i--)
 	    {
 	      if (try_hard_reg_pseudos_check[hard_regno + i]
 		  != curr_pseudo_check)
@@ -974,7 +974,7 @@  spill_for (int regno, bitmap spilled_pse
     {
       hard_regno = ira_class_hard_regs[rclass][i];
       bitmap_clear (&spill_pseudos_bitmap);
-      for (j = hard_regno_nregs[hard_regno][mode] - 1; j >= 0; j--)
+      for (j = hard_regno_nregs (hard_regno, mode) - 1; j >= 0; j--)
 	{
 	  if (try_hard_reg_pseudos_check[hard_regno + j] != curr_pseudo_check)
 	    continue;
@@ -1132,7 +1132,7 @@  assign_hard_regno (int hard_regno, int r
   lra_setup_reg_renumber (regno, hard_regno, true);
   update_lives (regno, false);
   for (i = 0;
-       i < hard_regno_nregs[hard_regno][lra_reg_info[regno].biggest_mode];
+       i < hard_regno_nregs (hard_regno, lra_reg_info[regno].biggest_mode);
        i++)
     df_set_regs_ever_live (hard_regno + i, true);
 }
@@ -1214,11 +1214,12 @@  setup_live_pseudos_and_spill_after_risky
 	  {
 	    int conflict_hard_regno = reg_renumber[conflict_regno];
 	    machine_mode biggest_mode = lra_reg_info[conflict_regno].biggest_mode;
-	    int biggest_nregs = hard_regno_nregs[conflict_hard_regno][biggest_mode];
-	    int nregs_diff = (biggest_nregs
-			      - (hard_regno_nregs
-				 [conflict_hard_regno]
-				 [PSEUDO_REGNO_MODE (conflict_regno)]));
+	    int biggest_nregs = hard_regno_nregs (conflict_hard_regno,
+						  biggest_mode);
+	    int nregs_diff
+	      = (biggest_nregs
+		 - hard_regno_nregs (conflict_hard_regno,
+				     PSEUDO_REGNO_MODE (conflict_regno)));
 	    add_to_hard_reg_set (&conflict_set,
 				 biggest_mode,
 				 conflict_hard_regno
@@ -1231,7 +1232,7 @@  setup_live_pseudos_and_spill_after_risky
 	}
       bitmap_set_bit (spilled_pseudo_bitmap, regno);
       for (j = 0;
-	   j < hard_regno_nregs[hard_regno][PSEUDO_REGNO_MODE (regno)];
+	   j < hard_regno_nregs (hard_regno, PSEUDO_REGNO_MODE (regno));
 	   j++)
 	lra_hard_reg_usage[hard_regno + j] -= lra_reg_info[regno].freq;
       reg_renumber[regno] = -1;
Index: gcc/lra-constraints.c
===================================================================
--- gcc/lra-constraints.c	2017-09-11 17:16:50.115975052 +0100
+++ gcc/lra-constraints.c	2017-09-11 17:22:43.384275511 +0100
@@ -291,7 +291,7 @@  in_class_p (rtx reg, enum reg_class cl,
       for (i = 0; i < class_size; i++)
 	{
 	  hard_regno = ira_class_hard_regs[common_class][i];
-	  nregs = hard_regno_nregs[hard_regno][reg_mode];
+	  nregs = hard_regno_nregs (hard_regno, reg_mode);
 	  if (nregs == 1)
 	    return true;
 	  for (j = 0; j < nregs; j++)
@@ -676,7 +676,7 @@  lra_constraint_offset (int regno, machin
   if (WORDS_BIG_ENDIAN
       && is_a <scalar_int_mode> (mode, &int_mode)
       && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD)
-    return hard_regno_nregs[regno][mode] - 1;
+    return hard_regno_nregs (regno, mode) - 1;
   return 0;
 }
 
@@ -1655,8 +1655,8 @@  simplify_operand_subreg (int nop, machin
        && (hard_regno = lra_get_regno_hard_regno (REGNO (reg))) >= 0
        /* Don't reload paradoxical subregs because we could be looping
 	  having repeatedly final regno out of hard regs range.  */
-       && (hard_regno_nregs[hard_regno][innermode]
-	   >= hard_regno_nregs[hard_regno][mode])
+       && (hard_regno_nregs (hard_regno, innermode)
+	   >= hard_regno_nregs (hard_regno, mode))
        && simplify_subreg_regno (hard_regno, innermode,
 				 SUBREG_BYTE (operand), mode) < 0
        /* Don't reload subreg for matching reload.  It is actually
@@ -1726,8 +1726,8 @@  simplify_operand_subreg (int nop, machin
   else if (REG_P (reg)
 	   && REGNO (reg) >= FIRST_PSEUDO_REGISTER
 	   && (hard_regno = lra_get_regno_hard_regno (REGNO (reg))) >= 0
-	   && (hard_regno_nregs[hard_regno][innermode]
-	       < hard_regno_nregs[hard_regno][mode])
+	   && (hard_regno_nregs (hard_regno, innermode)
+	       < hard_regno_nregs (hard_regno, mode))
 	   && (regclass = lra_get_allocno_class (REGNO (reg)))
 	   && (type != OP_IN
 	       || !in_hard_reg_set_p (reg_class_contents[regclass],
@@ -4663,7 +4663,7 @@  lra_constraints (bool first_p)
       {
 	int j, nregs;
 
-	nregs = hard_regno_nregs[hard_regno][lra_reg_info[i].biggest_mode];
+	nregs = hard_regno_nregs (hard_regno, lra_reg_info[i].biggest_mode);
 	for (j = 0; j < nregs; j++)
 	  df_set_regs_ever_live (hard_regno + j, true);
       }
@@ -4860,7 +4860,8 @@  lra_constraints (bool first_p)
 	if (lra_reg_info[i].nrefs != 0
 	    && (hard_regno = lra_get_regno_hard_regno (i)) >= 0)
 	  {
-	    int j, nregs = hard_regno_nregs[hard_regno][PSEUDO_REGNO_MODE (i)];
+	    int j, nregs = hard_regno_nregs (hard_regno,
+					     PSEUDO_REGNO_MODE (i));
 
 	    for (j = 0; j < nregs; j++)
 	      lra_assert (df_regs_ever_live_p (hard_regno + j));
@@ -5472,7 +5473,7 @@  split_reg (bool before_p, int original_r
     {
       mode = PSEUDO_REGNO_MODE (original_regno);
       hard_regno = reg_renumber[original_regno];
-      nregs = hard_regno_nregs[hard_regno][mode];
+      nregs = hard_regno_nregs (hard_regno, mode);
       rclass = lra_get_allocno_class (original_regno);
       original_reg = regno_reg_rtx[original_regno];
       call_save_p = need_for_call_save_p (original_regno);
@@ -5485,7 +5486,7 @@  split_reg (bool before_p, int original_r
   if (call_save_p)
     {
       mode = HARD_REGNO_CALLER_SAVE_MODE (hard_regno,
-					  hard_regno_nregs[hard_regno][mode],
+					  hard_regno_nregs (hard_regno, mode),
 					  mode);
       new_reg = lra_create_new_reg (mode, NULL_RTX, NO_REGS, "save");
     }
@@ -5634,7 +5635,7 @@  split_if_necessary (int regno, machine_m
   rtx next_usage_insns;
 
   if (regno < FIRST_PSEUDO_REGISTER)
-    nregs = hard_regno_nregs[regno][mode];
+    nregs = hard_regno_nregs (regno, mode);
   for (i = 0; i < nregs; i++)
     if (usage_insns[regno + i].check == curr_usage_insns_check
 	&& (next_usage_insns = usage_insns[regno + i].insns) != NULL_RTX
@@ -5679,7 +5680,7 @@  invariant_p (const_rtx x)
 	  || TEST_HARD_REG_BIT (eliminable_regset, regno)
 	  || GET_MODE_CLASS (GET_MODE (x)) == MODE_CC)
 	return false;
-      nregs = hard_regno_nregs[regno][mode];
+      nregs = hard_regno_nregs (regno, mode);
       for (i = 0; i < nregs; i++)
 	if (! fixed_regs[regno + i]
 	    /* A hard register may be clobbered in the current insn
@@ -6201,7 +6202,8 @@  inherit_in_ebb (rtx_insn *head, rtx_insn
 			usage_insns[dst_regno].check = -(int) INSN_UID (curr_insn);
 		      else
 			{
-			  nregs = hard_regno_nregs[dst_regno][reg->biggest_mode];
+			  nregs = hard_regno_nregs (dst_regno,
+						    reg->biggest_mode);
 			  for (i = 0; i < nregs; i++)
 			    usage_insns[dst_regno + i].check
 			      = -(int) INSN_UID (curr_insn);
Index: gcc/lra-lives.c
===================================================================
--- gcc/lra-lives.c	2017-09-11 17:20:21.708282653 +0100
+++ gcc/lra-lives.c	2017-09-11 17:22:43.385275322 +0100
@@ -726,7 +726,7 @@  process_bb_lives (basic_block bb, int &c
 		 but implicitly it can be used in natural mode as a
 		 part of multi-register group.  Process this case
 		 here.  */
-	      for (i = 1; i < hard_regno_nregs[regno][reg->biggest_mode]; i++)
+	      for (i = 1; i < hard_regno_nregs (regno, reg->biggest_mode); i++)
 		if (partial_subreg_p (lra_reg_info[regno + i].biggest_mode,
 				      GET_MODE (regno_reg_rtx[regno + i])))
 		  lra_reg_info[regno + i].biggest_mode
Index: gcc/lra-remat.c
===================================================================
--- gcc/lra-remat.c	2017-09-11 17:20:21.708282653 +0100
+++ gcc/lra-remat.c	2017-09-11 17:22:43.385275322 +0100
@@ -667,7 +667,7 @@  reg_overlap_for_remat_p (lra_insn_reg *r
   if (regno >= FIRST_PSEUDO_REGISTER)
     nregs = 1;
   else
-    nregs = hard_regno_nregs[regno][reg->biggest_mode];
+    nregs = hard_regno_nregs (regno, reg->biggest_mode);
 
   struct lra_insn_reg *reg2;
 
@@ -686,7 +686,7 @@  reg_overlap_for_remat_p (lra_insn_reg *r
 	if (regno2 >= FIRST_PSEUDO_REGISTER)
 	  nregs2 = 1;
 	else
-	  nregs2 = hard_regno_nregs[regno2][reg->biggest_mode];
+	  nregs2 = hard_regno_nregs (regno2, reg->biggest_mode);
 
 	if ((regno2 + nregs2 - 1 >= regno && regno2 < regno + nregs)
 	    || (regno + nregs - 1 >= regno2 && regno < regno2 + nregs2))
@@ -1011,7 +1011,7 @@  get_hard_regs (struct lra_insn_reg *reg,
   int hard_regno = regno < FIRST_PSEUDO_REGISTER ? regno : reg_renumber[regno];
 
   if (hard_regno >= 0)
-    nregs = hard_regno_nregs[hard_regno][reg->biggest_mode];
+    nregs = hard_regno_nregs (hard_regno, reg->biggest_mode);
   return hard_regno;
 }
 
@@ -1135,7 +1135,7 @@  do_remat (void)
 		? dst_regno : reg_renumber[dst_regno];
 	      gcc_assert (dst_hard_regno >= 0);
 	      machine_mode mode = GET_MODE (SET_DEST (set));
-	      dst_nregs = hard_regno_nregs[dst_hard_regno][mode];
+	      dst_nregs = hard_regno_nregs (dst_hard_regno, mode);
 
 	      for (reg = cand_id->regs; reg != NULL; reg = reg->next)
 		if (reg->type != OP_IN && reg->regno != ignore_regno)
Index: gcc/lra-spills.c
===================================================================
--- gcc/lra-spills.c	2017-09-11 17:16:47.035145961 +0100
+++ gcc/lra-spills.c	2017-09-11 17:22:43.386275132 +0100
@@ -291,7 +291,8 @@  assign_spill_hard_regs (int *pseudo_regn
       spill_hard_reg[regno]
 	= gen_raw_REG (PSEUDO_REGNO_MODE (regno), hard_regno);
       for (nr = 0;
-	   nr < hard_regno_nregs[hard_regno][lra_reg_info[regno].biggest_mode];
+	   nr < hard_regno_nregs (hard_regno,
+				  lra_reg_info[regno].biggest_mode);
 	   nr++)
 	/* Just loop.  */
 	df_set_regs_ever_live (hard_regno + nr, true);
Index: gcc/mode-switching.c
===================================================================
--- gcc/mode-switching.c	2017-09-11 17:16:57.895550989 +0100
+++ gcc/mode-switching.c	2017-09-11 17:22:43.386275132 +0100
@@ -361,8 +361,8 @@  create_pre_exit (int n_entities, int *en
 		    if (!targetm.calls.function_value_regno_p (copy_start))
 		      copy_num = 0;
 		    else
-		      copy_num
-			= hard_regno_nregs[copy_start][GET_MODE (copy_reg)];
+		      copy_num = hard_regno_nregs (copy_start,
+						   GET_MODE (copy_reg));
 
 		    /* If the return register is not likely spilled, - as is
 		       the case for floating point on SH4 - then it might
Index: gcc/postreload.c
===================================================================
--- gcc/postreload.c	2017-09-11 17:20:21.709282633 +0100
+++ gcc/postreload.c	2017-09-11 17:22:43.387274943 +0100
@@ -1136,7 +1136,7 @@  reload_combine_recognize_pattern (rtx_in
 		  && (call_used_regs[i] || df_regs_ever_live_p (i))
 		  && (!frame_pointer_needed || i != HARD_FRAME_POINTER_REGNUM)
 		  && !fixed_regs[i] && !global_regs[i]
-		  && hard_regno_nregs[i][GET_MODE (reg)] == 1
+		  && hard_regno_nregs (i, GET_MODE (reg)) == 1
 		  && targetm.hard_regno_scratch_ok (i))
 		{
 		  index_reg = gen_rtx_REG (GET_MODE (reg), i);
Index: gcc/recog.c
===================================================================
--- gcc/recog.c	2017-09-04 11:49:42.939500722 +0100
+++ gcc/recog.c	2017-09-11 17:22:43.388274753 +0100
@@ -3163,7 +3163,7 @@  peep2_find_free_register (int from, int
 	continue;
 
       success = 1;
-      for (j = 0; success && j < hard_regno_nregs[regno][mode]; j++)
+      for (j = 0; success && j < hard_regno_nregs (regno, mode); j++)
 	{
 	  /* Don't allocate fixed registers.  */
 	  if (fixed_regs[regno + j])
Index: gcc/regcprop.c
===================================================================
--- gcc/regcprop.c	2017-09-11 17:16:57.895550989 +0100
+++ gcc/regcprop.c	2017-09-11 17:22:43.388274753 +0100
@@ -176,7 +176,7 @@  kill_value_regno (unsigned int regno, un
       unsigned int i, n;
       if (vd->e[j].mode == VOIDmode)
 	continue;
-      n = hard_regno_nregs[j][vd->e[j].mode];
+      n = hard_regno_nregs (j, vd->e[j].mode);
       if (j + n > regno)
 	for (i = 0; i < n; ++i)
 	  kill_value_one_regno (j + i, vd);
@@ -209,7 +209,7 @@  set_value_regno (unsigned int regno, mac
 
   vd->e[regno].mode = mode;
 
-  nregs = hard_regno_nregs[regno][mode];
+  nregs = hard_regno_nregs (regno, mode);
   if (nregs > vd->max_value_regs)
     vd->max_value_regs = nregs;
 }
@@ -344,14 +344,14 @@  copy_value (rtx dest, rtx src, struct va
 
      We can't properly represent the latter case in our tables, so don't
      record anything then.  */
-  else if (sn < (unsigned int) hard_regno_nregs[sr][vd->e[sr].mode]
+  else if (sn < hard_regno_nregs (sr, vd->e[sr].mode)
 	   && subreg_lowpart_offset (GET_MODE (dest), vd->e[sr].mode) != 0)
     return;
 
   /* If SRC had been assigned a mode narrower than the copy, we can't
      link DEST into the chain, because not all of the pieces of the
      copy came from oldest_regno.  */
-  else if (sn > (unsigned int) hard_regno_nregs[sr][vd->e[sr].mode])
+  else if (sn > hard_regno_nregs (sr, vd->e[sr].mode))
     return;
 
   /* Link DR at the end of the value chain used by SR.  */
@@ -407,8 +407,8 @@  maybe_mode_change (machine_mode orig_mod
     return gen_raw_REG (new_mode, regno);
   else if (mode_change_ok (orig_mode, new_mode, regno))
     {
-      int copy_nregs = hard_regno_nregs[copy_regno][copy_mode];
-      int use_nregs = hard_regno_nregs[copy_regno][new_mode];
+      int copy_nregs = hard_regno_nregs (copy_regno, copy_mode);
+      int use_nregs = hard_regno_nregs (copy_regno, new_mode);
       int copy_offset
 	= GET_MODE_SIZE (copy_mode) / copy_nregs * (copy_nregs - use_nregs);
       unsigned int offset
@@ -440,7 +440,7 @@  find_oldest_value_reg (enum reg_class cl
 	(set (...) (reg:DI r9))
      Replacing r9 with r11 is invalid.  */
   if (mode != vd->e[regno].mode
-      && REG_NREGS (reg) > hard_regno_nregs[regno][vd->e[regno].mode])
+      && REG_NREGS (reg) > hard_regno_nregs (regno, vd->e[regno].mode))
     return NULL_RTX;
 
   for (i = vd->e[regno].oldest_regno; i != regno; i = vd->e[i].next_regno)
@@ -864,12 +864,12 @@  copyprop_hardreg_forward_1 (basic_block
 	  if (mode != vd->e[regno].mode)
 	    {
 	      if (REG_NREGS (src)
-		  > hard_regno_nregs[regno][vd->e[regno].mode])
+		  > hard_regno_nregs (regno, vd->e[regno].mode))
 		goto no_move_special_case;
 
 	      /* And likewise, if we are narrowing on big endian the transformation
 		 is also invalid.  */
-	      if (REG_NREGS (src) < hard_regno_nregs[regno][vd->e[regno].mode]
+	      if (REG_NREGS (src) < hard_regno_nregs (regno, vd->e[regno].mode)
 		  && subreg_lowpart_offset (mode, vd->e[regno].mode) != 0)
 		goto no_move_special_case;
 	    }
Index: gcc/regrename.c
===================================================================
--- gcc/regrename.c	2017-09-04 11:49:42.940500722 +0100
+++ gcc/regrename.c	2017-09-11 17:22:43.389274564 +0100
@@ -312,7 +312,7 @@  check_new_reg_p (int reg ATTRIBUTE_UNUSE
 		 struct du_head *this_head, HARD_REG_SET this_unavailable)
 {
   machine_mode mode = GET_MODE (*this_head->first->loc);
-  int nregs = hard_regno_nregs[new_reg][mode];
+  int nregs = hard_regno_nregs (new_reg, mode);
   int i;
   struct du_chain *tmp;
 
@@ -990,7 +990,7 @@  regrename_do_replace (struct du_head *he
   mode = GET_MODE (*head->first->loc);
   head->renamed = 1;
   head->regno = reg;
-  head->nregs = hard_regno_nregs[reg][mode];
+  head->nregs = hard_regno_nregs (reg, mode);
   return true;
 }
 
Index: gcc/reload.c
===================================================================
--- gcc/reload.c	2017-09-11 17:20:21.710282613 +0100
+++ gcc/reload.c	2017-09-11 17:22:43.392273996 +0100
@@ -1625,8 +1625,8 @@  push_reload (rtx in, rtx out, rtx *inloc
 	    && targetm.hard_regno_mode_ok (regno, outmode))
 	  {
 	    unsigned int offs;
-	    unsigned int nregs = MAX (hard_regno_nregs[regno][inmode],
-				      hard_regno_nregs[regno][outmode]);
+	    unsigned int nregs = MAX (hard_regno_nregs (regno, inmode),
+				      hard_regno_nregs (regno, outmode));
 
 	    for (offs = 0; offs < nregs; offs++)
 	      if (fixed_regs[regno + offs]
@@ -1905,7 +1905,7 @@  combine_reloads (void)
 	&& targetm.hard_regno_mode_ok (regno, rld[output_reload].outmode)
 	&& TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].rclass],
 			      regno)
-	&& (hard_regno_nregs[regno][rld[output_reload].outmode]
+	&& (hard_regno_nregs (regno, rld[output_reload].outmode)
 	    <= REG_NREGS (XEXP (note, 0)))
 	/* Ensure that a secondary or tertiary reload for this output
 	   won't want this register.  */
@@ -2005,7 +2005,7 @@  find_dummy_reload (rtx real_in, rtx real
       && REGNO (out) < FIRST_PSEUDO_REGISTER)
     {
       unsigned int regno = REGNO (out) + out_offset;
-      unsigned int nwords = hard_regno_nregs[regno][outmode];
+      unsigned int nwords = hard_regno_nregs (regno, outmode);
       rtx saved_rtx;
 
       /* When we consider whether the insn uses OUT,
@@ -2090,7 +2090,7 @@  find_dummy_reload (rtx real_in, rtx real
 	      && REG_NREGS (in) == 1)))
     {
       unsigned int regno = REGNO (in) + in_offset;
-      unsigned int nwords = hard_regno_nregs[regno][inmode];
+      unsigned int nwords = hard_regno_nregs (regno, inmode);
 
       if (! refers_to_regno_for_reload_p (regno, regno + nwords, out, (rtx*) 0)
 	  && ! hard_reg_set_here_p (regno, regno + nwords,
@@ -2264,13 +2264,13 @@  operands_match_p (rtx x, rtx y)
 	  && is_a <scalar_int_mode> (GET_MODE (x), &xmode)
 	  && GET_MODE_SIZE (xmode) > UNITS_PER_WORD
 	  && i < FIRST_PSEUDO_REGISTER)
-	i += hard_regno_nregs[i][xmode] - 1;
+	i += hard_regno_nregs (i, xmode) - 1;
       scalar_int_mode ymode;
       if (REG_WORDS_BIG_ENDIAN
 	  && is_a <scalar_int_mode> (GET_MODE (y), &ymode)
 	  && GET_MODE_SIZE (ymode) > UNITS_PER_WORD
 	  && j < FIRST_PSEUDO_REGISTER)
-	j += hard_regno_nregs[j][ymode] - 1;
+	j += hard_regno_nregs (j, ymode) - 1;
 
       return i == j;
     }
@@ -4576,7 +4576,7 @@  find_reloads (rtx_insn *insn, int replac
 	    && TEST_HARD_REG_BIT (reg_class_contents[rld[i].rclass], regno)
 	    && targetm.hard_regno_mode_ok (regno, rld[i].mode))
 	  {
-	    int nr = hard_regno_nregs[regno][rld[i].mode];
+	    int nr = hard_regno_nregs (regno, rld[i].mode);
 	    int ok = 1, nri;
 
 	    for (nri = 1; nri < nr; nri ++)
@@ -6856,10 +6856,10 @@  find_equiv_reg (rtx goal, rtx_insn *insn
   /* Reject registers that overlap GOAL.  */
 
   if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER)
-    nregs = hard_regno_nregs[regno][mode];
+    nregs = hard_regno_nregs (regno, mode);
   else
     nregs = 1;
-  valuenregs = hard_regno_nregs[valueno][mode];
+  valuenregs = hard_regno_nregs (valueno, mode);
 
   if (!goal_mem && !goal_const
       && regno + nregs > valueno && regno < valueno + valuenregs)
@@ -7234,7 +7234,8 @@  reload_adjust_reg_for_mode (rtx reloadre
   regno = REGNO (reloadreg);
 
   if (REG_WORDS_BIG_ENDIAN)
-    regno += (int) REG_NREGS (reloadreg) - (int) hard_regno_nregs[regno][mode];
+    regno += ((int) REG_NREGS (reloadreg)
+	      - (int) hard_regno_nregs (regno, mode));
 
   return gen_rtx_REG (mode, regno);
 }
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c	2017-09-11 17:17:46.895352189 +0100
+++ gcc/reload1.c	2017-09-11 17:22:43.394273617 +0100
@@ -1711,7 +1711,7 @@  count_pseudo (int reg)
   gcc_assert (r >= 0);
 
   spill_add_cost[r] += freq;
-  nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (reg)];
+  nregs = hard_regno_nregs (r, PSEUDO_REGNO_MODE (reg));
   while (nregs-- > 0)
     {
       hard_regno_to_pseudo_regno[r + nregs] = reg;
@@ -1788,7 +1788,7 @@  count_spilled_pseudo (int spilled, int s
 
   gcc_assert (r >= 0);
 
-  nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (reg)];
+  nregs = hard_regno_nregs (r, PSEUDO_REGNO_MODE (reg));
 
   if (REGNO_REG_SET_P (&spilled_pseudos, reg)
       || spilled + spilled_nregs <= r || r + nregs <= spilled)
@@ -1849,7 +1849,7 @@  find_reg (struct insn_chain *chain, int
 	{
 	  int this_cost = spill_cost[regno];
 	  int ok = 1;
-	  unsigned int this_nregs = hard_regno_nregs[regno][rl->mode];
+	  unsigned int this_nregs = hard_regno_nregs (regno, rl->mode);
 
 	  for (j = 1; j < this_nregs; j++)
 	    {
@@ -1920,7 +1920,7 @@  find_reg (struct insn_chain *chain, int
   if (dump_file)
     fprintf (dump_file, "Using reg %d for reload %d\n", best_reg, rnum);
 
-  rl->nregs = hard_regno_nregs[best_reg][rl->mode];
+  rl->nregs = hard_regno_nregs (best_reg, rl->mode);
   rl->regno = best_reg;
 
   EXECUTE_IF_SET_IN_REG_SET
@@ -5069,7 +5069,7 @@  mark_reload_reg_in_use (unsigned int reg
 clear_reload_reg_in_use (unsigned int regno, int opnum,
 			 enum reload_type type, machine_mode mode)
 {
-  unsigned int nregs = hard_regno_nregs[regno][mode];
+  unsigned int nregs = hard_regno_nregs (regno, mode);
   unsigned int start_regno, end_regno, r;
   int i;
   /* A complication is that for some reload types, inheritance might
@@ -6027,7 +6027,7 @@  free_for_value_p (int regno, machine_mod
 		  enum reload_type type, rtx value, rtx out, int reloadnum,
 		  int ignore_address_reloads)
 {
-  int nregs = hard_regno_nregs[regno][mode];
+  int nregs = hard_regno_nregs (regno, mode);
   while (nregs-- > 0)
     if (! reload_reg_free_for_value_p (regno, regno + nregs, opnum, type,
 				       value, out, reloadnum,
@@ -6223,7 +6223,7 @@  allocate_reload_reg (struct insn_chain *
 		      && ! TEST_HARD_REG_BIT (reload_reg_used_for_inherit,
 					      regnum))))
 	    {
-	      int nr = hard_regno_nregs[regnum][rld[r].mode];
+	      int nr = hard_regno_nregs (regnum, rld[r].mode);
 
 	      /* During the second pass we want to avoid reload registers
 		 which are "bad" for this reload.  */
@@ -6609,7 +6609,7 @@  choose_reload_regs (struct insn_chain *c
 		    {
 		      /* If a group is needed, verify that all the subsequent
 			 registers still have their values intact.  */
-		      int nr = hard_regno_nregs[i][rld[r].mode];
+		      int nr = hard_regno_nregs (i, rld[r].mode);
 		      int k;
 
 		      for (k = 1; k < nr; k++)
@@ -6839,7 +6839,7 @@  choose_reload_regs (struct insn_chain *c
 		  && (regno != HARD_FRAME_POINTER_REGNUM
 		      || !frame_pointer_needed))
 		{
-		  int nr = hard_regno_nregs[regno][rld[r].mode];
+		  int nr = hard_regno_nregs (regno, rld[r].mode);
 		  int k;
 		  rld[r].reg_rtx = equiv;
 		  reload_spill_index[r] = regno;
@@ -7076,7 +7076,7 @@  choose_reload_regs (struct insn_chain *c
 	  int nr = 1;
 
 	  if (nregno < FIRST_PSEUDO_REGISTER)
-	    nr = hard_regno_nregs[nregno][rld[r].mode];
+	    nr = hard_regno_nregs (nregno, rld[r].mode);
 
 	  while (--nr >= 0)
 	    SET_REGNO_REG_SET (&reg_has_output_reload,
@@ -7151,7 +7151,7 @@  reload_adjust_reg_for_temp (rtx *reload_
 	{
 	  if (!targetm.hard_regno_mode_ok (regno, new_mode))
 	    continue;
-	  if (hard_regno_nregs[regno][new_mode] > REG_NREGS (reg))
+	  if (hard_regno_nregs (regno, new_mode) > REG_NREGS (reg))
 	    continue;
 	  reg = reload_adjust_reg_for_mode (reg, new_mode);
 	}
@@ -8195,7 +8195,7 @@  emit_reload_insns (struct insn_chain *ch
 
       if (i >= 0 && rld[r].reg_rtx != 0)
 	{
-	  int nr = hard_regno_nregs[i][GET_MODE (rld[r].reg_rtx)];
+	  int nr = hard_regno_nregs (i, GET_MODE (rld[r].reg_rtx));
 	  int k;
 
 	  /* For a multi register reload, we need to check if all or part
@@ -8239,7 +8239,7 @@  emit_reload_insns (struct insn_chain *ch
 /* AUTO_INC */		     : XEXP (rld[r].in_reg, 0));
 		  int out_regno = REGNO (out);
 		  int out_nregs = (!HARD_REGISTER_NUM_P (out_regno) ? 1
-				   : hard_regno_nregs[out_regno][mode]);
+				   : hard_regno_nregs (out_regno, mode));
 		  bool piecemeal;
 
 		  spill_reg_store[regno] = new_spill_reg_store[regno];
@@ -8321,7 +8321,7 @@  emit_reload_insns (struct insn_chain *ch
 		  in_regno = REGNO (in);
 
 		  in_nregs = (!HARD_REGISTER_NUM_P (in_regno) ? 1
-			      : hard_regno_nregs[in_regno][mode]);
+			      : hard_regno_nregs (in_regno, mode));
 
 		  reg_last_reload_reg[in_regno] = reg;
 
@@ -8450,7 +8450,7 @@  emit_reload_insns (struct insn_chain *ch
 
 		  gcc_assert (GET_MODE (src_reg) == mode);
 		  src_regno = REGNO (src_reg);
-		  src_nregs = hard_regno_nregs[src_regno][mode];
+		  src_nregs = hard_regno_nregs (src_regno, mode);
 		  /* The place where to find a death note varies with
 		     PRESERVE_DEATH_INFO_REGNO_P .  The condition is not
 		     necessarily checked exactly in the code that moves
@@ -8489,7 +8489,7 @@  emit_reload_insns (struct insn_chain *ch
 	    }
 	  else
 	    {
-	      int k, out_nregs = hard_regno_nregs[out_regno][mode];
+	      int k, out_nregs = hard_regno_nregs (out_regno, mode);
 
 	      for (k = 0; k < out_nregs; k++)
 		reg_last_reload_reg[out_regno + k] = 0;
@@ -8861,7 +8861,7 @@  delete_output_reload (rtx_insn *insn, in
     }
 
   /* We will be deleting the insn.  Remove the spill reg information.  */
-  for (k = hard_regno_nregs[last_reload_reg][GET_MODE (reg)]; k-- > 0; )
+  for (k = hard_regno_nregs (last_reload_reg, GET_MODE (reg)); k-- > 0; )
     {
       spill_reg_store[last_reload_reg + k] = 0;
       spill_reg_stored_to[last_reload_reg + k] = 0;
Index: gcc/rtlanal.c
===================================================================
--- gcc/rtlanal.c	2017-09-11 17:15:13.593438926 +0100
+++ gcc/rtlanal.c	2017-09-11 17:22:43.396273238 +0100
@@ -3660,8 +3660,8 @@  subreg_get_info (unsigned int xregno, ma
       gcc_assert (nregs_xmode
 		  == (nunits
 		      * HARD_REGNO_NREGS_WITH_PADDING (xregno, xmode_unit)));
-      gcc_assert (hard_regno_nregs[xregno][xmode]
-		  == hard_regno_nregs[xregno][xmode_unit] * nunits);
+      gcc_assert (hard_regno_nregs (xregno, xmode)
+		  == hard_regno_nregs (xregno, xmode_unit) * nunits);
 
       /* You can only ask for a SUBREG of a value with holes in the middle
 	 if you don't cross the holes.  (Such a SUBREG should be done by
@@ -3680,9 +3680,9 @@  subreg_get_info (unsigned int xregno, ma
 	}
     }
   else
-    nregs_xmode = hard_regno_nregs[xregno][xmode];
+    nregs_xmode = hard_regno_nregs (xregno, xmode);
 
-  nregs_ymode = hard_regno_nregs[xregno][ymode];
+  nregs_ymode = hard_regno_nregs (xregno, ymode);
 
   /* Paradoxical subregs are otherwise valid.  */
   if (!rknown && offset == 0 && ysize > xsize)
Index: gcc/sched-deps.c
===================================================================
--- gcc/sched-deps.c	2017-09-04 11:48:57.534252460 +0100
+++ gcc/sched-deps.c	2017-09-11 17:22:43.397273048 +0100
@@ -2308,7 +2308,7 @@  sched_analyze_reg (struct deps_desc *dep
      If so, mark all of them just like the first.  */
   if (regno < FIRST_PSEUDO_REGISTER)
     {
-      int i = hard_regno_nregs[regno][mode];
+      int i = hard_regno_nregs (regno, mode);
       if (ref == SET)
 	{
 	  while (--i >= 0)
Index: gcc/sel-sched.c
===================================================================
--- gcc/sel-sched.c	2017-09-11 17:16:57.899550774 +0100
+++ gcc/sel-sched.c	2017-09-11 17:22:43.399272670 +0100
@@ -1079,7 +1079,7 @@  init_regs_for_mode (machine_mode mode)
       if (!targetm.hard_regno_mode_ok (cur_reg, mode))
         continue;
 
-      nregs = hard_regno_nregs[cur_reg][mode];
+      nregs = hard_regno_nregs (cur_reg, mode);
 
       for (i = nregs - 1; i >= 0; --i)
         if (fixed_regs[cur_reg + i]
@@ -1262,7 +1262,7 @@  mark_unavailable_hard_regs (def_t def, s
       int nregs;
       int i;
 
-      nregs = hard_regno_nregs[cur_reg][mode];
+      nregs = hard_regno_nregs (cur_reg, mode);
       gcc_assert (nregs > 0);
 
       for (i = nregs - 1; i >= 0; --i)
@@ -1372,7 +1372,7 @@  choose_best_reg_1 (HARD_REG_SET hard_reg
     if (! TEST_HARD_REG_BIT (hard_regs_used, cur_reg))
       {
 	/* Check that all hard regs for mode are available.  */
-	for (i = 1, n = hard_regno_nregs[cur_reg][mode]; i < n; i++)
+	for (i = 1, n = hard_regno_nregs (cur_reg, mode); i < n; i++)
 	  if (TEST_HARD_REG_BIT (hard_regs_used, cur_reg + i)
 	      || !TEST_HARD_REG_BIT (reg_rename_p->available_for_renaming,
 				     cur_reg + i))
@@ -1535,7 +1535,7 @@  verify_target_availability (expr_t expr,
   regno = expr_dest_regno (expr);
   mode = GET_MODE (EXPR_LHS (expr));
   target_available = EXPR_TARGET_AVAILABLE (expr) == 1;
-  n = HARD_REGISTER_NUM_P (regno) ? hard_regno_nregs[regno][mode] : 1;
+  n = HARD_REGISTER_NUM_P (regno) ? hard_regno_nregs (regno, mode) : 1;
 
   live_available = hard_available = true;
   for (i = 0; i < n; i++)
Index: gcc/valtrack.c
===================================================================
--- gcc/valtrack.c	2017-02-23 19:54:03.000000000 +0000
+++ gcc/valtrack.c	2017-09-11 17:22:43.399272670 +0100
@@ -701,7 +701,7 @@  dead_debug_insert_temp (struct dead_debu
 	     the debug temp to.  */
 	  else if (REGNO (reg) < FIRST_PSEUDO_REGISTER
 		   && (REG_NREGS (reg)
-		       != hard_regno_nregs[REGNO (reg)][GET_MODE (dest)]))
+		       != hard_regno_nregs (REGNO (reg), GET_MODE (dest))))
 	    breg = NULL;
 	  /* Yay, we can use SRC, just adjust its mode.  */
 	  else
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c	2017-08-30 12:18:46.633341450 +0100
+++ gcc/var-tracking.c	2017-09-11 17:22:43.402272101 +0100
@@ -5312,7 +5312,7 @@  track_loc_p (rtx loc, tree expr, HOST_WI
   if ((paradoxical_subreg_p (mode, DECL_MODE (expr))
        || (store_reg_p
 	   && !COMPLEX_MODE_P (DECL_MODE (expr))
-	   && hard_regno_nregs[REGNO (loc)][DECL_MODE (expr)] == 1))
+	   && hard_regno_nregs (REGNO (loc), DECL_MODE (expr)) == 1))
       && offset + byte_lowpart_offset (DECL_MODE (expr), mode) == 0)
     {
       mode = DECL_MODE (expr);
@@ -8722,8 +8722,8 @@  emit_note_insn_var_location (variable **
 	  rtx new_loc = NULL;
 
 	  if (REG_P (loc[n_var_parts])
-	      && hard_regno_nregs[REGNO (loc[n_var_parts])][mode] * 2
-		 == hard_regno_nregs[REGNO (loc[n_var_parts])][wider_mode]
+	      && hard_regno_nregs (REGNO (loc[n_var_parts]), mode) * 2
+		 == hard_regno_nregs (REGNO (loc[n_var_parts]), wider_mode)
 	      && end_hard_regno (mode, REGNO (loc[n_var_parts]))
 		 == REGNO (loc2))
 	    {
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c	2017-09-11 17:10:56.047131306 +0100
+++ gcc/varasm.c	2017-09-11 17:22:43.404271722 +0100
@@ -1432,7 +1432,7 @@  make_decl_rtl (tree decl)
 	      name = IDENTIFIER_POINTER (DECL_NAME (decl));
 	      ASM_DECLARE_REGISTER_GLOBAL (asm_out_file, decl, reg_number, name);
 #endif
-	      nregs = hard_regno_nregs[reg_number][mode];
+	      nregs = hard_regno_nregs (reg_number, mode);
 	      while (nregs > 0)
 		globalize_reg (decl, reg_number + --nregs);
 	    }
Index: gcc/reginfo.c
===================================================================
--- gcc/reginfo.c	2017-09-04 11:49:42.940500722 +0100
+++ gcc/reginfo.c	2017-09-11 17:22:43.389274564 +0100
@@ -508,7 +508,8 @@  init_reg_modes_target (void)
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     for (j = 0; j < MAX_MACHINE_MODE; j++)
-      hard_regno_nregs[i][j] = HARD_REGNO_NREGS (i, (machine_mode)j);
+      this_target_regs->x_hard_regno_nregs[i][j]
+	= HARD_REGNO_NREGS (i, (machine_mode)j);
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     {
@@ -518,7 +519,7 @@  init_reg_modes_target (void)
 	 if it is suitable, otherwise fall back on word_mode.  */
       if (reg_raw_mode[i] == VOIDmode)
     	{
-	  if (i > 0 && hard_regno_nregs[i][reg_raw_mode[i - 1]] == 1)
+	  if (i > 0 && hard_regno_nregs (i, reg_raw_mode[i - 1]) == 1)
 	    reg_raw_mode[i] = reg_raw_mode[i - 1];
 	  else
 	    reg_raw_mode[i] = word_mode;
@@ -633,7 +634,7 @@  choose_hard_reg_mode (unsigned int regno
      If we still didn't find a valid mode, try CCmode.  */
 
   FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
-    if ((unsigned) hard_regno_nregs[regno][mode] == nregs
+    if (hard_regno_nregs (regno, mode) == nregs
 	&& targetm.hard_regno_mode_ok (regno, mode)
 	&& (!call_saved
 	    || !targetm.hard_regno_call_part_clobbered (regno, mode))
@@ -641,7 +642,7 @@  choose_hard_reg_mode (unsigned int regno
       found_mode = mode;
 
   FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
-    if ((unsigned) hard_regno_nregs[regno][mode] == nregs
+    if (hard_regno_nregs (regno, mode) == nregs
 	&& targetm.hard_regno_mode_ok (regno, mode)
 	&& (!call_saved
 	    || !targetm.hard_regno_call_part_clobbered (regno, mode))
@@ -649,7 +650,7 @@  choose_hard_reg_mode (unsigned int regno
       found_mode = mode;
 
   FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_FLOAT)
-    if ((unsigned) hard_regno_nregs[regno][mode] == nregs
+    if (hard_regno_nregs (regno, mode) == nregs
 	&& targetm.hard_regno_mode_ok (regno, mode)
 	&& (!call_saved
 	    || !targetm.hard_regno_call_part_clobbered (regno, mode))
@@ -657,7 +658,7 @@  choose_hard_reg_mode (unsigned int regno
       found_mode = mode;
 
   FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
-    if ((unsigned) hard_regno_nregs[regno][mode] == nregs
+    if (hard_regno_nregs (regno, mode) == nregs
 	&& targetm.hard_regno_mode_ok (regno, mode)
 	&& (!call_saved
 	    || !targetm.hard_regno_call_part_clobbered (regno, mode))
@@ -671,7 +672,7 @@  choose_hard_reg_mode (unsigned int regno
   for (m = (unsigned int) CCmode; m < (unsigned int) NUM_MACHINE_MODES; ++m)
     {
       mode = (machine_mode) m;
-      if ((unsigned) hard_regno_nregs[regno][mode] == nregs
+      if (hard_regno_nregs (regno, mode) == nregs
 	  && targetm.hard_regno_mode_ok (regno, mode)
 	  && (!call_saved
 	      || !targetm.hard_regno_call_part_clobbered (regno, mode)))