@@ -284,6 +284,9 @@ typedef struct reg_stat_struct {
static vec<reg_stat_type> reg_stat;
+/* Highest pseudo for which we track REG_N_SETS. */
+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). */
@@ -2420,7 +2423,9 @@ can_change_dest_mode (rtx x, int added_s
>= 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));
}
@@ -3630,7 +3635,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2,
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);
}
}
@@ -4480,7 +4486,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2,
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);
}
@@ -4497,7 +4504,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2,
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);
}
@@ -4514,7 +4523,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2,
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);
}
@@ -9750,6 +9761,7 @@ reg_nonzero_bits_for_combine (const_rtx
|| (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),
@@ -9825,6 +9837,7 @@ reg_num_sign_bit_copies_for_combine (con
|| (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),
@@ -12863,6 +12876,7 @@ get_last_value_validate (rtx *loc, rtx_i
/* 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),
@@ -12979,6 +12993,7 @@ get_last_value (const_rtx x)
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))))
@@ -14166,6 +14181,7 @@ rest_of_handle_combine (void)
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 ());