Mercurial > hg > CbC > CbC_gcc
diff gcc/ira-costs.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | 58ad6c70ea60 |
children | b7f97abdc517 |
line wrap: on
line diff
--- a/gcc/ira-costs.c Sun Feb 07 18:28:00 2010 +0900 +++ b/gcc/ira-costs.c Fri Feb 12 23:39:51 2010 +0900 @@ -1,5 +1,5 @@ -/* IRA hard register and memory cost calculation for allocnos. - Copyright (C) 2006, 2007, 2008 +/* IRA hard register and memory cost calculation for allocnos or pseudos. + Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Vladimir Makarov <vmakarov@redhat.com>. @@ -38,18 +38,25 @@ #include "params.h" #include "ira-int.h" -/* The file contains code is similar to one in regclass but the code - works on the allocno basis. */ +/* The flags is set up every time when we calculate pseudo register + classes through function ira_set_pseudo_classes. */ +static bool pseudo_classes_defined_p = false; + +/* TRUE if we work with allocnos. Otherwise we work with pseudos. */ +static bool allocno_p; + +/* Number of elements in arrays `in_inc_dec' and `costs'. */ +static int cost_elements_num; #ifdef FORBIDDEN_INC_DEC_CLASSES -/* Indexed by n, is TRUE if allocno with number N is used in an - auto-inc or auto-dec context. */ +/* Indexed by n, is TRUE if allocno or pseudo with number N is used in + an auto-inc or auto-dec context. */ static bool *in_inc_dec; #endif /* The `costs' struct records the cost of using hard registers of each class considered for the calculation and of using memory for each - allocno. */ + allocno or pseudo. */ struct costs { int mem_cost; @@ -74,8 +81,11 @@ static struct costs *op_costs[MAX_RECOG_OPERANDS]; static struct costs *this_op_costs[MAX_RECOG_OPERANDS]; -/* Original and accumulated costs of each class for each allocno. */ -static struct costs *allocno_costs, *total_costs; +/* Costs of each class for each allocno or pseudo. */ +static struct costs *costs; + +/* Accumulated costs of each class for each allocno. */ +static struct costs *total_allocno_costs; /* Classes used for cost calculation. They may be different on different iterations of the cost calculations or in different @@ -92,21 +102,26 @@ /* It is the current size of struct costs. */ static int struct_costs_size; -/* Return pointer to structure containing costs of allocno with given - NUM in array ARR. */ -#define COSTS_OF_ALLOCNO(arr, num) \ +/* Return pointer to structure containing costs of allocno or pseudo + with given NUM in array ARR. */ +#define COSTS(arr, num) \ ((struct costs *) ((char *) (arr) + (num) * struct_costs_size)) -/* Record register class preferences of each allocno. Null value - means no preferences. It happens on the 1st iteration of the cost - calculation. */ -static enum reg_class *allocno_pref; +/* Return index in COSTS when processing reg with REGNO. */ +#define COST_INDEX(regno) (allocno_p \ + ? ALLOCNO_NUM (ira_curr_regno_allocno_map[regno]) \ + : (int) regno) -/* Allocated buffers for allocno_pref. */ -static enum reg_class *allocno_pref_buffer; +/* Record register class preferences of each allocno or pseudo. Null + value means no preferences. It happens on the 1st iteration of the + cost calculation. */ +static enum reg_class *pref; -/* Record register class of each allocno with the same regno. */ -static enum reg_class *common_classes; +/* Allocated buffers for pref. */ +static enum reg_class *pref_buffer; + +/* Record cover register class of each allocno with the same regno. */ +static enum reg_class *regno_cover_class; /* Execution frequency of the current insn. */ static int frequency; @@ -189,7 +204,7 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, enum machine_mode *modes, const char **constraints, rtx insn, struct costs **op_costs, - enum reg_class *allocno_pref) + enum reg_class *pref) { int alt; int i, j, k; @@ -205,7 +220,7 @@ { enum reg_class classes[MAX_RECOG_OPERANDS]; int allows_mem[MAX_RECOG_OPERANDS]; - int rclass; + enum reg_class rclass; int alt_fail = 0; int alt_cost = 0, op_cost_add; @@ -320,12 +335,9 @@ were not in the appropriate class. We could use cover class here but it is less accurate approximation. */ - if (allocno_pref) + if (pref) { - enum reg_class pref_class - = allocno_pref[ALLOCNO_NUM - (ira_curr_regno_allocno_map - [REGNO (op)])]; + enum reg_class pref_class = pref[COST_INDEX (REGNO (op))]; if (pref_class == NO_REGS) alt_cost @@ -355,7 +367,7 @@ continue; } } - + /* Scan all the constraint letters. See if the operand matches any of the constraints. Collect the valid register classes and see if this operand accepts @@ -429,7 +441,7 @@ break; case 's': - if (GET_CODE (op) == CONST_INT + if (CONST_INT_P (op) || (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)) break; @@ -441,7 +453,7 @@ break; case 'n': - if (GET_CODE (op) == CONST_INT + if (CONST_INT_P (op) || (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)) win = 1; @@ -455,7 +467,7 @@ case 'N': case 'O': case 'P': - if (GET_CODE (op) == CONST_INT + if (CONST_INT_P (op) && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, p)) win = 1; break; @@ -564,12 +576,9 @@ were not in the appropriate class. We could use cover class here but it is less accurate approximation. */ - if (allocno_pref) + if (pref) { - enum reg_class pref_class - = allocno_pref[ALLOCNO_NUM - (ira_curr_regno_allocno_map - [REGNO (op)])]; + enum reg_class pref_class = pref[COST_INDEX (REGNO (op))]; if (pref_class == NO_REGS) alt_cost @@ -637,17 +646,18 @@ } } - for (i = 0; i < n_ops; i++) - { - ira_allocno_t a; - rtx op = ops[i]; + if (allocno_p) + for (i = 0; i < n_ops; i++) + { + ira_allocno_t a; + rtx op = ops[i]; - if (! REG_P (op) || REGNO (op) < FIRST_PSEUDO_REGISTER) - continue; - a = ira_curr_regno_allocno_map [REGNO (op)]; - if (! ALLOCNO_BAD_SPILL_P (a) && insn_allows_mem[i] == 0) - ALLOCNO_BAD_SPILL_P (a) = true; - } + if (! REG_P (op) || REGNO (op) < FIRST_PSEUDO_REGISTER) + continue; + a = ira_curr_regno_allocno_map [REGNO (op)]; + if (! ALLOCNO_BAD_SPILL_P (a) && insn_allows_mem[i] == 0) + ALLOCNO_BAD_SPILL_P (a) = true; + } /* If this insn is a single set copying operand 1 to operand 0 and one operand is an allocno with the other a hard reg or an allocno @@ -672,7 +682,7 @@ { unsigned int regno = REGNO (ops[!i]); enum machine_mode mode = GET_MODE (ops[!i]); - int rclass; + enum reg_class rclass; unsigned int nr; if (regno < FIRST_PSEUDO_REGISTER) @@ -693,7 +703,7 @@ if (! TEST_HARD_REG_BIT (reg_class_contents[rclass], regno + nr)) break; - + if (nr == (unsigned) hard_regno_nregs[regno][mode]) op_costs[i]->cost[k] = -frequency; } @@ -877,8 +887,7 @@ #ifdef FORBIDDEN_INC_DEC_CLASSES if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER) - in_inc_dec[ALLOCNO_NUM (ira_curr_regno_allocno_map - [REGNO (XEXP (x, 0))])] = true; + in_inc_dec[COST_INDEX (REGNO (XEXP (x, 0)))] = true; #endif record_address_regs (mode, XEXP (x, 0), 0, code, SCRATCH, 2 * scale); break; @@ -886,15 +895,15 @@ case REG: { struct costs *pp; - int i, k; + enum reg_class i; + int k; if (REGNO (x) < FIRST_PSEUDO_REGISTER) break; - ALLOCNO_BAD_SPILL_P (ira_curr_regno_allocno_map[REGNO (x)]) = true; - pp = COSTS_OF_ALLOCNO (allocno_costs, - ALLOCNO_NUM (ira_curr_regno_allocno_map - [REGNO (x)])); + if (allocno_p) + ALLOCNO_BAD_SPILL_P (ira_curr_regno_allocno_map[REGNO (x)]) = true; + pp = COSTS (costs, COST_INDEX (REGNO (x))); pp->mem_cost += (ira_memory_move_cost[Pmode][rclass][1] * scale) / 2; for (k = 0; k < cost_classes_num; k++) { @@ -921,8 +930,7 @@ /* Calculate the costs of insn operands. */ static void -record_operand_costs (rtx insn, struct costs **op_costs, - enum reg_class *allocno_pref) +record_operand_costs (rtx insn, struct costs **op_costs, enum reg_class *pref) { const char *constraints[MAX_RECOG_OPERANDS]; enum machine_mode modes[MAX_RECOG_OPERANDS]; @@ -975,11 +983,11 @@ xconstraints[i+1] = constraints[i]; record_reg_classes (recog_data.n_alternatives, recog_data.n_operands, recog_data.operand, modes, - xconstraints, insn, op_costs, allocno_pref); + xconstraints, insn, op_costs, pref); } record_reg_classes (recog_data.n_alternatives, recog_data.n_operands, recog_data.operand, modes, - constraints, insn, op_costs, allocno_pref); + constraints, insn, op_costs, pref); } @@ -994,7 +1002,7 @@ rtx set, note; int i, k; - if (!INSN_P (insn)) + if (!NONDEBUG_INSN_P (insn)) return insn; pat_code = GET_CODE (PATTERN (insn)); @@ -1014,17 +1022,17 @@ { enum reg_class cl = GENERAL_REGS; rtx reg = SET_DEST (set); - int num = ALLOCNO_NUM (ira_curr_regno_allocno_map[REGNO (reg)]); + int num = COST_INDEX (REGNO (reg)); - if (allocno_pref) - cl = allocno_pref[num]; - COSTS_OF_ALLOCNO (allocno_costs, num)->mem_cost + if (pref) + cl = pref[num]; + COSTS (costs, num)->mem_cost -= ira_memory_move_cost[GET_MODE (reg)][cl][1] * frequency; record_address_regs (GET_MODE (SET_SRC (set)), XEXP (SET_SRC (set), 0), 0, MEM, SCRATCH, frequency * 2); } - record_operand_costs (insn, op_costs, allocno_pref); + record_operand_costs (insn, op_costs, pref); /* Now add the cost for each operand to the total costs for its allocno. */ @@ -1033,9 +1041,7 @@ && REGNO (recog_data.operand[i]) >= FIRST_PSEUDO_REGISTER) { int regno = REGNO (recog_data.operand[i]); - struct costs *p - = COSTS_OF_ALLOCNO (allocno_costs, - ALLOCNO_NUM (ira_curr_regno_allocno_map[regno])); + struct costs *p = COSTS (costs, COST_INDEX (regno)); struct costs *q = op_costs[i]; p->mem_cost += q->mem_cost; @@ -1050,12 +1056,13 @@ /* Print allocnos costs to file F. */ static void -print_costs (FILE *f) +print_allocno_costs (FILE *f) { int k; ira_allocno_t a; ira_allocno_iterator ai; + ira_assert (allocno_p); fprintf (f, "\n"); FOR_EACH_ALLOCNO (a, ai) { @@ -1084,57 +1091,114 @@ ) { fprintf (f, " %s:%d", reg_class_names[rclass], - COSTS_OF_ALLOCNO (allocno_costs, i)->cost[k]); + COSTS (costs, i)->cost[k]); if (flag_ira_region == IRA_REGION_ALL || flag_ira_region == IRA_REGION_MIXED) - fprintf (f, ",%d", COSTS_OF_ALLOCNO (total_costs, i)->cost[k]); + fprintf (f, ",%d", COSTS (total_allocno_costs, i)->cost[k]); } } - fprintf (f, " MEM:%i\n", COSTS_OF_ALLOCNO (allocno_costs, i)->mem_cost); + fprintf (f, " MEM:%i\n", COSTS (costs, i)->mem_cost); } } +/* Print pseudo costs to file F. */ +static void +print_pseudo_costs (FILE *f) +{ + int regno, k; + int rclass; + + ira_assert (! allocno_p); + fprintf (f, "\n"); + for (regno = max_reg_num () - 1; regno >= FIRST_PSEUDO_REGISTER; regno--) + { + if (regno_reg_rtx[regno] == NULL_RTX) + continue; + fprintf (f, " r%d costs:", regno); + for (k = 0; k < cost_classes_num; k++) + { + rclass = cost_classes[k]; + if (contains_reg_of_mode[rclass][PSEUDO_REGNO_MODE (regno)] +#ifdef FORBIDDEN_INC_DEC_CLASSES + && (! in_inc_dec[regno] || ! forbidden_inc_dec_class[rclass]) +#endif +#ifdef CANNOT_CHANGE_MODE_CLASS + && ! invalid_mode_change_p (regno, (enum reg_class) rclass, + PSEUDO_REGNO_MODE (regno)) +#endif + ) + fprintf (f, " %s:%d", reg_class_names[rclass], + COSTS (costs, regno)->cost[k]); + } + fprintf (f, " MEM:%i\n", COSTS (costs, regno)->mem_cost); + } +} + +/* Traverse the BB represented by LOOP_TREE_NODE to update the allocno + costs. */ +static void +process_bb_for_costs (basic_block bb) +{ + rtx insn; + + frequency = REG_FREQ_FROM_BB (bb); + if (frequency == 0) + frequency = 1; + FOR_BB_INSNS (bb, insn) + insn = scan_one_insn (insn); +} + /* Traverse the BB represented by LOOP_TREE_NODE to update the allocno costs. */ static void process_bb_node_for_costs (ira_loop_tree_node_t loop_tree_node) { basic_block bb; - rtx insn; bb = loop_tree_node->bb; - if (bb == NULL) - return; - frequency = REG_FREQ_FROM_BB (bb); - if (frequency == 0) - frequency = 1; - FOR_BB_INSNS (bb, insn) - insn = scan_one_insn (insn); + if (bb != NULL) + process_bb_for_costs (bb); } -/* Find costs of register classes and memory for allocnos and their - best costs. */ +/* Find costs of register classes and memory for allocnos or pseudos + and their best costs. Set up preferred, alternative and cover + classes for pseudos. */ static void -find_allocno_class_costs (void) +find_costs_and_classes (FILE *dump_file) { - int i, k; + int i, k, start; int pass; basic_block bb; init_recog (); #ifdef FORBIDDEN_INC_DEC_CLASSES - in_inc_dec = ira_allocate (sizeof (bool) * ira_allocnos_num); + in_inc_dec = ira_allocate (sizeof (bool) * cost_elements_num); #endif /* FORBIDDEN_INC_DEC_CLASSES */ - allocno_pref = NULL; + pref = NULL; + start = 0; + if (!resize_reg_info () && allocno_p && pseudo_classes_defined_p) + { + ira_allocno_t a; + ira_allocno_iterator ai; + + pref = pref_buffer; + FOR_EACH_ALLOCNO (a, ai) + pref[ALLOCNO_NUM (a)] = reg_preferred_class (ALLOCNO_REGNO (a)); + if (flag_expensive_optimizations) + start = 1; + } + if (allocno_p) + /* Clear the flag for the next compiled function. */ + pseudo_classes_defined_p = false; /* Normally we scan the insns once and determine the best class to use for each allocno. However, if -fexpensive-optimizations are on, we do so twice, the second time using the tentative best classes to guide the selection. */ - for (pass = 0; pass <= flag_expensive_optimizations; pass++) + for (pass = start; pass <= flag_expensive_optimizations; pass++) { - if (internal_flag_ira_verbose > 0 && ira_dump_file) - fprintf (ira_dump_file, "\nPass %i for finding allocno costs\n\n", - pass); + if ((!allocno_p || internal_flag_ira_verbose > 0) && dump_file) + fprintf (dump_file, + "\nPass %i for finding pseudo/allocno costs\n\n", pass); /* We could use only cover classes. Unfortunately it does not work well for some targets where some subclass of cover class is costly and wrong cover class is chosen. */ @@ -1153,20 +1217,31 @@ = sizeof (struct costs) + sizeof (int) * (cost_classes_num - 1); /* Zero out our accumulation of the cost of each class for each allocno. */ - memset (allocno_costs, 0, ira_allocnos_num * struct_costs_size); + memset (costs, 0, cost_elements_num * struct_costs_size); #ifdef FORBIDDEN_INC_DEC_CLASSES - memset (in_inc_dec, 0, ira_allocnos_num * sizeof (bool)); + memset (in_inc_dec, 0, cost_elements_num * sizeof (bool)); #endif - /* Scan the instructions and record each time it would save code - to put a certain allocno in a certain class. */ - ira_traverse_loop_tree (true, ira_loop_tree_root, - process_bb_node_for_costs, NULL); + if (allocno_p) + { + /* Scan the instructions and record each time it would save code + to put a certain allocno in a certain class. */ + ira_traverse_loop_tree (true, ira_loop_tree_root, + process_bb_node_for_costs, NULL); - memcpy (total_costs, allocno_costs, - max_struct_costs_size * ira_allocnos_num); + memcpy (total_allocno_costs, costs, + max_struct_costs_size * ira_allocnos_num); + } + else + { + basic_block bb; + + FOR_EACH_BB (bb) + process_bb_for_costs (bb); + } + if (pass == 0) - allocno_pref = allocno_pref_buffer; + pref = pref_buffer; /* Now for each allocno look at how desirable each class is and find which class is preferred. */ @@ -1181,41 +1256,52 @@ int inc_dec_p = false; #endif - if (ira_regno_allocno_map[i] == NULL) - continue; - memset (temp_costs, 0, struct_costs_size); - /* Find cost of all allocnos with the same regno. */ - for (a = ira_regno_allocno_map[i]; - a != NULL; - a = ALLOCNO_NEXT_REGNO_ALLOCNO (a)) + if (! allocno_p) { - a_num = ALLOCNO_NUM (a); - if ((flag_ira_region == IRA_REGION_ALL - || flag_ira_region == IRA_REGION_MIXED) - && (parent = ALLOCNO_LOOP_TREE_NODE (a)->parent) != NULL - && (parent_a = parent->regno_allocno_map[i]) != NULL - /* There are no caps yet. */ - && bitmap_bit_p (ALLOCNO_LOOP_TREE_NODE (a)->border_allocnos, - ALLOCNO_NUM (a))) + if (regno_reg_rtx[i] == NULL_RTX) + continue; +#ifdef FORBIDDEN_INC_DEC_CLASSES + inc_dec_p = in_inc_dec[i]; +#endif + memcpy (temp_costs, COSTS (costs, i), struct_costs_size); + } + else + { + if (ira_regno_allocno_map[i] == NULL) + continue; + memset (temp_costs, 0, struct_costs_size); + /* Find cost of all allocnos with the same regno. */ + for (a = ira_regno_allocno_map[i]; + a != NULL; + a = ALLOCNO_NEXT_REGNO_ALLOCNO (a)) { - /* Propagate costs to upper levels in the region - tree. */ - parent_a_num = ALLOCNO_NUM (parent_a); + a_num = ALLOCNO_NUM (a); + if ((flag_ira_region == IRA_REGION_ALL + || flag_ira_region == IRA_REGION_MIXED) + && (parent = ALLOCNO_LOOP_TREE_NODE (a)->parent) != NULL + && (parent_a = parent->regno_allocno_map[i]) != NULL + /* There are no caps yet. */ + && bitmap_bit_p (ALLOCNO_LOOP_TREE_NODE + (a)->border_allocnos, + ALLOCNO_NUM (a))) + { + /* Propagate costs to upper levels in the region + tree. */ + parent_a_num = ALLOCNO_NUM (parent_a); + for (k = 0; k < cost_classes_num; k++) + COSTS (total_allocno_costs, parent_a_num)->cost[k] + += COSTS (total_allocno_costs, a_num)->cost[k]; + COSTS (total_allocno_costs, parent_a_num)->mem_cost + += COSTS (total_allocno_costs, a_num)->mem_cost; + } for (k = 0; k < cost_classes_num; k++) - COSTS_OF_ALLOCNO (total_costs, parent_a_num)->cost[k] - += COSTS_OF_ALLOCNO (total_costs, a_num)->cost[k]; - COSTS_OF_ALLOCNO (total_costs, parent_a_num)->mem_cost - += COSTS_OF_ALLOCNO (total_costs, a_num)->mem_cost; + temp_costs->cost[k] += COSTS (costs, a_num)->cost[k]; + temp_costs->mem_cost += COSTS (costs, a_num)->mem_cost; +#ifdef FORBIDDEN_INC_DEC_CLASSES + if (in_inc_dec[a_num]) + inc_dec_p = true; +#endif } - for (k = 0; k < cost_classes_num; k++) - temp_costs->cost[k] - += COSTS_OF_ALLOCNO (allocno_costs, a_num)->cost[k]; - temp_costs->mem_cost - += COSTS_OF_ALLOCNO (allocno_costs, a_num)->mem_cost; -#ifdef FORBIDDEN_INC_DEC_CLASSES - if (in_inc_dec[a_num]) - inc_dec_p = true; -#endif } best_cost = (1 << (HOST_BITS_PER_INT - 2)) - 1; best = ALL_REGS; @@ -1251,38 +1337,45 @@ alt_class = reg_class_subunion[alt_class][rclass]; } alt_class = ira_class_translate[alt_class]; + if (best_cost > temp_costs->mem_cost) + regno_cover_class[i] = NO_REGS; + else if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY) + /* Make the common class the biggest class of best and + alt_class. */ + regno_cover_class[i] = alt_class == NO_REGS ? best : alt_class; + else + /* Make the common class a cover class. Remember all + allocnos with the same regno should have the same cover + class. */ + regno_cover_class[i] = ira_class_translate[best]; if (pass == flag_expensive_optimizations) { if (best_cost > temp_costs->mem_cost) best = alt_class = NO_REGS; else if (best == alt_class) alt_class = NO_REGS; - setup_reg_classes (i, best, alt_class); - if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) - fprintf (ira_dump_file, - " r%d: preferred %s, alternative %s\n", - i, reg_class_names[best], reg_class_names[alt_class]); + setup_reg_classes (i, best, alt_class, regno_cover_class[i]); + if ((!allocno_p || internal_flag_ira_verbose > 2) + && dump_file != NULL) + fprintf (dump_file, + " r%d: preferred %s, alternative %s, cover %s\n", + i, reg_class_names[best], reg_class_names[alt_class], + reg_class_names[regno_cover_class[i]]); } - if (best_cost > temp_costs->mem_cost) - common_classes[i] = NO_REGS; - else if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY) - /* Make the common class the biggest class of best and - alt_class. */ - common_classes[i] = alt_class == NO_REGS ? best : alt_class; - else - /* Make the common class a cover class. Remember all - allocnos with the same regno should have the same cover - class. */ - common_classes[i] = ira_class_translate[best]; + if (! allocno_p) + { + pref[i] = best_cost > temp_costs->mem_cost ? NO_REGS : best; + continue; + } for (a = ira_regno_allocno_map[i]; a != NULL; a = ALLOCNO_NEXT_REGNO_ALLOCNO (a)) { a_num = ALLOCNO_NUM (a); - if (common_classes[i] == NO_REGS) + if (regno_cover_class[i] == NO_REGS) best = NO_REGS; else - { + { /* Finding best class which is subset of the common class. */ best_cost = (1 << (HOST_BITS_PER_INT - 2)) - 1; @@ -1291,7 +1384,7 @@ for (k = 0; k < cost_classes_num; k++) { rclass = cost_classes[k]; - if (! ira_class_subset_p[rclass][common_classes[i]]) + if (! ira_class_subset_p[rclass][regno_cover_class[i]]) continue; /* Ignore classes that are too small for this operand or invalid for an operand that was @@ -1306,50 +1399,50 @@ #endif ) ; - else if (COSTS_OF_ALLOCNO (total_costs, a_num)->cost[k] + else if (COSTS (total_allocno_costs, a_num)->cost[k] < best_cost) { best_cost - = COSTS_OF_ALLOCNO (total_costs, a_num)->cost[k]; - allocno_cost - = COSTS_OF_ALLOCNO (allocno_costs, a_num)->cost[k]; + = COSTS (total_allocno_costs, a_num)->cost[k]; + allocno_cost = COSTS (costs, a_num)->cost[k]; best = (enum reg_class) rclass; } - else if (COSTS_OF_ALLOCNO (total_costs, a_num)->cost[k] + else if (COSTS (total_allocno_costs, a_num)->cost[k] == best_cost) { best = ira_reg_class_union[best][rclass]; allocno_cost - = MAX (allocno_cost, - COSTS_OF_ALLOCNO (allocno_costs, - a_num)->cost[k]); + = MAX (allocno_cost, COSTS (costs, a_num)->cost[k]); } } ALLOCNO_COVER_CLASS_COST (a) = allocno_cost; } ira_assert (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY - || ira_class_translate[best] == common_classes[i]); - if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL - && (pass == 0 || allocno_pref[a_num] != best)) + || ira_class_translate[best] == regno_cover_class[i]); + if (internal_flag_ira_verbose > 2 && dump_file != NULL + && (pass == 0 || pref[a_num] != best)) { - fprintf (ira_dump_file, " a%d (r%d,", a_num, i); + fprintf (dump_file, " a%d (r%d,", a_num, i); if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL) - fprintf (ira_dump_file, "b%d", bb->index); + fprintf (dump_file, "b%d", bb->index); else - fprintf (ira_dump_file, "l%d", + fprintf (dump_file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num); - fprintf (ira_dump_file, ") best %s, cover %s\n", + fprintf (dump_file, ") best %s, cover %s\n", reg_class_names[best], - reg_class_names[common_classes[i]]); + reg_class_names[regno_cover_class[i]]); } - allocno_pref[a_num] = best; + pref[a_num] = best; } } - - if (internal_flag_ira_verbose > 4 && ira_dump_file) + + if (internal_flag_ira_verbose > 4 && dump_file) { - print_costs (ira_dump_file); - fprintf (ira_dump_file,"\n"); + if (allocno_p) + print_allocno_costs (dump_file); + else + print_pseudo_costs (dump_file); + fprintf (dump_file,"\n"); } } #ifdef FORBIDDEN_INC_DEC_CLASSES @@ -1383,7 +1476,7 @@ freq = 1; FOR_BB_INSNS (bb, insn) { - if (! INSN_P (insn)) + if (!NONDEBUG_INSN_P (insn)) continue; set = single_set (insn); if (set == NULL_RTX) @@ -1441,24 +1534,21 @@ int i, j, n, regno, num; int *reg_costs; enum reg_class cover_class, rclass; - enum machine_mode mode; - HARD_REG_SET *pref; ira_allocno_t a; ira_allocno_iterator ai; + ira_assert (allocno_p); FOR_EACH_ALLOCNO (a, ai) { i = ALLOCNO_NUM (a); - mode = ALLOCNO_MODE (a); - cover_class = common_classes[ALLOCNO_REGNO (a)]; - ira_assert (allocno_pref[i] == NO_REGS || cover_class != NO_REGS); - ALLOCNO_MEMORY_COST (a) = COSTS_OF_ALLOCNO (allocno_costs, i)->mem_cost; + cover_class = regno_cover_class[ALLOCNO_REGNO (a)]; + ira_assert (pref[i] == NO_REGS || cover_class != NO_REGS); + ALLOCNO_MEMORY_COST (a) = COSTS (costs, i)->mem_cost; ira_set_allocno_cover_class (a, cover_class); if (cover_class == NO_REGS) continue; ALLOCNO_AVAILABLE_REGS_NUM (a) = ira_available_class_regs[cover_class]; - pref = ®_class_contents[allocno_pref[i]]; - if (optimize && ALLOCNO_COVER_CLASS (a) != allocno_pref[i]) + if (optimize && ALLOCNO_COVER_CLASS (a) != pref[i]) { n = ira_class_hard_regs_num[cover_class]; ALLOCNO_HARD_REG_COSTS (a) @@ -1466,7 +1556,7 @@ for (j = n - 1; j >= 0; j--) { regno = ira_class_hard_regs[cover_class][j]; - if (TEST_HARD_REG_BIT (*pref, regno)) + if (TEST_HARD_REG_BIT (reg_class_contents[pref[i]], regno)) reg_costs[j] = ALLOCNO_COVER_CLASS_COST (a); else { @@ -1481,7 +1571,7 @@ == cover_class); num = cost_class_nums[cover_class]; } - reg_costs[j] = COSTS_OF_ALLOCNO (allocno_costs, i)->cost[num]; + reg_costs[j] = COSTS (costs, i)->cost[num]; } } } @@ -1568,27 +1658,59 @@ +/* Common initialization function for ira_costs and + ira_set_pseudo_classes. */ +static void +init_costs (void) +{ + init_subregs_of_mode (); + costs = (struct costs *) ira_allocate (max_struct_costs_size + * cost_elements_num); + pref_buffer + = (enum reg_class *) ira_allocate (sizeof (enum reg_class) + * cost_elements_num); + regno_cover_class + = (enum reg_class *) ira_allocate (sizeof (enum reg_class) + * max_reg_num ()); +} + +/* Common finalization function for ira_costs and + ira_set_pseudo_classes. */ +static void +finish_costs (void) +{ + ira_free (regno_cover_class); + ira_free (pref_buffer); + ira_free (costs); +} + /* Entry function which defines cover class, memory and hard register costs for each allocno. */ void ira_costs (void) { - allocno_costs = (struct costs *) ira_allocate (max_struct_costs_size - * ira_allocnos_num); - total_costs = (struct costs *) ira_allocate (max_struct_costs_size - * ira_allocnos_num); - allocno_pref_buffer - = (enum reg_class *) ira_allocate (sizeof (enum reg_class) - * ira_allocnos_num); - common_classes - = (enum reg_class *) ira_allocate (sizeof (enum reg_class) - * max_reg_num ()); - find_allocno_class_costs (); + allocno_p = true; + cost_elements_num = ira_allocnos_num; + init_costs (); + total_allocno_costs = (struct costs *) ira_allocate (max_struct_costs_size + * ira_allocnos_num); + find_costs_and_classes (ira_dump_file); setup_allocno_cover_class_and_costs (); - ira_free (common_classes); - ira_free (allocno_pref_buffer); - ira_free (total_costs); - ira_free (allocno_costs); + finish_costs (); + ira_free (total_allocno_costs); +} + +/* Entry function which defines classes for pseudos. */ +void +ira_set_pseudo_classes (FILE *dump_file) +{ + allocno_p = false; + internal_flag_ira_verbose = flag_ira_verbose; + cost_elements_num = max_reg_num (); + init_costs (); + find_costs_and_classes (dump_file); + pseudo_classes_defined_p = true; + finish_costs (); }