From 1e204c7444fe8a80a1183349ccf75766c144d626 Mon Sep 17 00:00:00 2001 From: vmakarov Date: Mon, 27 Oct 2008 16:24:19 +0000 Subject: [PATCH] 2008-10-27 Vladimir Makarov PR middle-end/37813 * ira-conflicts.c (process_regs_for_copy): Remove class subset check. * ira-int.h (ira_hard_regno_cover_class): New. * ira-lives.c (mark_reg_live, mark_reg_dead, process_bb_node_lives): Use ira_hard_regno_cover_class. * ira.c (reg_class ira_hard_regno_cover_class): New global variable. (setup_hard_regno_cover_class): New function. (ira_init): Call setup_hard_regno_cover_class. * ira-costs.c (cost_class_nums): Add comment. (find_allocno_class_costs): Initiate cost_class_nums. (setup_allocno_cover_class_and_costs): Check cost_class_nums. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@141384 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 20 ++++++++++++++++++++ gcc/ira-conflicts.c | 2 -- gcc/ira-costs.c | 23 +++++++++++++++++------ gcc/ira-int.h | 5 +++++ gcc/ira-lives.c | 7 +++---- gcc/ira.c | 31 +++++++++++++++++++++++++++++++ 6 files changed, 76 insertions(+), 12 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6d67af1831f..666594f8b30 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,25 @@ 2008-10-27 Vladimir Makarov + PR middle-end/37813 + * ira-conflicts.c (process_regs_for_copy): Remove class subset + check. + + * ira-int.h (ira_hard_regno_cover_class): New. + + * ira-lives.c (mark_reg_live, mark_reg_dead, + process_bb_node_lives): Use ira_hard_regno_cover_class. + + * ira.c (reg_class ira_hard_regno_cover_class): New global + variable. + (setup_hard_regno_cover_class): New function. + (ira_init): Call setup_hard_regno_cover_class. + + * ira-costs.c (cost_class_nums): Add comment. + (find_allocno_class_costs): Initiate cost_class_nums. + (setup_allocno_cover_class_and_costs): Check cost_class_nums. + +2008-10-27 Vladimir Makarov + PR middle-end/37884 * ira-build.c (copy_live_ranges_to_removed_store_destinations): Rename to copy_info_to_removed_store_destinations. Propagate diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c index e467a7c60ee..9bdc3e7252d 100644 --- a/gcc/ira-conflicts.c +++ b/gcc/ira-conflicts.c @@ -374,8 +374,6 @@ process_regs_for_copy (rtx reg1, rtx reg2, rtx insn, int freq) rclass = REGNO_REG_CLASS (allocno_preferenced_hard_regno); mode = ALLOCNO_MODE (a); cover_class = ALLOCNO_COVER_CLASS (a); - if (! ira_class_subset_p[rclass][cover_class]) - return false; if (only_regs_p && insn != NULL_RTX && reg_class_size[rclass] <= (unsigned) CLASS_MAX_NREGS (rclass, mode)) /* It is already taken into account in ira-costs.c. */ diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c index 64b2e7995d6..82adf5dccb8 100644 --- a/gcc/ira-costs.c +++ b/gcc/ira-costs.c @@ -86,7 +86,7 @@ static enum reg_class *cost_classes; static int cost_classes_num; /* Map: cost class -> order number (they start with 0) of the cost - class. */ + class. The order number is negative for non-cost classes. */ static int cost_class_nums[N_REG_CLASSES]; /* It is the current size of struct costs. */ @@ -1112,6 +1112,8 @@ find_allocno_class_costs (void) /* 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. */ + for (i = 0; i < N_REG_CLASSES; i++) + cost_class_nums[i] = -1; for (cost_classes_num = 0; cost_classes_num < ira_important_classes_num; cost_classes_num++) @@ -1392,7 +1394,7 @@ process_bb_node_for_hard_reg_moves (ira_loop_tree_node_t loop_tree_node) static void setup_allocno_cover_class_and_costs (void) { - int i, j, n, regno; + int i, j, n, regno, num; int *reg_costs; enum reg_class cover_class, rclass; enum machine_mode mode; @@ -1411,9 +1413,10 @@ setup_allocno_cover_class_and_costs (void) if (cover_class == NO_REGS) continue; ALLOCNO_AVAILABLE_REGS_NUM (a) = ira_available_class_regs[cover_class]; + num = cost_class_nums[allocno_pref[i]]; + ira_assert (num >= 0); ALLOCNO_COVER_CLASS_COST (a) - = (COSTS_OF_ALLOCNO (allocno_costs, i) - ->cost[cost_class_nums[allocno_pref[i]]]); + = COSTS_OF_ALLOCNO (allocno_costs, i)->cost[num]; if (optimize && ALLOCNO_COVER_CLASS (a) != allocno_pref[i]) { n = ira_class_hard_regs_num[cover_class]; @@ -1423,8 +1426,16 @@ setup_allocno_cover_class_and_costs (void) { regno = ira_class_hard_regs[cover_class][j]; rclass = REGNO_REG_CLASS (regno); - reg_costs[j] = (COSTS_OF_ALLOCNO (allocno_costs, i) - ->cost[cost_class_nums[rclass]]); + num = cost_class_nums[rclass]; + if (num < 0) + { + /* The hard register class is not a cover class or a + class not fully inside in a cover class -- use + the allocno cover class. */ + ira_assert (ira_hard_regno_cover_class[regno] == cover_class); + num = cost_class_nums[cover_class]; + } + reg_costs[j] = COSTS_OF_ALLOCNO (allocno_costs, i)->cost[num]; } } } diff --git a/gcc/ira-int.h b/gcc/ira-int.h index fc18cdf9a0d..dafcfb7ec46 100644 --- a/gcc/ira-int.h +++ b/gcc/ira-int.h @@ -547,6 +547,11 @@ extern int ira_reg_cost, ira_mem_cost; extern int ira_load_cost, ira_store_cost, ira_shuffle_cost; extern int ira_move_loops_num, ira_additional_jumps_num; +/* Map: hard register number -> cover class it belongs to. If the + corresponding class is NO_REGS, the hard register is not available + for allocation. */ +extern enum reg_class ira_hard_regno_cover_class[FIRST_PSEUDO_REGISTER]; + /* Map: register class x machine mode -> number of hard registers of given class needed to store value of given mode. If the number for some hard-registers of the register class is different, the size diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c index f4b2d6de42b..c908ab71338 100644 --- a/gcc/ira-lives.c +++ b/gcc/ira-lives.c @@ -243,7 +243,7 @@ mark_reg_live (rtx reg) if (! TEST_HARD_REG_BIT (hard_regs_live, regno) && ! TEST_HARD_REG_BIT (eliminable_regset, regno)) { - cover_class = ira_class_translate[REGNO_REG_CLASS (regno)]; + cover_class = ira_hard_regno_cover_class[regno]; if (cover_class != NO_REGS) { curr_reg_pressure[cover_class]++; @@ -308,7 +308,7 @@ mark_reg_dead (rtx reg) { if (TEST_HARD_REG_BIT (hard_regs_live, regno)) { - cover_class = ira_class_translate[REGNO_REG_CLASS (regno)]; + cover_class = ira_hard_regno_cover_class[regno]; if (cover_class != NO_REGS) { curr_reg_pressure[cover_class]--; @@ -794,10 +794,9 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) { enum reg_class cover_class; - cover_class = REGNO_REG_CLASS (i); + cover_class = ira_hard_regno_cover_class[i]; if (cover_class == NO_REGS) continue; - cover_class = ira_class_translate[cover_class]; curr_reg_pressure[cover_class]++; if (curr_bb_node->reg_pressure[cover_class] < curr_reg_pressure[cover_class]) diff --git a/gcc/ira.c b/gcc/ira.c index 5fbd713ac75..30ef8c898c7 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -976,6 +976,36 @@ find_reg_class_closure (void) +/* Map: hard register number -> cover class it belongs to. If the + corresponding class is NO_REGS, the hard register is not available + for allocation. */ +enum reg_class ira_hard_regno_cover_class[FIRST_PSEUDO_REGISTER]; + +/* Set up the array above. */ +static void +setup_hard_regno_cover_class (void) +{ + int i, j; + enum reg_class cl; + + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + { + ira_hard_regno_cover_class[i] = NO_REGS; + for (j = 0; j < ira_reg_class_cover_size; j++) + { + cl = ira_reg_class_cover[j]; + if (ira_class_hard_reg_index[cl][i] >= 0) + { + ira_hard_regno_cover_class[i] = cl; + break; + } + } + + } +} + + + /* Map: register class x machine mode -> number of hard registers of given class needed to store value of given mode. If the number is different, the size will be negative. */ @@ -1118,6 +1148,7 @@ ira_init (void) setup_alloc_regs (flag_omit_frame_pointer != 0); setup_class_subset_and_memory_move_costs (); find_reg_class_closure (); + setup_hard_regno_cover_class (); setup_reg_class_nregs (); setup_prohibited_class_mode_regs (); ira_init_costs (); -- 2.11.4.GIT