This is another patch needed for the MIPS MD_REGS change described here: http://gcc.gnu.org/ml/gcc-patches/2012-09/msg01992.html
The profitable_hard_regs set used during IRA colouring used to be restricted to registers that are valid for the allocno's mode. That caused problems for multi-register modes that can only start with an even register (say), because profitable_hard_regs would only include the even start registers, not the pairing odd registers. Vlad fixed it with: 2011-04-08 Vladimir Makarov <vmaka...@redhat.com> PR inline-asm/48435 * ira-color.c (setup_profitable_hard_regs): Add comments. Don't take prohibited hard regs into account. (setup_conflict_profitable_regs): Rename to get_conflict_profitable_regs. (check_hard_reg_p): Check prohibited hard regs. However, one effect of that change is that if register R belongs to class CL but can never be used anywhere in a register of mode M, it will still be included in profitable_hard_regs. That's the case with MD_REGS and register HI on MIPS. The patch below is a half-way house between the original behaviour and the post-48435 one. It restricts profitable_hard_regs to registers that can be used for the allocno's mode, but doesn't restrict it to starting registers. Most of the ira.c change is reindentation, so I've included a -b diff as well. As with the patch linked above, I checked that this produced no difference in assembly output for a set of x86_64 gcc .ii files (tested with -O2 -march=native on gcc20). Also tested on x86_64-linux-gnu (including -m32) and mipsisa64-elf. OK to install? Richard gcc/ * ira-int.h (target_ira_int): Add x_ira_useful_class_mode_regs. (ira_useful_class_mode_regs): New macro. * ira.c (clarify_prohibited_class_mode_regs): Set up ira_useful_class_mode_regs. * ira-color.c (setup_profitable_hard_regs): Use it to initialise profitable_hard_regs. Index: gcc/ira-int.h =================================================================== --- gcc/ira-int.h 2012-09-30 18:59:09.463447170 +0100 +++ gcc/ira-int.h 2012-09-30 19:21:59.395407339 +0100 @@ -816,6 +816,20 @@ struct target_ira_int { values for given mode are zero. */ HARD_REG_SET x_ira_prohibited_class_mode_regs[N_REG_CLASSES][NUM_MACHINE_MODES]; + /* Index [CL][M] contains R if R appears somewhere in a register of the form: + + (reg:M R'), R' not in x_ira_prohibited_class_mode_regs[CL][M] + + For example, if: + + - (reg:M 2) is valid and occupies two registers; + - register 2 belongs to CL; and + - register 3 belongs to the same pressure class as CL + + then (reg:M 2) contributes to [CL][M] and registers 2 and 3 will be + in the set. */ + HARD_REG_SET x_ira_useful_class_mode_regs[N_REG_CLASSES][NUM_MACHINE_MODES]; + /* The value is number of elements in the subsequent array. */ int x_ira_important_classes_num; @@ -902,6 +916,8 @@ #define ira_class_hard_reg_index \ (this_target_ira_int->x_ira_class_hard_reg_index) #define ira_prohibited_class_mode_regs \ (this_target_ira_int->x_ira_prohibited_class_mode_regs) +#define ira_useful_class_mode_regs \ + (this_target_ira_int->x_ira_useful_class_mode_regs) #define ira_important_classes_num \ (this_target_ira_int->x_ira_important_classes_num) #define ira_important_classes \ Index: gcc/ira.c =================================================================== --- gcc/ira.c 2012-09-30 19:20:32.555409864 +0100 +++ gcc/ira.c 2012-09-30 19:21:59.396407339 +0100 @@ -1495,29 +1495,36 @@ clarify_prohibited_class_mode_regs (void for (cl = (int) N_REG_CLASSES - 1; cl >= 0; cl--) for (j = 0; j < NUM_MACHINE_MODES; j++) - for (k = ira_class_hard_regs_num[cl] - 1; k >= 0; k--) - { - hard_regno = ira_class_hard_regs[cl][k]; - if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], hard_regno)) - continue; - nregs = hard_regno_nregs[hard_regno][j]; - if (hard_regno + nregs > FIRST_PSEUDO_REGISTER) - { - SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], - hard_regno); - continue; - } - pclass = ira_pressure_class_translate[REGNO_REG_CLASS (hard_regno)]; - for (nregs-- ;nregs >= 0; nregs--) - if (((enum reg_class) pclass - != ira_pressure_class_translate[REGNO_REG_CLASS - (hard_regno + nregs)])) + { + CLEAR_HARD_REG_SET (ira_useful_class_mode_regs[cl][j]); + for (k = ira_class_hard_regs_num[cl] - 1; k >= 0; k--) + { + hard_regno = ira_class_hard_regs[cl][k]; + if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], hard_regno)) + continue; + nregs = hard_regno_nregs[hard_regno][j]; + if (hard_regno + nregs > FIRST_PSEUDO_REGISTER) { SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], hard_regno); - break; + continue; } - } + pclass = ira_pressure_class_translate[REGNO_REG_CLASS (hard_regno)]; + for (nregs-- ;nregs >= 0; nregs--) + if (((enum reg_class) pclass + != ira_pressure_class_translate[REGNO_REG_CLASS + (hard_regno + nregs)])) + { + SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], + hard_regno); + break; + } + if (!TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], + hard_regno)) + add_to_hard_reg_set (&ira_useful_class_mode_regs[cl][j], + (enum machine_mode) j, hard_regno); + } + } } /* Allocate and initialize IRA_REGISTER_MOVE_COST, IRA_MAY_MOVE_IN_COST Index: gcc/ira-color.c =================================================================== --- gcc/ira-color.c 2012-09-30 18:59:09.463447170 +0100 +++ gcc/ira-color.c 2012-09-30 19:21:59.394407339 +0100 @@ -1023,10 +1023,9 @@ setup_profitable_hard_regs (void) CLEAR_HARD_REG_SET (data->profitable_hard_regs); else { + mode = ALLOCNO_MODE (a); COPY_HARD_REG_SET (data->profitable_hard_regs, - reg_class_contents[aclass]); - AND_COMPL_HARD_REG_SET (data->profitable_hard_regs, - ira_no_alloc_regs); + ira_useful_class_mode_regs[aclass][mode]); nobj = ALLOCNO_NUM_OBJECTS (a); for (k = 0; k < nobj; k++) {
Index: gcc/ira-color.c =================================================================== --- gcc/ira-color.c 2012-09-30 18:59:09.463447170 +0100 +++ gcc/ira-color.c 2012-09-30 19:21:59.394407339 +0100 @@ -1023,10 +1023,9 @@ setup_profitable_hard_regs (void) CLEAR_HARD_REG_SET (data->profitable_hard_regs); else { + mode = ALLOCNO_MODE (a); COPY_HARD_REG_SET (data->profitable_hard_regs, - reg_class_contents[aclass]); - AND_COMPL_HARD_REG_SET (data->profitable_hard_regs, - ira_no_alloc_regs); + ira_useful_class_mode_regs[aclass][mode]); nobj = ALLOCNO_NUM_OBJECTS (a); for (k = 0; k < nobj; k++) { Index: gcc/ira-int.h =================================================================== --- gcc/ira-int.h 2012-09-30 18:59:09.463447170 +0100 +++ gcc/ira-int.h 2012-09-30 19:21:59.395407339 +0100 @@ -816,6 +816,20 @@ struct target_ira_int { values for given mode are zero. */ HARD_REG_SET x_ira_prohibited_class_mode_regs[N_REG_CLASSES][NUM_MACHINE_MODES]; + /* Index [CL][M] contains R if R appears somewhere in a register of the form: + + (reg:M R'), R' not in x_ira_prohibited_class_mode_regs[CL][M] + + For example, if: + + - (reg:M 2) is valid and occupies two registers; + - register 2 belongs to CL; and + - register 3 belongs to the same pressure class as CL + + then (reg:M 2) contributes to [CL][M] and registers 2 and 3 will be + in the set. */ + HARD_REG_SET x_ira_useful_class_mode_regs[N_REG_CLASSES][NUM_MACHINE_MODES]; + /* The value is number of elements in the subsequent array. */ int x_ira_important_classes_num; @@ -902,6 +916,8 @@ #define ira_class_hard_reg_index \ (this_target_ira_int->x_ira_class_hard_reg_index) #define ira_prohibited_class_mode_regs \ (this_target_ira_int->x_ira_prohibited_class_mode_regs) +#define ira_useful_class_mode_regs \ + (this_target_ira_int->x_ira_useful_class_mode_regs) #define ira_important_classes_num \ (this_target_ira_int->x_ira_important_classes_num) #define ira_important_classes \ Index: gcc/ira.c =================================================================== --- gcc/ira.c 2012-09-30 19:20:32.555409864 +0100 +++ gcc/ira.c 2012-09-30 19:21:59.396407339 +0100 @@ -1495,6 +1495,8 @@ clarify_prohibited_class_mode_regs (void for (cl = (int) N_REG_CLASSES - 1; cl >= 0; cl--) for (j = 0; j < NUM_MACHINE_MODES; j++) + { + CLEAR_HARD_REG_SET (ira_useful_class_mode_regs[cl][j]); for (k = ira_class_hard_regs_num[cl] - 1; k >= 0; k--) { hard_regno = ira_class_hard_regs[cl][k]; @@ -1517,6 +1519,11 @@ clarify_prohibited_class_mode_regs (void hard_regno); break; } + if (!TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], + hard_regno)) + add_to_hard_reg_set (&ira_useful_class_mode_regs[cl][j], + (enum machine_mode) j, hard_regno); + } } }