+2012-10-02 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * ira.h (target_ira): Add x_ira_class_singleton.
+ (ira_class_singleton): New macro.
+ * ira.c (setup_prohibited_class_mode_regs): Set up ira_class_singleton.
+ * ira-build.c (update_conflict_hard_reg_costs): Use
+ ira_class_singleton to check for classes with a single
+ allocatable register.
+ * ira-lives.c (ira_implicitly_set_insn_hard_regs): Likewise.
+ (single_reg_class): Likewise. When more than one class is specified,
+ check whether they have the same singleton register.
+ (process_single_reg_class_operands): Require single_reg_class
+ to return NO_REGS or a class with a single allocatable register.
+ Obtain that register from ira_class_singleton.
+
2012-10-02 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/rs6000.c (rs6000_option_override_internal): If
{
reg_class_t aclass = ALLOCNO_CLASS (a);
reg_class_t pref = reg_preferred_class (ALLOCNO_REGNO (a));
-
- if (reg_class_size[(int) pref] != 1)
+ int singleton = ira_class_singleton[pref][ALLOCNO_MODE (a)];
+ if (singleton < 0)
continue;
- index = ira_class_hard_reg_index[(int) aclass]
- [ira_class_hard_regs[(int) pref][0]];
+ index = ira_class_hard_reg_index[(int) aclass][singleton];
if (index < 0)
continue;
if (ALLOCNO_CONFLICT_HARD_REG_COSTS (a) == NULL
next_cl = (c == 'r'
? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT (c, constraints));
- if ((cl != NO_REGS && next_cl != cl)
- || (ira_class_hard_regs_num[next_cl]
- > ira_reg_class_max_nregs[next_cl][GET_MODE (op)]))
+ if (cl == NO_REGS
+ ? ira_class_singleton[next_cl][GET_MODE (op)] < 0
+ : (ira_class_singleton[cl][GET_MODE (op)]
+ != ira_class_singleton[next_cl][GET_MODE (op)]))
return NO_REGS;
cl = next_cl;
break;
next_cl
= single_reg_class (recog_data.constraints[c - '0'],
recog_data.operand[c - '0'], NULL_RTX);
- if ((cl != NO_REGS && next_cl != cl)
- || next_cl == NO_REGS
- || (ira_class_hard_regs_num[next_cl]
- > ira_reg_class_max_nregs[next_cl][GET_MODE (op)]))
+ if (cl == NO_REGS
+ ? ira_class_singleton[next_cl][GET_MODE (op)] < 0
+ : (ira_class_singleton[cl][GET_MODE (op)]
+ != ira_class_singleton[next_cl][GET_MODE (op)]))
return NO_REGS;
cl = next_cl;
break;
cl = (c == 'r'
? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT (c, p));
- if (cl != NO_REGS
+ if (cl != NO_REGS)
+ {
/* There is no register pressure problem if all of the
regs in this class are fixed. */
- && ira_class_hard_regs_num[cl] != 0
- && (ira_class_hard_regs_num[cl]
- <= ira_reg_class_max_nregs[cl][mode]))
- IOR_HARD_REG_SET (*set, reg_class_contents[cl]);
+ int regno = ira_class_singleton[cl][mode];
+ if (regno >= 0)
+ add_to_hard_reg_set (set, mode, regno);
+ }
break;
}
}
operand_a = ira_curr_regno_allocno_map[regno];
aclass = ALLOCNO_CLASS (operand_a);
- if (ira_class_subset_p[cl][aclass]
- && ira_class_hard_regs_num[cl] != 0)
+ if (ira_class_subset_p[cl][aclass])
{
/* View the desired allocation of OPERAND as:
HOST_WIDE_INT offset;
xmode = recog_data.operand_mode[i];
- xregno = ira_class_hard_regs[cl][0];
+ xregno = ira_class_singleton[cl][xmode];
+ gcc_assert (xregno >= 0);
ymode = ALLOCNO_MODE (operand_a);
offset = subreg_lowpart_offset (ymode, xmode);
yregno = simplify_subreg_regno (xregno, xmode, offset, ymode);
\f
-/* Set up IRA_PROHIBITED_CLASS_MODE_REGS. */
+/* Set up IRA_PROHIBITED_CLASS_MODE_REGS and IRA_CLASS_SINGLETON.
+ This function is called once IRA_CLASS_HARD_REGS has been initialized. */
static void
setup_prohibited_class_mode_regs (void)
{
- int j, k, hard_regno, cl;
+ int j, k, hard_regno, cl, last_hard_regno, count;
for (cl = (int) N_REG_CLASSES - 1; cl >= 0; cl--)
{
+ COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
+ AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
for (j = 0; j < NUM_MACHINE_MODES; j++)
{
+ count = 0;
+ last_hard_regno = -1;
CLEAR_HARD_REG_SET (ira_prohibited_class_mode_regs[cl][j]);
for (k = ira_class_hard_regs_num[cl] - 1; k >= 0; k--)
{
if (! HARD_REGNO_MODE_OK (hard_regno, (enum machine_mode) j))
SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j],
hard_regno);
+ else if (in_hard_reg_set_p (temp_hard_regset,
+ (enum machine_mode) j, hard_regno))
+ {
+ last_hard_regno = hard_regno;
+ count++;
+ }
}
+ ira_class_singleton[cl][j] = (count == 1 ? last_hard_regno : -1);
}
}
}
class. */
int x_ira_class_hard_regs_num[N_REG_CLASSES];
+ /* If class CL has a single allocatable register of mode M,
+ index [CL][M] gives the number of that register, otherwise it is -1. */
+ short x_ira_class_singleton[N_REG_CLASSES][MAX_MACHINE_MODE];
+
/* Function specific hard registers can not be used for the register
allocation. */
HARD_REG_SET x_ira_no_alloc_regs;
(this_target_ira->x_ira_class_hard_regs)
#define ira_class_hard_regs_num \
(this_target_ira->x_ira_class_hard_regs_num)
+#define ira_class_singleton \
+ (this_target_ira->x_ira_class_singleton)
#define ira_no_alloc_regs \
(this_target_ira->x_ira_no_alloc_regs)