static vec<reg_stat_type> reg_stat;
+/* One plus the highest pseudo for which we track REG_N_SETS.
+ regstat_init_n_sets_and_refs allocates the array for REG_N_SETS just once,
+ but during combine_split_insns new pseudos can be created. As we don't have
+ updated DF information in that case, it is hard to initialize the array
+ after growing. The combiner only cares about REG_N_SETS (regno) == 1,
+ so instead of growing the arrays, just assume all newly created pseudos
+ during combine might be set multiple times. */
+
+static unsigned int reg_n_sets_max;
+
/* Record the luid of the last insn that invalidated memory
(anything that writes memory, and subroutine calls, but not pushes). */
>= hard_regno_nregs[regno][mode]));
/* Or a pseudo that is only used once. */
- return (REG_N_SETS (regno) == 1 && !added_sets
+ return (regno < reg_n_sets_max
+ && REG_N_SETS (regno) == 1
+ && !added_sets
&& !REG_USERVAR_P (x));
}
if (REG_P (new_i3_dest)
&& REG_P (new_i2_dest)
- && REGNO (new_i3_dest) == REGNO (new_i2_dest))
+ && REGNO (new_i3_dest) == REGNO (new_i2_dest)
+ && REGNO (new_i2_dest) < reg_n_sets_max)
INC_REG_N_SETS (REGNO (new_i2_dest), 1);
}
}
zero its use count so it won't make `reload' do any work. */
if (! added_sets_2
&& (newi2pat == 0 || ! reg_mentioned_p (i2dest, newi2pat))
- && ! i2dest_in_i2src)
+ && ! i2dest_in_i2src
+ && REGNO (i2dest) < reg_n_sets_max)
INC_REG_N_SETS (REGNO (i2dest), -1);
}
record_value_for_reg (i1dest, i1_insn, i1_val);
- if (! added_sets_1 && ! i1dest_in_i1src)
+ if (! added_sets_1
+ && ! i1dest_in_i1src
+ && REGNO (i1dest) < reg_n_sets_max)
INC_REG_N_SETS (REGNO (i1dest), -1);
}
record_value_for_reg (i0dest, i0_insn, i0_val);
- if (! added_sets_0 && ! i0dest_in_i0src)
+ if (! added_sets_0
+ && ! i0dest_in_i0src
+ && REGNO (i0dest) < reg_n_sets_max)
INC_REG_N_SETS (REGNO (i0dest), -1);
}
|| (rsp->last_set_label == label_tick
&& DF_INSN_LUID (rsp->last_set) < subst_low_luid)
|| (REGNO (x) >= FIRST_PSEUDO_REGISTER
+ && REGNO (x) < reg_n_sets_max
&& REG_N_SETS (REGNO (x)) == 1
&& !REGNO_REG_SET_P
(DF_LR_IN (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb),
|| (rsp->last_set_label == label_tick
&& DF_INSN_LUID (rsp->last_set) < subst_low_luid)
|| (REGNO (x) >= FIRST_PSEUDO_REGISTER
+ && REGNO (x) < reg_n_sets_max
&& REG_N_SETS (REGNO (x)) == 1
&& !REGNO_REG_SET_P
(DF_LR_IN (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb),
/* If this is a pseudo-register that was only set once and not
live at the beginning of the function, it is always valid. */
|| (! (regno >= FIRST_PSEUDO_REGISTER
+ && regno < reg_n_sets_max
&& REG_N_SETS (regno) == 1
&& (!REGNO_REG_SET_P
(DF_LR_IN (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb),
if (value == 0
|| (rsp->last_set_label < label_tick_ebb_start
&& (regno < FIRST_PSEUDO_REGISTER
+ || regno >= reg_n_sets_max
|| REG_N_SETS (regno) != 1
|| REGNO_REG_SET_P
(DF_LR_IN (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb), regno))))
df_analyze ();
regstat_init_n_sets_and_refs ();
+ reg_n_sets_max = max_reg_num ();
rebuild_jump_labels_after_combine
= combine_instructions (get_insns (), max_reg_num ());