diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-02 19:34:38 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-02 19:34:38 +0000 |
commit | c259678fdd8088668cb71fe2d6c00920ea24f815 (patch) | |
tree | db8ded671097465c0fd2ce2c9d3774344bcda7fc /gcc | |
parent | 61e26f31fae6b504f618bed1f6eb41018572ecc3 (diff) | |
download | gcc-c259678fdd8088668cb71fe2d6c00920ea24f815.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@191995 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/ira-build.c | 7 | ||||
-rw-r--r-- | gcc/ira-lives.c | 32 | ||||
-rw-r--r-- | gcc/ira.c | 16 | ||||
-rw-r--r-- | gcc/ira.h | 6 |
5 files changed, 55 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0a6a13953fb..ad6c14bac81 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 dba1d467ad7..1181813d92b 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 0de1b81b73f..853832e3c9f 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 ad0ae0a8e6e..8436f606d97 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 d53db4e0cee..6870c4bf303 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) |