diff options
-rw-r--r-- | gcc/ChangeLog | 23 | ||||
-rw-r--r-- | gcc/ira-color.c | 43 | ||||
-rw-r--r-- | gcc/ira-costs.c | 8 | ||||
-rw-r--r-- | gcc/ira-int.h | 8 | ||||
-rw-r--r-- | gcc/ira.c | 18 |
5 files changed, 72 insertions, 28 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dabaf4eda27..41c3db20a36 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2011-08-17 Vladimir Makarov <vmakarov@redhat.com> + + PR rtl-optimization/50107 + * ira-int.h (ira_hard_reg_not_in_set_p): Remove. + (ira_hard_reg_in_set_p): New. + + * ira-color.c (calculate_saved_nregs): New. + (assign_hard_reg): Use it. Set up allocated_hard_reg_p for all + hard regs. + (allocno_reload_assign, fast_allocation): Use + ira_hard_reg_set_intersection_p instead of + ira_hard_reg_not_in_set_p. + + * ira.c (setup_reg_renumber): Use + ira_hard_reg_set_intersection_p instead of + ira_hard_reg_not_in_set_p. + (setup_allocno_assignment_flags, calculate_allocation_cost): Use + ira_hard_reg_in_set_p instead of ira_hard_reg_not_in_set_p. + + * ira-costs.c (ira_tune_allocno_costs): Use + ira_hard_reg_set_intersection_p instead of + ira_hard_reg_not_in_set_p. + 2011-08-18 H.J. Lu <hongjiu.lu@intel.com> Igor Zamyatin <igor.zamyatin@intel.com> diff --git a/gcc/ira-color.c b/gcc/ira-color.c index 7a1073b0bf2..eb87b0e419b 100644 --- a/gcc/ira-color.c +++ b/gcc/ira-color.c @@ -1519,6 +1519,26 @@ check_hard_reg_p (ira_allocno_t a, int hard_regno, } return j == nregs; } +#ifndef HONOR_REG_ALLOC_ORDER + +/* Return number of registers needed to be saved and restored at + function prologue/epilogue if we allocate HARD_REGNO to hold value + of MODE. */ +static int +calculate_saved_nregs (int hard_regno, enum machine_mode mode) +{ + int i; + int nregs = 0; + + ira_assert (hard_regno >= 0); + for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--) + if (!allocated_hardreg_p[hard_regno + i] + && !TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + i) + && !LOCAL_REGNO (hard_regno + i)) + nregs++; + return nregs; +} +#endif /* Choose a hard register for allocno A. If RETRY_P is TRUE, it means that the function called from function @@ -1547,7 +1567,7 @@ static bool assign_hard_reg (ira_allocno_t a, bool retry_p) { HARD_REG_SET conflicting_regs[2], profitable_hard_regs[2]; - int i, j, hard_regno, best_hard_regno, class_size; + int i, j, hard_regno, best_hard_regno, class_size, saved_nregs; int cost, mem_cost, min_cost, full_cost, min_full_cost, nwords, word; int *a_costs; enum reg_class aclass; @@ -1716,16 +1736,14 @@ assign_hard_reg (ira_allocno_t a, bool retry_p) cost = costs[i]; full_cost = full_costs[i]; #ifndef HONOR_REG_ALLOC_ORDER - if (! allocated_hardreg_p[hard_regno] - && ira_hard_reg_not_in_set_p (hard_regno, mode, call_used_reg_set) - && !LOCAL_REGNO (hard_regno)) + if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0) /* We need to save/restore the hard register in epilogue/prologue. Therefore we increase the cost. */ { - /* ??? If only part is call clobbered. */ rclass = REGNO_REG_CLASS (hard_regno); - add_cost = (ira_memory_move_cost[mode][rclass][0] - + ira_memory_move_cost[mode][rclass][1] - 1); + add_cost = ((ira_memory_move_cost[mode][rclass][0] + + ira_memory_move_cost[mode][rclass][1]) + * saved_nregs / hard_regno_nregs[hard_regno][mode] - 1); cost += add_cost; full_cost += add_cost; } @@ -1748,7 +1766,10 @@ assign_hard_reg (ira_allocno_t a, bool retry_p) } fail: if (best_hard_regno >= 0) - allocated_hardreg_p[best_hard_regno] = true; + { + for (i = hard_regno_nregs[best_hard_regno][mode] - 1; i >= 0; i--) + allocated_hardreg_p[best_hard_regno + 1] = true; + } ALLOCNO_HARD_REGNO (a) = best_hard_regno; ALLOCNO_ASSIGNED_P (a) = true; if (best_hard_regno >= 0) @@ -3975,8 +3996,8 @@ allocno_reload_assign (ira_allocno_t a, HARD_REG_SET forbidden_regs) : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index [aclass][hard_regno]])); if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0 - && ! ira_hard_reg_not_in_set_p (hard_regno, ALLOCNO_MODE (a), - call_used_reg_set)) + && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a), + call_used_reg_set)) { ira_assert (flag_caller_saves); caller_save_needed = 1; @@ -4467,7 +4488,7 @@ fast_allocation (void) && hard_regno <= LAST_STACK_REG) continue; #endif - if (!ira_hard_reg_not_in_set_p (hard_regno, mode, conflict_hard_regs) + if (ira_hard_reg_set_intersection_p (hard_regno, mode, conflict_hard_regs) || (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode], hard_regno))) continue; diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c index 39ef33a541c..12d3ed67fa7 100644 --- a/gcc/ira-costs.c +++ b/gcc/ira-costs.c @@ -2072,9 +2072,9 @@ ira_tune_allocno_costs (void) skip_p = false; FOR_EACH_ALLOCNO_OBJECT (a, obj, oi) { - if (! ira_hard_reg_not_in_set_p (regno, mode, - OBJECT_CONFLICT_HARD_REGS - (obj))) + if (ira_hard_reg_set_intersection_p (regno, mode, + OBJECT_CONFLICT_HARD_REGS + (obj))) { skip_p = true; break; @@ -2084,7 +2084,7 @@ ira_tune_allocno_costs (void) continue; rclass = REGNO_REG_CLASS (regno); cost = 0; - if (! ira_hard_reg_not_in_set_p (regno, mode, call_used_reg_set) + if (ira_hard_reg_set_intersection_p (regno, mode, call_used_reg_set) || HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)) cost += (ALLOCNO_CALL_FREQ (a) * (ira_memory_move_cost[mode][rclass][0] diff --git a/gcc/ira-int.h b/gcc/ira-int.h index 6a6c4831c00..1db9b411e0b 100644 --- a/gcc/ira-int.h +++ b/gcc/ira-int.h @@ -1323,17 +1323,17 @@ hard_reg_set_size (HARD_REG_SET set) } /* The function returns TRUE if hard registers starting with - HARD_REGNO and containing value of MODE are not in set + HARD_REGNO and containing value of MODE are fully in set HARD_REGSET. */ static inline bool -ira_hard_reg_not_in_set_p (int hard_regno, enum machine_mode mode, - HARD_REG_SET hard_regset) +ira_hard_reg_in_set_p (int hard_regno, enum machine_mode mode, + HARD_REG_SET hard_regset) { int i; ira_assert (hard_regno >= 0); for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--) - if (TEST_HARD_REG_BIT (hard_regset, hard_regno + i)) + if (!TEST_HARD_REG_BIT (hard_regset, hard_regno + i)) return false; return true; } diff --git a/gcc/ira.c b/gcc/ira.c index b54762e8962..e4be8b52f71 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -1953,8 +1953,8 @@ setup_reg_renumber (void) reg_class_contents[pclass]); } if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0 - && ! ira_hard_reg_not_in_set_p (hard_regno, ALLOCNO_MODE (a), - call_used_reg_set)) + && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a), + call_used_reg_set)) { ira_assert (!optimize || flag_caller_saves || regno >= ira_reg_equiv_len @@ -1992,10 +1992,10 @@ setup_allocno_assignment_flags (void) || ALLOCNO_EMIT_DATA (a)->mem_optimized_dest_p || (ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a)) < 0); - ira_assert (hard_regno < 0 - || ! ira_hard_reg_not_in_set_p (hard_regno, ALLOCNO_MODE (a), - reg_class_contents - [ALLOCNO_CLASS (a)])); + ira_assert + (hard_regno < 0 + || ira_hard_reg_in_set_p (hard_regno, ALLOCNO_MODE (a), + reg_class_contents[ALLOCNO_CLASS (a)])); } } @@ -2013,9 +2013,9 @@ calculate_allocation_cost (void) { hard_regno = ALLOCNO_HARD_REGNO (a); ira_assert (hard_regno < 0 - || ! ira_hard_reg_not_in_set_p - (hard_regno, ALLOCNO_MODE (a), - reg_class_contents[ALLOCNO_CLASS (a)])); + || (ira_hard_reg_in_set_p + (hard_regno, ALLOCNO_MODE (a), + reg_class_contents[ALLOCNO_CLASS (a)]))); if (hard_regno < 0) { cost = ALLOCNO_MEMORY_COST (a); |