diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6108adbb201..030667df9f4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2000-05-27 Geoffrey Keating + + * config/rs6000/rs6000.md (movsi): Constify 'name'. + + * regclass.c [CLASS_CANNOT_CHANGE_SIZE] + (class_can_change_size): New variable. + (reg_changes_size): New variable. + (init_reg_sets_1): Initialise class_can_change_size. + (record_operand_costs): Remove subreg_changes_size. + Don't pass it around. Instead update reg_changes_size. + (regclass): Initialise and free reg_changes_size. If a register + changes size, don't preference it to a class that contains + registers that can't change size. + (record_reg_classes): Don't look at subreg_changes_size. + 2000-05-27 Richard Henderson * print-rtl.c (reg_names): Remove const. diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 589d3c72f7f..3b406f65fe5 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -7481,7 +7481,7 @@ && GET_CODE (operands[1]) == SYMBOL_REF && XSTR (operands[1], 0)[0] == '.') { - char *name = XSTR (operands[1], 0); + const char *name = XSTR (operands[1], 0); rtx new_ref; while (*name == '.') name++; diff --git a/gcc/regclass.c b/gcc/regclass.c index f3fdf4c4d9a..6a741a64b4b 100644 --- a/gcc/regclass.c +++ b/gcc/regclass.c @@ -203,6 +203,19 @@ static char *in_inc_dec; #endif /* FORBIDDEN_INC_DEC_CLASSES */ +#ifdef CLASS_CANNOT_CHANGE_SIZE + +/* These are the classes containing only registers that can be used in + a SUBREG expression that changes the size of the register. */ + +static int class_can_change_size[N_REG_CLASSES]; + +/* Registers, including pseudos, which change size. */ + +static regset reg_changes_size; + +#endif /* CLASS_CANNOT_CHANGE_SIZE */ + #ifdef HAVE_SECONDARY_RELOADS /* Sample MEM values for use by memory_move_secondary_cost. */ @@ -444,6 +457,22 @@ init_reg_sets_1 () else may_move_out_cost[i][j] = cost; } + +#ifdef CLASS_CANNOT_CHANGE_SIZE + { + HARD_REG_SET c; + COMPL_HARD_REG_SET (c, reg_class_contents[CLASS_CANNOT_CHANGE_SIZE]); + + for (i = 0; i < N_REG_CLASSES; i++) + { + GO_IF_HARD_REG_SUBSET (reg_class_contents[i], c, ok_class); + class_can_change_size [i] = 0; + continue; + ok_class: + class_can_change_size [i] = 1; + } + } +#endif /* CLASS_CANNOT_CHANGE_SIZE */ } /* Compute the table of register modes. @@ -725,7 +754,7 @@ static rtx scan_one_insn PARAMS ((rtx, int)); static void record_operand_costs PARAMS ((rtx, struct costs *, struct reg_pref *)); static void dump_regclass PARAMS ((FILE *)); static void record_reg_classes PARAMS ((int, int, rtx *, enum machine_mode *, - char *, const char **, rtx, + const char **, rtx, struct costs *, struct reg_pref *)); static int copy_cost PARAMS ((rtx, enum machine_mode, enum reg_class, int)); @@ -809,7 +838,6 @@ record_operand_costs (insn, op_costs, reg_pref) { const char *constraints[MAX_RECOG_OPERANDS]; enum machine_mode modes[MAX_RECOG_OPERANDS]; - char subreg_changes_size[MAX_RECOG_OPERANDS]; int i; for (i = 0; i < recog_data.n_operands; i++) @@ -817,7 +845,6 @@ record_operand_costs (insn, op_costs, reg_pref) constraints[i] = recog_data.constraints[i]; modes[i] = recog_data.operand_mode[i]; } - memset (subreg_changes_size, 0, sizeof (subreg_changes_size)); /* If we get here, we are set up to record the costs of all the operands for this insn. Start by initializing the costs. @@ -832,8 +859,9 @@ record_operand_costs (insn, op_costs, reg_pref) if (GET_CODE (recog_data.operand[i]) == SUBREG) { rtx inner = SUBREG_REG (recog_data.operand[i]); - if (GET_MODE_SIZE (modes[i]) != GET_MODE_SIZE (GET_MODE (inner))) - subreg_changes_size[i] = 1; + if (GET_MODE_SIZE (modes[i]) != GET_MODE_SIZE (GET_MODE (inner)) + && GET_CODE (inner) == REG) + SET_REGNO_REG_SET (reg_changes_size, REGNO (inner)); recog_data.operand[i] = inner; } @@ -864,12 +892,12 @@ record_operand_costs (insn, op_costs, reg_pref) xconstraints[i] = constraints[i+1]; xconstraints[i+1] = constraints[i]; record_reg_classes (recog_data.n_alternatives, recog_data.n_operands, - recog_data.operand, modes, subreg_changes_size, + recog_data.operand, modes, xconstraints, insn, op_costs, reg_pref); } record_reg_classes (recog_data.n_alternatives, recog_data.n_operands, - recog_data.operand, modes, subreg_changes_size, + recog_data.operand, modes, constraints, insn, op_costs, reg_pref); } @@ -1017,6 +1045,10 @@ regclass (f, nregs, dump) costs = (struct costs *) xmalloc (nregs * sizeof (struct costs)); +#ifdef CLASS_CANNOT_CHANGE_SIZE + reg_changes_size = BITMAP_XMALLOC(); +#endif + #ifdef FORBIDDEN_INC_DEC_CLASSES in_inc_dec = (char *) xmalloc (nregs); @@ -1154,6 +1186,10 @@ regclass (f, nregs, dump) > reg_class_size[class] #ifdef FORBIDDEN_INC_DEC_CLASSES || (in_inc_dec[i] && forbidden_inc_dec_class[class]) +#endif +#ifdef CLASS_CANNOT_CHANGE_SIZE + || (REGNO_REG_SET_P (reg_changes_size, i) + && ! class_can_change_size [class]) #endif ) ; @@ -1180,6 +1216,10 @@ regclass (f, nregs, dump) > reg_class_size[(int) alt]) #ifdef FORBIDDEN_INC_DEC_CLASSES && ! (in_inc_dec[i] && forbidden_inc_dec_class[class]) +#endif +#ifdef CLASS_CANNOT_CHANGE_SIZE + && ! (REGNO_REG_SET_P (reg_changes_size, i) + && ! class_can_change_size [class]) #endif ) alt = reg_class_subunion[(int) alt][class]; @@ -1212,6 +1252,9 @@ regclass (f, nregs, dump) #ifdef FORBIDDEN_INC_DEC_CLASSES free (in_inc_dec); +#endif +#ifdef CLASS_CANNOT_CHANGE_SIZE + BITMAP_XFREE (reg_changes_size); #endif free (costs); } @@ -1241,13 +1284,12 @@ regclass (f, nregs, dump) alternatives. */ static void -record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size, +record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn, op_costs, reg_pref) int n_alts; int n_ops; rtx *ops; enum machine_mode *modes; - char *subreg_changes_size ATTRIBUTE_UNUSED; const char **constraints; rtx insn; struct costs *op_costs; @@ -1545,16 +1587,6 @@ record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size, constraints[i] = p; -#ifdef CLASS_CANNOT_CHANGE_SIZE - /* If we noted a subreg earlier, and the selected class is a - subclass of CLASS_CANNOT_CHANGE_SIZE, zap it. */ - if (subreg_changes_size[i] - && (reg_class_subunion[(int) CLASS_CANNOT_CHANGE_SIZE] - [(int) classes[i]] - == CLASS_CANNOT_CHANGE_SIZE)) - classes[i] = NO_REGS; -#endif - /* How we account for this operand now depends on whether it is a pseudo register or not. If it is, we first check if any register classes are valid. If not, we ignore this alternative, @@ -1566,13 +1598,13 @@ record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size, { if (classes[i] == NO_REGS) { - /* We must always fail if the operand is a REG, but - we did not find a suitable class. - - Otherwise we may perform an uninitialized read - from this_op_costs after the `continue' statement - below. */ - alt_fail = 1; + /* We must always fail if the operand is a REG, but + we did not find a suitable class. + + Otherwise we may perform an uninitialized read + from this_op_costs after the `continue' statement + below. */ + alt_fail = 1; } else {