aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2012-10-02 19:34:38 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2012-10-02 19:34:38 +0000
commitc9d74da68c27d7af5c5c2edef7f723190ab461d2 (patch)
treedb8ded671097465c0fd2ce2c9d3774344bcda7fc
parent59a2dfe8d754913ff356c83e1c9a7106a69aad11 (diff)
downloadgcc-c9d74da68c27d7af5c5c2edef7f723190ab461d2.zip
gcc-c9d74da68c27d7af5c5c2edef7f723190ab461d2.tar.gz
gcc-c9d74da68c27d7af5c5c2edef7f723190ab461d2.tar.bz2
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
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/ira-build.c7
-rw-r--r--gcc/ira-lives.c32
-rw-r--r--gcc/ira.c16
-rw-r--r--gcc/ira.h6
5 files changed, 55 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0a6a139..ad6c14b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+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
diff --git a/gcc/ira-build.c b/gcc/ira-build.c
index dba1d46..1181813 100644
--- a/gcc/ira-build.c
+++ b/gcc/ira-build.c
@@ -3047,11 +3047,10 @@ update_conflict_hard_reg_costs (void)
{
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
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c
index 0de1b81..853832e 100644
--- a/gcc/ira-lives.c
+++ b/gcc/ira-lives.c
@@ -849,9 +849,10 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
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;
@@ -861,10 +862,10 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
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;
@@ -939,13 +940,14 @@ ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set)
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;
}
}
@@ -989,8 +991,7 @@ process_single_reg_class_operands (bool in_p, int freq)
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:
@@ -1004,7 +1005,8 @@ process_single_reg_class_operands (bool in_p, int freq)
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);
diff --git a/gcc/ira.c b/gcc/ira.c
index ad0ae0a..8436f60 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -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
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--)
{
@@ -1468,7 +1473,14 @@ setup_prohibited_class_mode_regs (void)
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);
}
}
}
diff --git a/gcc/ira.h b/gcc/ira.h
index d53db4e..6870c4b 100644
--- a/gcc/ira.h
+++ b/gcc/ira.h
@@ -79,6 +79,10 @@ struct target_ira {
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;
@@ -117,6 +121,8 @@ extern struct target_ira *this_target_ira;
(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)