diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-01-03 15:23:56 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-01-03 15:23:56 +0000 |
commit | 299a8d4e5f1b0cf43bcbb5cd63393b1c996fa417 (patch) | |
tree | c385eb88d5708aa09a583d60fe79cf0bb8e605d3 /gcc/regclass.c | |
parent | 60310566355dd0bfb78ee65e2164778480113449 (diff) | |
download | gcc-299a8d4e5f1b0cf43bcbb5cd63393b1c996fa417.tar.gz |
* regclass.c (op_costs): Remove global variable.
(record_reg_classes): New parameter "op_costs" and "reg_pref".
(record_operand_costs): Break out from ...
(scan_one_insn): ... here.
(dump_regclass): Make dumps nicer.
(regclass): Dump preferrences choosed and changes done during passes.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31179 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/regclass.c')
-rw-r--r-- | gcc/regclass.c | 189 |
1 files changed, 113 insertions, 76 deletions
diff --git a/gcc/regclass.c b/gcc/regclass.c index 4344c58701e..1da14a4c068 100644 --- a/gcc/regclass.c +++ b/gcc/regclass.c @@ -1,5 +1,5 @@ /* Compute register class preferences for pseudo-registers. - Copyright (C) 1987, 88, 91-98, 1999 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 91-98, 1999, 2000 Free Software Foundation, Inc. This file is part of GNU CC. @@ -703,12 +703,6 @@ static struct costs *costs; static struct costs init_cost; -/* Record the same data by operand number, accumulated for each alternative - in an insn. The contribution to a pseudo is that of the minimum-cost - alternative. */ - -static struct costs op_costs[MAX_RECOG_OPERANDS]; - /* Record preferrences of each pseudo. This is available after `regclass' is run. */ @@ -724,9 +718,11 @@ static struct reg_pref *reg_pref_buffer; static int loop_cost; static rtx scan_one_insn PROTO((rtx, int)); +static void record_operand_costs PROTO((rtx, struct costs *, struct reg_pref *)); static void dump_regclass PROTO((FILE *)); static void record_reg_classes PROTO((int, int, rtx *, enum machine_mode *, - char *, const char **, rtx)); + char *, const char **, rtx, + struct costs *, struct reg_pref *)); static int copy_cost PROTO((rtx, enum machine_mode, enum reg_class, int)); static void record_address_regs PROTO((rtx, enum reg_class, int)); @@ -789,15 +785,89 @@ dump_regclass (dump) enum reg_class class; if (REG_N_REFS (i)) { - fprintf (dump, ";; Register %i costs:", i); + fprintf (dump, " Register %i costs:", i); for (class = 0; class < N_REG_CLASSES; class++) fprintf (dump, " %s:%i", reg_class_names[(int) class], costs[i].cost[class]); - fprintf (dump, " MEM:%i\n\n", costs[i].mem_cost); + fprintf (dump, " MEM:%i\n", costs[i].mem_cost); } } } + + +/* Calculate the costs of insn operands. */ + +static void +record_operand_costs (insn, op_costs, reg_pref) + rtx insn; + struct costs *op_costs; + struct reg_pref *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++) + { + 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. + Then handle any address registers. Finally record the desired + classes for any pseudos, doing it twice if some pair of + operands are commutative. */ + + for (i = 0; i < recog_data.n_operands; i++) + { + op_costs[i] = init_cost; + + 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; + recog_data.operand[i] = inner; + } + + if (GET_CODE (recog_data.operand[i]) == MEM) + record_address_regs (XEXP (recog_data.operand[i], 0), + BASE_REG_CLASS, loop_cost * 2); + else if (constraints[i][0] == 'p') + record_address_regs (recog_data.operand[i], + BASE_REG_CLASS, loop_cost * 2); + } + + /* Check for commutative in a separate loop so everything will + have been initialized. We must do this even if one operand + is a constant--see addsi3 in m68k.md. */ + + for (i = 0; i < (int) recog_data.n_operands - 1; i++) + if (constraints[i][0] == '%') + { + const char *xconstraints[MAX_RECOG_OPERANDS]; + int j; + + /* Handle commutative operands by swapping the constraints. + We assume the modes are the same. */ + + for (j = 0; j < recog_data.n_operands; j++) + xconstraints[j] = constraints[j]; + + 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, + xconstraints, insn, op_costs, reg_pref); + } + + record_reg_classes (recog_data.n_alternatives, recog_data.n_operands, + recog_data.operand, modes, subreg_changes_size, + constraints, insn, op_costs, reg_pref); +} /* Subroutine of regclass, processes one insn INSN. Scan it and record each time it would save code to put a certain register in a certain class. @@ -813,11 +883,9 @@ scan_one_insn (insn, pass) { enum rtx_code code = GET_CODE (insn); enum rtx_code pat_code; - const char *constraints[MAX_RECOG_OPERANDS]; - enum machine_mode modes[MAX_RECOG_OPERANDS]; - char subreg_changes_size[MAX_RECOG_OPERANDS]; rtx set, note; int i, j; + struct costs op_costs[MAX_RECOG_OPERANDS]; if (GET_RTX_CLASS (code) != 'i') return insn; @@ -833,13 +901,6 @@ scan_one_insn (insn, pass) set = single_set (insn); extract_insn (insn); - for (i = 0; i < recog_data.n_operands; i++) - { - constraints[i] = recog_data.constraints[i]; - modes[i] = recog_data.operand_mode[i]; - } - memset (subreg_changes_size, 0, sizeof (subreg_changes_size)); - /* If this insn loads a parameter from its stack slot, then it represents a savings, rather than a cost, if the parameter is stored in memory. Record this fact. */ @@ -913,58 +974,7 @@ scan_one_insn (insn, pass) return PREV_INSN (newinsn); } - /* If we get here, we are set up to record the costs of all the - operands for this insn. Start by initializing the costs. - Then handle any address registers. Finally record the desired - classes for any pseudos, doing it twice if some pair of - operands are commutative. */ - - for (i = 0; i < recog_data.n_operands; i++) - { - op_costs[i] = init_cost; - - 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; - recog_data.operand[i] = inner; - } - - if (GET_CODE (recog_data.operand[i]) == MEM) - record_address_regs (XEXP (recog_data.operand[i], 0), - BASE_REG_CLASS, loop_cost * 2); - else if (constraints[i][0] == 'p') - record_address_regs (recog_data.operand[i], - BASE_REG_CLASS, loop_cost * 2); - } - - /* Check for commutative in a separate loop so everything will - have been initialized. We must do this even if one operand - is a constant--see addsi3 in m68k.md. */ - - for (i = 0; i < (int) recog_data.n_operands - 1; i++) - if (constraints[i][0] == '%') - { - const char *xconstraints[MAX_RECOG_OPERANDS]; - int j; - - /* Handle commutative operands by swapping the constraints. - We assume the modes are the same. */ - - for (j = 0; j < recog_data.n_operands; j++) - xconstraints[j] = constraints[j]; - - 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, - xconstraints, insn); - } - - record_reg_classes (recog_data.n_alternatives, recog_data.n_operands, - recog_data.operand, modes, subreg_changes_size, - constraints, insn); + record_operand_costs(insn, op_costs, reg_pref); /* Now add the cost for each operand to the total costs for its register. */ @@ -1064,6 +1074,9 @@ regclass (f, nregs, dump) for (pass = 0; pass <= flag_expensive_optimizations; pass++) { int index; + + if (dump) + fprintf (dump, "\n\nPass %i\n\n",pass); /* Zero out our accumulation of the cost of each class for each reg. */ bzero ((char *) costs, nregs * sizeof (struct costs)); @@ -1110,6 +1123,11 @@ regclass (f, nregs, dump) if (pass == 0) reg_pref = reg_pref_buffer; + if (dump) + { + dump_regclass (dump); + fprintf(dump,"\n"); + } for (i = FIRST_PSEUDO_REGISTER; i < nregs; i++) { register int best_cost = (1 << (HOST_BITS_PER_INT - 2)) - 1; @@ -1119,6 +1137,9 @@ regclass (f, nregs, dump) register int class; register struct costs *p = &costs[i]; + if (!REG_N_REFS (i)) + continue; + for (class = (int) ALL_REGS - 1; class > 0; class--) { /* Ignore classes that are too small for this operand or @@ -1146,7 +1167,7 @@ regclass (f, nregs, dump) should be provided as a register class. Don't do this if we will be doing it again later. */ - if (pass == 1 || ! flag_expensive_optimizations) + if ((pass == 1 || dump) || ! flag_expensive_optimizations) for (class = 0; class < N_REG_CLASSES; class++) if (p->cost[class] < p->mem_cost && (reg_class_size[(int) reg_class_subunion[(int) alt][class]] @@ -1161,14 +1182,28 @@ regclass (f, nregs, dump) if (alt == best) alt = NO_REGS; + if (dump + && (reg_pref[i].prefclass != (int) best + || reg_pref[i].altclass != (int) alt)) + { + static const char *const reg_class_names[] = REG_CLASS_NAMES; + fprintf(dump, " Register %i", i); + if (alt == ALL_REGS || best == ALL_REGS) + fprintf (dump, " pref %s\n", reg_class_names[(int) best]); + else if (alt == NO_REGS) + fprintf (dump, " pref %s or none\n", reg_class_names[(int) best]); + else + fprintf (dump, " pref %s, else %s\n", + reg_class_names[(int) best], + reg_class_names[(int) alt]); + } + /* We cast to (int) because (char) hits bugs in some compilers. */ reg_pref[i].prefclass = (int) best; reg_pref[i].altclass = (int) alt; } } - if (dump) - dump_regclass (dump); #ifdef FORBIDDEN_INC_DEC_CLASSES free (in_inc_dec); #endif @@ -1201,7 +1236,7 @@ regclass (f, nregs, dump) static void record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size, - constraints, insn) + constraints, insn, op_costs, reg_pref) int n_alts; int n_ops; rtx *ops; @@ -1209,6 +1244,8 @@ record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size, char *subreg_changes_size ATTRIBUTE_UNUSED; const char **constraints; rtx insn; + struct costs *op_costs; + struct reg_pref *reg_pref; { int alt; int i, j; |