From 69f8e08094a3f6e518c08f323bc2687ffe696c9e Mon Sep 17 00:00:00 2001 From: vmakarov Date: Wed, 19 Nov 2008 21:20:44 +0000 Subject: [PATCH] 2008-11-15 Vladimir Makarov PR bootstrap/37790 * ira-int.h (ira_copy_allocno_live_range_list, ira_merge_allocno_live_ranges, ira_allocno_live_ranges_intersect_p, ira_finish_allocno_live_range_list): New prototypes. (ira_allocno_live_ranges_intersect_p, ira_pseudo_live_ranges_intersect_p): Remove. * ira-conflicts.c (ira_allocno_live_ranges_intersect_p, ira_pseudo_live_ranges_intersect_p): Rename to allocnos_have_intersected_live_ranges_p and pseudos_have_intersected_live_ranges_p. Move them from here to ... * ira-color.c: ... here (coalesced_allocno_conflict_p): Use allocnos_have_intersected_live_ranges_p. (coalesced_allocnos_living_at_program_points, coalesced_allocnos_live_at_points_p, set_coalesced_allocnos_live_points): Remove. (slot_coalesced_allocnos_live_ranges, slot_coalesced_allocno_live_ranges_intersect_p, setup_slot_coalesced_allocno_live_ranges): New. (coalesce_spill_slots): Use ranges of coalesced allocnos. (ira_sort_regnos_for_alter_reg): Use allocnos_have_intersected_live_ranges_p. (ira_reuse_stack_slot): Use pseudos_have_intersected_live_ranges_p. * global.c (pseudo_for_reload_consideration_p): Check flag_ira_share_spill_slots too. * ira-build.c (copy_allocno_live_range_list): Rename to ira_copy_allocno_live_range_list. Make it external. (merge_ranges): Rename to ira_merge_allocno_live_ranges. Make it external. (ira_allocno_live_ranges_intersect_p): New. (ira_finish_allocno_live_range_list): New. (finish_allocno): Use it. (remove_unnecessary_allocnos): Use ira_merge_allocno_live_ranges. (copy_info_to_removed_store_destinations): Ditto. Use ira_copy_allocno_live_range_list. (ira_flattening): Use ira_merge_allocno_live_ranges. * ira.c (too_high_register_pressure_p): New function. (ira): Switch off sharing spill slots if the pressure is too high. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142017 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 49 ++++++++++++ gcc/global.c | 3 +- gcc/ira-build.c | 210 +++++++++++++++++++++++++++++----------------------- gcc/ira-color.c | 124 +++++++++++++++++++++---------- gcc/ira-conflicts.c | 46 ------------ gcc/ira-int.h | 9 ++- gcc/ira.c | 27 +++++++ 7 files changed, 289 insertions(+), 179 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6b972ee..eacb5e0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,52 @@ +2008-11-15 Vladimir Makarov + + PR bootstrap/37790 + * ira-int.h (ira_copy_allocno_live_range_list, + ira_merge_allocno_live_ranges, + ira_allocno_live_ranges_intersect_p, + ira_finish_allocno_live_range_list): New prototypes. + (ira_allocno_live_ranges_intersect_p, + ira_pseudo_live_ranges_intersect_p): Remove. + + * ira-conflicts.c (ira_allocno_live_ranges_intersect_p, + ira_pseudo_live_ranges_intersect_p): Rename to + allocnos_have_intersected_live_ranges_p and + pseudos_have_intersected_live_ranges_p. Move them from here to + ... + + * ira-color.c: ... here + (coalesced_allocno_conflict_p): Use + allocnos_have_intersected_live_ranges_p. + (coalesced_allocnos_living_at_program_points, + coalesced_allocnos_live_at_points_p, + set_coalesced_allocnos_live_points): Remove. + (slot_coalesced_allocnos_live_ranges, + slot_coalesced_allocno_live_ranges_intersect_p, + setup_slot_coalesced_allocno_live_ranges): New. + (coalesce_spill_slots): Use ranges of coalesced allocnos. + (ira_sort_regnos_for_alter_reg): Use + allocnos_have_intersected_live_ranges_p. + (ira_reuse_stack_slot): Use + pseudos_have_intersected_live_ranges_p. + + * global.c (pseudo_for_reload_consideration_p): Check + flag_ira_share_spill_slots too. + + * ira-build.c (copy_allocno_live_range_list): Rename to + ira_copy_allocno_live_range_list. Make it external. + (merge_ranges): Rename to ira_merge_allocno_live_ranges. Make it + external. + (ira_allocno_live_ranges_intersect_p): New. + (ira_finish_allocno_live_range_list): New. + (finish_allocno): Use it. + (remove_unnecessary_allocnos): Use ira_merge_allocno_live_ranges. + (copy_info_to_removed_store_destinations): Ditto. Use + ira_copy_allocno_live_range_list. + (ira_flattening): Use ira_merge_allocno_live_ranges. + + * ira.c (too_high_register_pressure_p): New function. + (ira): Switch off sharing spill slots if the pressure is too high. + 2008-11-19 Richard Guenther * tree.c (build2_stat): Allow non-POINTER_PLUS_EXPRs with diff --git a/gcc/global.c b/gcc/global.c index edc2a42..824fcf0 100644 --- a/gcc/global.c +++ b/gcc/global.c @@ -1393,7 +1393,8 @@ pseudo_for_reload_consideration_p (int regno) { /* Consider spilled pseudos too for IRA because they still have a chance to get hard-registers in the reload when IRA is used. */ - return reg_renumber[regno] >= 0 || (flag_ira && optimize); + return (reg_renumber[regno] >= 0 + || (flag_ira && optimize && flag_ira_share_spill_slots)); } /* Walk the insns of the current function and build reload_insn_chain, diff --git a/gcc/ira-build.c b/gcc/ira-build.c index 110da63..af1d174 100644 --- a/gcc/ira-build.c +++ b/gcc/ira-build.c @@ -826,8 +826,8 @@ copy_allocno_live_range (allocno_live_range_t r) /* Copy allocno live range list given by its head R and return the result. */ -static allocno_live_range_t -copy_allocno_live_range_list (allocno_live_range_t r) +allocno_live_range_t +ira_copy_allocno_live_range_list (allocno_live_range_t r) { allocno_live_range_t p, first, last; @@ -845,6 +845,103 @@ copy_allocno_live_range_list (allocno_live_range_t r) return first; } +/* Merge ranges R1 and R2 and returns the result. The function + maintains the order of ranges and tries to minimize number of the + result ranges. */ +allocno_live_range_t +ira_merge_allocno_live_ranges (allocno_live_range_t r1, + allocno_live_range_t r2) +{ + allocno_live_range_t first, last, temp; + + if (r1 == NULL) + return r2; + if (r2 == NULL) + return r1; + for (first = last = NULL; r1 != NULL && r2 != NULL;) + { + if (r1->start < r2->start) + { + temp = r1; + r1 = r2; + r2 = temp; + } + if (r1->start <= r2->finish + 1) + { + /* Intersected ranges: merge r1 and r2 into r1. */ + r1->start = r2->start; + if (r1->finish < r2->finish) + r1->finish = r2->finish; + temp = r2; + r2 = r2->next; + ira_finish_allocno_live_range (temp); + if (r2 == NULL) + { + /* To try to merge with subsequent ranges in r1. */ + r2 = r1->next; + r1->next = NULL; + } + } + else + { + /* Add r1 to the result. */ + if (first == NULL) + first = last = r1; + else + { + last->next = r1; + last = r1; + } + r1 = r1->next; + if (r1 == NULL) + { + /* To try to merge with subsequent ranges in r2. */ + r1 = r2->next; + r2->next = NULL; + } + } + } + if (r1 != NULL) + { + if (first == NULL) + first = r1; + else + last->next = r1; + ira_assert (r1->next == NULL); + } + else if (r2 != NULL) + { + if (first == NULL) + first = r2; + else + last->next = r2; + ira_assert (r2->next == NULL); + } + else + { + ira_assert (last->next == NULL); + } + return first; +} + +/* Return TRUE if live ranges R1 and R2 intersect. */ +bool +ira_allocno_live_ranges_intersect_p (allocno_live_range_t r1, + allocno_live_range_t r2) +{ + /* Remember the live ranges are always kept ordered. */ + while (r1 != NULL && r2 != NULL) + { + if (r1->start > r2->finish) + r1 = r1->next; + else if (r2->start > r1->finish) + r2 = r2->next; + else + return true; + } + return false; +} + /* Free allocno live range R. */ void ira_finish_allocno_live_range (allocno_live_range_t r) @@ -852,6 +949,19 @@ ira_finish_allocno_live_range (allocno_live_range_t r) pool_free (allocno_live_range_pool, r); } +/* Free list of allocno live ranges starting with R. */ +void +ira_finish_allocno_live_range_list (allocno_live_range_t r) +{ + allocno_live_range_t next_r; + + for (; r != NULL; r = next_r) + { + next_r = r->next; + ira_finish_allocno_live_range (r); + } +} + /* Free updated register costs of allocno A. */ void ira_free_allocno_updated_costs (ira_allocno_t a) @@ -872,7 +982,6 @@ ira_free_allocno_updated_costs (ira_allocno_t a) static void finish_allocno (ira_allocno_t a) { - allocno_live_range_t r, next_r; enum reg_class cover_class = ALLOCNO_COVER_CLASS (a); ira_allocnos[ALLOCNO_NUM (a)] = NULL; @@ -888,11 +997,7 @@ finish_allocno (ira_allocno_t a) if (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) != NULL) ira_free_cost_vector (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a), cover_class); - for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = next_r) - { - next_r = r->next; - ira_finish_allocno_live_range (r); - } + ira_finish_allocno_live_range_list (ALLOCNO_LIVE_RANGES (a)); pool_free (allocno_pool, a); } @@ -1543,84 +1648,6 @@ create_allocnos (void) will hardly improve the result. As a result we speed up regional register allocation. */ -/* Merge ranges R1 and R2 and returns the result. The function - maintains the order of ranges and tries to minimize number of the - result ranges. */ -static allocno_live_range_t -merge_ranges (allocno_live_range_t r1, allocno_live_range_t r2) -{ - allocno_live_range_t first, last, temp; - - if (r1 == NULL) - return r2; - if (r2 == NULL) - return r1; - for (first = last = NULL; r1 != NULL && r2 != NULL;) - { - if (r1->start < r2->start) - { - temp = r1; - r1 = r2; - r2 = temp; - } - if (r1->start <= r2->finish + 1) - { - /* Intersected ranges: merge r1 and r2 into r1. */ - r1->start = r2->start; - if (r1->finish < r2->finish) - r1->finish = r2->finish; - temp = r2; - r2 = r2->next; - ira_finish_allocno_live_range (temp); - if (r2 == NULL) - { - /* To try to merge with subsequent ranges in r1. */ - r2 = r1->next; - r1->next = NULL; - } - } - else - { - /* Add r1 to the result. */ - if (first == NULL) - first = last = r1; - else - { - last->next = r1; - last = r1; - } - r1 = r1->next; - if (r1 == NULL) - { - /* To try to merge with subsequent ranges in r2. */ - r1 = r2->next; - r2->next = NULL; - } - } - } - if (r1 != NULL) - { - if (first == NULL) - first = r1; - else - last->next = r1; - ira_assert (r1->next == NULL); - } - else if (r2 != NULL) - { - if (first == NULL) - first = r2; - else - last->next = r2; - ira_assert (r2->next == NULL); - } - else - { - ira_assert (last->next == NULL); - } - return first; -} - /* The function changes allocno in range list given by R onto A. */ static void change_allocno_in_range_list (allocno_live_range_t r, ira_allocno_t a) @@ -1762,7 +1789,8 @@ remove_unnecessary_allocnos (void) r = ALLOCNO_LIVE_RANGES (a); change_allocno_in_range_list (r, parent_a); ALLOCNO_LIVE_RANGES (parent_a) - = merge_ranges (r, ALLOCNO_LIVE_RANGES (parent_a)); + = ira_merge_allocno_live_ranges + (r, ALLOCNO_LIVE_RANGES (parent_a)); merged_p = true; ALLOCNO_LIVE_RANGES (a) = NULL; IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (parent_a), @@ -2155,10 +2183,10 @@ copy_info_to_removed_store_destinations (int regno) ira_print_live_range_list (ira_dump_file, ALLOCNO_LIVE_RANGES (a)); } - r = copy_allocno_live_range_list (ALLOCNO_LIVE_RANGES (a)); + r = ira_copy_allocno_live_range_list (ALLOCNO_LIVE_RANGES (a)); change_allocno_in_range_list (r, parent_a); ALLOCNO_LIVE_RANGES (parent_a) - = merge_ranges (r, ALLOCNO_LIVE_RANGES (parent_a)); + = ira_merge_allocno_live_ranges (r, ALLOCNO_LIVE_RANGES (parent_a)); IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (parent_a), ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a)); #ifdef STACK_REGS @@ -2255,8 +2283,8 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit) } change_allocno_in_range_list (ALLOCNO_LIVE_RANGES (a), parent_a); ALLOCNO_LIVE_RANGES (parent_a) - = merge_ranges (ALLOCNO_LIVE_RANGES (a), - ALLOCNO_LIVE_RANGES (parent_a)); + = ira_merge_allocno_live_ranges + (ALLOCNO_LIVE_RANGES (a), ALLOCNO_LIVE_RANGES (parent_a)); merged_p = true; ALLOCNO_LIVE_RANGES (a) = NULL; ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a) diff --git a/gcc/ira-color.c b/gcc/ira-color.c index eea3b2c..7343e0c 100644 --- a/gcc/ira-color.c +++ b/gcc/ira-color.c @@ -84,6 +84,49 @@ static VEC(ira_allocno_t,heap) *removed_splay_allocno_vec; +/* This page contains functions used to find conflicts using allocno + live ranges. */ + +/* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is + used to find a conflict for new allocnos or allocnos with the + different cover classes. */ +static bool +allocnos_have_intersected_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2) +{ + if (a1 == a2) + return false; + if (ALLOCNO_REG (a1) != NULL && ALLOCNO_REG (a2) != NULL + && (ORIGINAL_REGNO (ALLOCNO_REG (a1)) + == ORIGINAL_REGNO (ALLOCNO_REG (a2)))) + return false; + return ira_allocno_live_ranges_intersect_p (ALLOCNO_LIVE_RANGES (a1), + ALLOCNO_LIVE_RANGES (a2)); +} + +#ifdef ENABLE_IRA_CHECKING + +/* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2 + intersect. This should be used when there is only one region. + Currently this is used during reload. */ +static bool +pseudos_have_intersected_live_ranges_p (int regno1, int regno2) +{ + ira_allocno_t a1, a2; + + ira_assert (regno1 >= FIRST_PSEUDO_REGISTER + && regno2 >= FIRST_PSEUDO_REGISTER); + /* Reg info caclulated by dataflow infrastructure can be different + from one calculated by regclass. */ + if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL + || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL) + return false; + return allocnos_have_intersected_live_ranges_p (a1, a2); +} + +#endif + + + /* This page contains functions used to choose hard registers for allocnos. */ @@ -1489,7 +1532,8 @@ coalesced_allocno_conflict_p (ira_allocno_t a1, ira_allocno_t a2, conflict_allocno = ALLOCNO_NEXT_COALESCED_ALLOCNO (conflict_allocno)) { - if (ira_allocno_live_ranges_intersect_p (a, conflict_allocno)) + if (allocnos_have_intersected_live_ranges_p (a, + conflict_allocno)) return true; if (conflict_allocno == a1) break; @@ -2319,38 +2363,37 @@ collect_spilled_coalesced_allocnos (int *pseudo_regnos, int n, return num; } -/* Array of bitmaps of size IRA_MAX_POINT. Bitmap for given point - contains numbers of coalesced allocnos living at this point. */ -static regset_head *coalesced_allocnos_living_at_program_points; +/* Array of live ranges of size IRA_ALLOCNOS_NUM. Live range for + given slot contains live ranges of coalesced allocnos assigned to + given slot. */ +static allocno_live_range_t *slot_coalesced_allocnos_live_ranges; -/* Return TRUE if coalesced allocnos represented by ALLOCNO live at - program points of coalesced allocnos with number N. */ +/* Return TRUE if coalesced allocnos represented by ALLOCNO has live + ranges intersected with live ranges of coalesced allocnos assigned + to slot with number N. */ static bool -coalesced_allocnos_live_at_points_p (ira_allocno_t allocno, int n) +slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno, int n) { - int i; ira_allocno_t a; - allocno_live_range_t r; for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);; a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a)) { - for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = r->next) - for (i = r->start; i <= r->finish; i++) - if (bitmap_bit_p (&coalesced_allocnos_living_at_program_points[i], n)) - return true; + if (ira_allocno_live_ranges_intersect_p + (slot_coalesced_allocnos_live_ranges[n], ALLOCNO_LIVE_RANGES (a))) + return true; if (a == allocno) break; } return false; } -/* Mark program points where coalesced allocnos represented by ALLOCNO - live. */ +/* Update live ranges of slot to which coalesced allocnos represented + by ALLOCNO were assigned. */ static void -set_coalesced_allocnos_live_points (ira_allocno_t allocno) +setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno) { - int i, n; + int n; ira_allocno_t a; allocno_live_range_t r; @@ -2358,9 +2401,10 @@ set_coalesced_allocnos_live_points (ira_allocno_t allocno) for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);; a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a)) { - for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = r->next) - for (i = r->start; i <= r->finish; i++) - bitmap_set_bit (&coalesced_allocnos_living_at_program_points[i], n); + r = ira_copy_allocno_live_range_list (ALLOCNO_LIVE_RANGES (a)); + slot_coalesced_allocnos_live_ranges[n] + = ira_merge_allocno_live_ranges + (slot_coalesced_allocnos_live_ranges[n], r); if (a == allocno) break; } @@ -2374,14 +2418,15 @@ set_coalesced_allocnos_live_points (ira_allocno_t allocno) static bool coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num) { - int i, j, last_coalesced_allocno_num; + int i, j, n, last_coalesced_allocno_num; ira_allocno_t allocno, a; bool merged_p = false; - coalesced_allocnos_living_at_program_points - = (regset_head *) ira_allocate (sizeof (regset_head) * ira_max_point); - for (i = 0; i < ira_max_point; i++) - INIT_REG_SET (&coalesced_allocnos_living_at_program_points[i]); + slot_coalesced_allocnos_live_ranges + = (allocno_live_range_t *) ira_allocate (sizeof (allocno_live_range_t) + * ira_allocnos_num); + memset (slot_coalesced_allocnos_live_ranges, 0, + sizeof (allocno_live_range_t) * ira_allocnos_num); last_coalesced_allocno_num = 0; /* Coalesce non-conflicting spilled allocnos preferring most frequently used. */ @@ -2390,18 +2435,18 @@ coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num) allocno = spilled_coalesced_allocnos[i]; if (ALLOCNO_FIRST_COALESCED_ALLOCNO (allocno) != allocno || (ALLOCNO_REGNO (allocno) < ira_reg_equiv_len - && (ira_reg_equiv_invariant_p[ALLOCNO_REGNO (allocno)] - || ira_reg_equiv_const[ALLOCNO_REGNO (allocno)] != NULL_RTX))) + && (ira_reg_equiv_const[ALLOCNO_REGNO (allocno)] != NULL_RTX + || ira_reg_equiv_invariant_p[ALLOCNO_REGNO (allocno)]))) continue; for (j = 0; j < i; j++) { a = spilled_coalesced_allocnos[j]; + n = ALLOCNO_TEMP (a); if (ALLOCNO_FIRST_COALESCED_ALLOCNO (a) == a && (ALLOCNO_REGNO (a) >= ira_reg_equiv_len || (! ira_reg_equiv_invariant_p[ALLOCNO_REGNO (a)] && ira_reg_equiv_const[ALLOCNO_REGNO (a)] == NULL_RTX)) - && ! coalesced_allocnos_live_at_points_p (allocno, - ALLOCNO_TEMP (a))) + && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno, n)) break; } if (j >= i) @@ -2409,7 +2454,7 @@ coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num) /* No coalescing: set up number for coalesced allocnos represented by ALLOCNO. */ ALLOCNO_TEMP (allocno) = last_coalesced_allocno_num++; - set_coalesced_allocnos_live_points (allocno); + setup_slot_coalesced_allocno_live_ranges (allocno); } else { @@ -2421,14 +2466,15 @@ coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num) ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno), ALLOCNO_NUM (a), ALLOCNO_REGNO (a)); ALLOCNO_TEMP (allocno) = ALLOCNO_TEMP (a); - set_coalesced_allocnos_live_points (allocno); + setup_slot_coalesced_allocno_live_ranges (allocno); merge_allocnos (a, allocno); ira_assert (ALLOCNO_FIRST_COALESCED_ALLOCNO (a) == a); } } - for (i = 0; i < ira_max_point; i++) - CLEAR_REG_SET (&coalesced_allocnos_living_at_program_points[i]); - ira_free (coalesced_allocnos_living_at_program_points); + for (i = 0; i < ira_allocnos_num; i++) + ira_finish_allocno_live_range_list + (slot_coalesced_allocnos_live_ranges[i]); + ira_free (slot_coalesced_allocnos_live_ranges); return merged_p; } @@ -2499,8 +2545,8 @@ ira_sort_regnos_for_alter_reg (int *pseudo_regnos, int n, if (ALLOCNO_FIRST_COALESCED_ALLOCNO (allocno) != allocno || ALLOCNO_HARD_REGNO (allocno) >= 0 || (ALLOCNO_REGNO (allocno) < ira_reg_equiv_len - && (ira_reg_equiv_invariant_p[ALLOCNO_REGNO (allocno)] - || ira_reg_equiv_const[ALLOCNO_REGNO (allocno)] != NULL_RTX))) + && (ira_reg_equiv_const[ALLOCNO_REGNO (allocno)] != NULL_RTX + || ira_reg_equiv_invariant_p[ALLOCNO_REGNO (allocno)]))) continue; if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL) fprintf (ira_dump_file, " Slot %d (freq,size):", slot_num); @@ -2829,8 +2875,8 @@ ira_reuse_stack_slot (int regno, unsigned int inherent_size, FIRST_PSEUDO_REGISTER, i, bi) { another_allocno = ira_regno_allocno_map[i]; - if (ira_allocno_live_ranges_intersect_p (allocno, - another_allocno)) + if (allocnos_have_intersected_live_ranges_p (allocno, + another_allocno)) goto cont; } for (cost = 0, cp = ALLOCNO_COPIES (allocno); @@ -2878,7 +2924,7 @@ ira_reuse_stack_slot (int regno, unsigned int inherent_size, EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs, FIRST_PSEUDO_REGISTER, i, bi) { - ira_assert (! ira_pseudo_live_ranges_intersect_p (regno, i)); + ira_assert (! pseudos_have_intersected_live_ranges_p (regno, i)); } SET_REGNO_REG_SET (&slot->spilled_regs, regno); if (internal_flag_ira_verbose > 3 && ira_dump_file) diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c index 66376b6..6e7d769 100644 --- a/gcc/ira-conflicts.c +++ b/gcc/ira-conflicts.c @@ -532,52 +532,6 @@ propagate_copies (void) } } -/* Return TRUE if live ranges of allocnos A1 and A2 intersect. It is - used to find a conflict for new allocnos or allocnos with the - different cover classes. */ -bool -ira_allocno_live_ranges_intersect_p (ira_allocno_t a1, ira_allocno_t a2) -{ - allocno_live_range_t r1, r2; - - if (a1 == a2) - return false; - if (ALLOCNO_REG (a1) != NULL && ALLOCNO_REG (a2) != NULL - && (ORIGINAL_REGNO (ALLOCNO_REG (a1)) - == ORIGINAL_REGNO (ALLOCNO_REG (a2)))) - return false; - /* Remember the ranges are always kept ordered. */ - for (r1 = ALLOCNO_LIVE_RANGES (a1), r2 = ALLOCNO_LIVE_RANGES (a2); - r1 != NULL && r2 != NULL;) - { - if (r1->start > r2->finish) - r1 = r1->next; - else if (r2->start > r1->finish) - r2 = r2->next; - else - return true; - } - return false; -} - -/* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2 - intersect. This should be used when there is only one region. - Currently this is used during reload. */ -bool -ira_pseudo_live_ranges_intersect_p (int regno1, int regno2) -{ - ira_allocno_t a1, a2; - - ira_assert (regno1 >= FIRST_PSEUDO_REGISTER - && regno2 >= FIRST_PSEUDO_REGISTER); - /* Reg info caclulated by dataflow infrastructure can be different - from one calculated by regclass. */ - if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL - || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL) - return false; - return ira_allocno_live_ranges_intersect_p (a1, a2); -} - /* Array used to collect all conflict allocnos for given allocno. */ static ira_allocno_t *collected_conflict_allocnos; diff --git a/gcc/ira-int.h b/gcc/ira-int.h index 0b2e928..7f5479b 100644 --- a/gcc/ira-int.h +++ b/gcc/ira-int.h @@ -862,7 +862,14 @@ extern void ira_add_allocno_conflict (ira_allocno_t, ira_allocno_t); extern void ira_print_expanded_allocno (ira_allocno_t); extern allocno_live_range_t ira_create_allocno_live_range (ira_allocno_t, int, int, allocno_live_range_t); +extern allocno_live_range_t ira_copy_allocno_live_range_list + (allocno_live_range_t); +extern allocno_live_range_t ira_merge_allocno_live_ranges + (allocno_live_range_t, allocno_live_range_t); +extern bool ira_allocno_live_ranges_intersect_p (allocno_live_range_t, + allocno_live_range_t); extern void ira_finish_allocno_live_range (allocno_live_range_t); +extern void ira_finish_allocno_live_range_list (allocno_live_range_t); extern void ira_free_allocno_updated_costs (ira_allocno_t); extern ira_copy_t ira_create_copy (ira_allocno_t, ira_allocno_t, int, bool, rtx, ira_loop_tree_node_t); @@ -898,8 +905,6 @@ extern void ira_compress_allocno_live_ranges (void); extern void ira_finish_allocno_live_ranges (void); /* ira-conflicts.c */ -extern bool ira_allocno_live_ranges_intersect_p (ira_allocno_t, ira_allocno_t); -extern bool ira_pseudo_live_ranges_intersect_p (int, int); extern void ira_debug_conflicts (bool); extern void ira_build_conflicts (void); diff --git a/gcc/ira.c b/gcc/ira.c index d0232f7..d7f4e3d 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -1695,6 +1695,23 @@ expand_reg_info (int old_size) } } +/* Return TRUE if there is too high register pressure in the function. + It is used to decide when stack slot sharing is worth to do. */ +static bool +too_high_register_pressure_p (void) +{ + int i; + enum reg_class cover_class; + + for (i = 0; i < ira_reg_class_cover_size; i++) + { + cover_class = ira_reg_class_cover[i]; + if (ira_loop_tree_root->reg_pressure[cover_class] > 10000) + return true; + } + return false; +} + /* All natural loops. */ @@ -1709,6 +1726,7 @@ ira (FILE *f) int max_regno_before_ira, ira_max_point_before_emit; int rebuild_p; int saved_flag_ira_algorithm; + int saved_flag_ira_share_spill_slots; basic_block bb; timevar_push (TV_IRA); @@ -1792,6 +1810,13 @@ ira (FILE *f) loops_p = ira_build (optimize && (flag_ira_algorithm == IRA_ALGORITHM_REGIONAL || flag_ira_algorithm == IRA_ALGORITHM_MIXED)); + + saved_flag_ira_share_spill_slots = flag_ira_share_spill_slots; + if (too_high_register_pressure_p ()) + /* It is just wasting compiler's time to pack spilled pseudos into + stack slots in this case -- prohibit it. */ + flag_ira_share_spill_slots = FALSE; + ira_color (); ira_max_point_before_emit = ira_max_point; @@ -1902,6 +1927,8 @@ ira (FILE *f) fprintf (ira_dump_file, "+++Overall after reload %d\n", ira_overall_cost); ira_destroy (); + flag_ira_share_spill_slots = saved_flag_ira_share_spill_slots; + flow_loops_free (&ira_loops); free_dominance_info (CDI_DOMINATORS); FOR_ALL_BB (bb) -- 2.7.4