Commit c9d74da6 by Richard Sandiford Committed by Richard Sandiford

ira.h (target_ira): Add x_ira_class_singleton.

gcc/
	* 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.

From-SVN: r191995
parent 59a2dfe8
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> 2012-10-02 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/rs6000.c (rs6000_option_override_internal): If * config/rs6000/rs6000.c (rs6000_option_override_internal): If
......
...@@ -3047,11 +3047,10 @@ update_conflict_hard_reg_costs (void) ...@@ -3047,11 +3047,10 @@ update_conflict_hard_reg_costs (void)
{ {
reg_class_t aclass = ALLOCNO_CLASS (a); reg_class_t aclass = ALLOCNO_CLASS (a);
reg_class_t pref = reg_preferred_class (ALLOCNO_REGNO (a)); reg_class_t pref = reg_preferred_class (ALLOCNO_REGNO (a));
int singleton = ira_class_singleton[pref][ALLOCNO_MODE (a)];
if (reg_class_size[(int) pref] != 1) if (singleton < 0)
continue; continue;
index = ira_class_hard_reg_index[(int) aclass] index = ira_class_hard_reg_index[(int) aclass][singleton];
[ira_class_hard_regs[(int) pref][0]];
if (index < 0) if (index < 0)
continue; continue;
if (ALLOCNO_CONFLICT_HARD_REG_COSTS (a) == NULL if (ALLOCNO_CONFLICT_HARD_REG_COSTS (a) == NULL
......
...@@ -849,9 +849,10 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const) ...@@ -849,9 +849,10 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
next_cl = (c == 'r' next_cl = (c == 'r'
? GENERAL_REGS ? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT (c, constraints)); : REG_CLASS_FROM_CONSTRAINT (c, constraints));
if ((cl != NO_REGS && next_cl != cl) if (cl == NO_REGS
|| (ira_class_hard_regs_num[next_cl] ? ira_class_singleton[next_cl][GET_MODE (op)] < 0
> ira_reg_class_max_nregs[next_cl][GET_MODE (op)])) : (ira_class_singleton[cl][GET_MODE (op)]
!= ira_class_singleton[next_cl][GET_MODE (op)]))
return NO_REGS; return NO_REGS;
cl = next_cl; cl = next_cl;
break; break;
...@@ -861,10 +862,10 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const) ...@@ -861,10 +862,10 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
next_cl next_cl
= single_reg_class (recog_data.constraints[c - '0'], = single_reg_class (recog_data.constraints[c - '0'],
recog_data.operand[c - '0'], NULL_RTX); recog_data.operand[c - '0'], NULL_RTX);
if ((cl != NO_REGS && next_cl != cl) if (cl == NO_REGS
|| next_cl == NO_REGS ? ira_class_singleton[next_cl][GET_MODE (op)] < 0
|| (ira_class_hard_regs_num[next_cl] : (ira_class_singleton[cl][GET_MODE (op)]
> ira_reg_class_max_nregs[next_cl][GET_MODE (op)])) != ira_class_singleton[next_cl][GET_MODE (op)]))
return NO_REGS; return NO_REGS;
cl = next_cl; cl = next_cl;
break; break;
...@@ -939,13 +940,14 @@ ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set) ...@@ -939,13 +940,14 @@ ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set)
cl = (c == 'r' cl = (c == 'r'
? GENERAL_REGS ? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT (c, p)); : REG_CLASS_FROM_CONSTRAINT (c, p));
if (cl != NO_REGS if (cl != NO_REGS)
{
/* There is no register pressure problem if all of the /* There is no register pressure problem if all of the
regs in this class are fixed. */ regs in this class are fixed. */
&& ira_class_hard_regs_num[cl] != 0 int regno = ira_class_singleton[cl][mode];
&& (ira_class_hard_regs_num[cl] if (regno >= 0)
<= ira_reg_class_max_nregs[cl][mode])) add_to_hard_reg_set (set, mode, regno);
IOR_HARD_REG_SET (*set, reg_class_contents[cl]); }
break; break;
} }
} }
...@@ -989,8 +991,7 @@ process_single_reg_class_operands (bool in_p, int freq) ...@@ -989,8 +991,7 @@ process_single_reg_class_operands (bool in_p, int freq)
operand_a = ira_curr_regno_allocno_map[regno]; operand_a = ira_curr_regno_allocno_map[regno];
aclass = ALLOCNO_CLASS (operand_a); aclass = ALLOCNO_CLASS (operand_a);
if (ira_class_subset_p[cl][aclass] if (ira_class_subset_p[cl][aclass])
&& ira_class_hard_regs_num[cl] != 0)
{ {
/* View the desired allocation of OPERAND as: /* View the desired allocation of OPERAND as:
...@@ -1004,7 +1005,8 @@ process_single_reg_class_operands (bool in_p, int freq) ...@@ -1004,7 +1005,8 @@ process_single_reg_class_operands (bool in_p, int freq)
HOST_WIDE_INT offset; HOST_WIDE_INT offset;
xmode = recog_data.operand_mode[i]; 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); ymode = ALLOCNO_MODE (operand_a);
offset = subreg_lowpart_offset (ymode, xmode); offset = subreg_lowpart_offset (ymode, xmode);
yregno = simplify_subreg_regno (xregno, xmode, offset, ymode); yregno = simplify_subreg_regno (xregno, xmode, offset, ymode);
......
...@@ -1451,16 +1451,21 @@ setup_reg_class_nregs (void) ...@@ -1451,16 +1451,21 @@ setup_reg_class_nregs (void)
/* 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 static void
setup_prohibited_class_mode_regs (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--) 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++) 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]); CLEAR_HARD_REG_SET (ira_prohibited_class_mode_regs[cl][j]);
for (k = ira_class_hard_regs_num[cl] - 1; k >= 0; k--) for (k = ira_class_hard_regs_num[cl] - 1; k >= 0; k--)
{ {
...@@ -1468,7 +1473,14 @@ setup_prohibited_class_mode_regs (void) ...@@ -1468,7 +1473,14 @@ setup_prohibited_class_mode_regs (void)
if (! HARD_REGNO_MODE_OK (hard_regno, (enum machine_mode) j)) if (! HARD_REGNO_MODE_OK (hard_regno, (enum machine_mode) j))
SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j],
hard_regno); 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);
} }
} }
} }
......
...@@ -79,6 +79,10 @@ struct target_ira { ...@@ -79,6 +79,10 @@ struct target_ira {
class. */ class. */
int x_ira_class_hard_regs_num[N_REG_CLASSES]; 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 /* Function specific hard registers can not be used for the register
allocation. */ allocation. */
HARD_REG_SET x_ira_no_alloc_regs; HARD_REG_SET x_ira_no_alloc_regs;
...@@ -117,6 +121,8 @@ extern struct target_ira *this_target_ira; ...@@ -117,6 +121,8 @@ extern struct target_ira *this_target_ira;
(this_target_ira->x_ira_class_hard_regs) (this_target_ira->x_ira_class_hard_regs)
#define ira_class_hard_regs_num \ #define ira_class_hard_regs_num \
(this_target_ira->x_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 \ #define ira_no_alloc_regs \
(this_target_ira->x_ira_no_alloc_regs) (this_target_ira->x_ira_no_alloc_regs)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment