Mercurial > hg > CbC > CbC_gcc
diff gcc/ira-color.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
line wrap: on
line diff
--- a/gcc/ira-color.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/ira-color.c Thu Feb 13 11:34:05 2020 +0900 @@ -1,5 +1,5 @@ /* IRA allocation based on graph coloring. - Copyright (C) 2006-2018 Free Software Foundation, Inc. + Copyright (C) 2006-2020 Free Software Foundation, Inc. Contributed by Vladimir Makarov <vmakarov@redhat.com>. This file is part of GCC. @@ -151,6 +151,8 @@ ira_allocno_t next_thread_allocno; /* All thread frequency. Defined only for first thread allocno. */ int thread_freq; + /* Sum of frequencies of hard register preferences of the allocno. */ + int hard_reg_prefs; }; /* See above. */ @@ -218,7 +220,7 @@ allocno_hard_regs_hasher::equal (const allocno_hard_regs *hv1, const allocno_hard_regs *hv2) { - return hard_reg_set_equal_p (hv1->set, hv2->set); + return hv1->set == hv2->set; } /* Hash table of unique allocno hard registers. */ @@ -261,14 +263,14 @@ allocno_hard_regs_t hv; gcc_assert (! hard_reg_set_empty_p (set)); - COPY_HARD_REG_SET (temp.set, set); + temp.set = set; if ((hv = find_hard_regs (&temp)) != NULL) hv->cost += cost; else { hv = ((struct allocno_hard_regs *) ira_allocate (sizeof (struct allocno_hard_regs))); - COPY_HARD_REG_SET (hv->set, set); + hv->set = set; hv->cost = cost; allocno_hard_regs_vec.safe_push (hv); insert_hard_regs (hv); @@ -371,7 +373,7 @@ start = hard_regs_node_vec.length (); for (node = *roots; node != NULL; node = node->next) { - if (hard_reg_set_equal_p (hv->set, node->hard_regs->set)) + if (hv->set == node->hard_regs->set) return; if (hard_reg_set_subset_p (hv->set, node->hard_regs->set)) { @@ -382,8 +384,7 @@ hard_regs_node_vec.safe_push (node); else if (hard_reg_set_intersect_p (hv->set, node->hard_regs->set)) { - COPY_HARD_REG_SET (temp_set, hv->set); - AND_HARD_REG_SET (temp_set, node->hard_regs->set); + temp_set = hv->set & node->hard_regs->set; hv2 = add_allocno_hard_regs (temp_set, hv->cost); add_allocno_hard_regs_to_forest (&node->first, hv2); } @@ -398,7 +399,7 @@ i++) { node = hard_regs_node_vec[i]; - IOR_HARD_REG_SET (temp_set, node->hard_regs->set); + temp_set |= node->hard_regs->set; } hv = add_allocno_hard_regs (temp_set, hv->cost); new_node = create_new_allocno_hard_regs_node (hv); @@ -479,24 +480,26 @@ static void print_hard_reg_set (FILE *f, HARD_REG_SET set, bool new_line_p) { - int i, start; - - for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++) + int i, start, end; + + for (start = end = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++) { - if (TEST_HARD_REG_BIT (set, i)) + bool reg_included = TEST_HARD_REG_BIT (set, i); + + if (reg_included) { - if (i == 0 || ! TEST_HARD_REG_BIT (set, i - 1)) + if (start == -1) start = i; + end = i; } - if (start >= 0 - && (i == FIRST_PSEUDO_REGISTER - 1 || ! TEST_HARD_REG_BIT (set, i))) + if (start >= 0 && (!reg_included || i == FIRST_PSEUDO_REGISTER - 1)) { - if (start == i - 1) + if (start == end) fprintf (f, " %d", start); - else if (start == i - 2) - fprintf (f, " %d %d", start, start + 1); + else if (start == end + 1) + fprintf (f, " %d %d", start, end); else - fprintf (f, " %d-%d", start, i - 1); + fprintf (f, " %d-%d", start, end); start = -1; } } @@ -717,8 +720,7 @@ (allocno_data->profitable_hard_regs, ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a))); } - SET_HARD_REG_SET (temp); - AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs); + temp = ~ira_no_alloc_regs; add_allocno_hard_regs (temp, 0); qsort (allocno_hard_regs_vec.address () + start, allocno_hard_regs_vec.length () - start, @@ -833,10 +835,10 @@ nobj = ALLOCNO_NUM_OBJECTS (a); data = ALLOCNO_COLOR_DATA (a); subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start; - COPY_HARD_REG_SET (profitable_hard_regs, data->profitable_hard_regs); + profitable_hard_regs = data->profitable_hard_regs; node = data->hard_regs_node; node_preorder_num = node->preorder_num; - COPY_HARD_REG_SET (node_set, node->hard_regs->set); + node_set = node->hard_regs->set; node_check_tick++; for (k = 0; k < nobj; k++) { @@ -859,7 +861,7 @@ ->profitable_hard_regs)) continue; conflict_node = conflict_data->hard_regs_node; - COPY_HARD_REG_SET (conflict_node_set, conflict_node->hard_regs->set); + conflict_node_set = conflict_node->hard_regs->set; if (hard_reg_set_subset_p (node_set, conflict_node_set)) temp_node = node; else @@ -897,8 +899,7 @@ int j, n, hard_regno; enum reg_class aclass; - COPY_HARD_REG_SET (temp_set, temp_node->hard_regs->set); - AND_HARD_REG_SET (temp_set, profitable_hard_regs); + temp_set = temp_node->hard_regs->set & profitable_hard_regs; aclass = ALLOCNO_CLASS (a); for (n = 0, j = ira_class_hard_regs_num[aclass] - 1; j >= 0; j--) { @@ -1042,15 +1043,15 @@ else { mode = ALLOCNO_MODE (a); - COPY_HARD_REG_SET (data->profitable_hard_regs, - ira_useful_class_mode_regs[aclass][mode]); + data->profitable_hard_regs + = ira_useful_class_mode_regs[aclass][mode]; nobj = ALLOCNO_NUM_OBJECTS (a); for (k = 0; k < nobj; k++) { ira_object_t obj = ALLOCNO_OBJECT (a, k); - AND_COMPL_HARD_REG_SET (data->profitable_hard_regs, - OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); + data->profitable_hard_regs + &= ~OBJECT_TOTAL_CONFLICT_HARD_REGS (obj); } } } @@ -1091,9 +1092,8 @@ hard_regno + num); } else - AND_COMPL_HARD_REG_SET - (ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs, - ira_reg_mode_hard_regset[hard_regno][mode]); + ALLOCNO_COLOR_DATA (conflict_a)->profitable_hard_regs + &= ~ira_reg_mode_hard_regset[hard_regno][mode]; } } } @@ -1108,7 +1108,6 @@ || empty_profitable_hard_regs (a)) continue; data = ALLOCNO_COLOR_DATA (a); - mode = ALLOCNO_MODE (a); if ((costs = ALLOCNO_UPDATED_HARD_REG_COSTS (a)) != NULL || (costs = ALLOCNO_HARD_REG_COSTS (a)) != NULL) { @@ -1377,6 +1376,7 @@ e.g. DImode for AREG on x86. For such cases the register move cost will be maximal. */ mode = narrower_subreg_mode (mode, ALLOCNO_MODE (cp->second)); + ira_init_register_move_cost_if_necessary (mode); cost = (cp->second == allocno ? ira_register_move_cost[mode][rclass][aclass] @@ -1575,7 +1575,7 @@ /* Set up conflicting (through CONFLICT_REGS) for each object of allocno A and the start allocno profitable regs (through START_PROFITABLE_REGS). Remember that the start profitable regs - exclude hard regs which can not hold value of mode of allocno A. + exclude hard regs which cannot hold value of mode of allocno A. This covers mostly cases when multi-register value should be aligned. */ static inline void @@ -1590,20 +1590,15 @@ for (i = 0; i < nwords; i++) { obj = ALLOCNO_OBJECT (a, i); - COPY_HARD_REG_SET (conflict_regs[i], - OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); + conflict_regs[i] = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj); } if (retry_p) - { - COPY_HARD_REG_SET (*start_profitable_regs, - reg_class_contents[ALLOCNO_CLASS (a)]); - AND_COMPL_HARD_REG_SET (*start_profitable_regs, - ira_prohibited_class_mode_regs - [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]); - } + *start_profitable_regs + = (reg_class_contents[ALLOCNO_CLASS (a)] + &~ (ira_prohibited_class_mode_regs + [ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)])); else - COPY_HARD_REG_SET (*start_profitable_regs, - ALLOCNO_COLOR_DATA (a)->profitable_hard_regs); + *start_profitable_regs = ALLOCNO_COLOR_DATA (a)->profitable_hard_regs; } /* Return true if HARD_REGNO is ok for assigning to allocno A with @@ -1660,7 +1655,7 @@ 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) + && !crtl->abi->clobbers_full_reg_p (hard_regno + i) && !LOCAL_REGNO (hard_regno + i)) nregs++; return nregs; @@ -1804,9 +1799,8 @@ hard_regno + num); } else - IOR_HARD_REG_SET - (conflicting_regs[word], - ira_reg_mode_hard_regset[hard_regno][mode]); + conflicting_regs[word] + |= ira_reg_mode_hard_regset[hard_regno][mode]; if (hard_reg_set_subset_p (profitable_hard_regs, conflicting_regs[word])) goto fail; @@ -2183,6 +2177,7 @@ ira_allocno_t a; unsigned int j; bitmap_iterator bi; + ira_pref_t pref; EXECUTE_IF_SET_IN_BITMAP (consideration_allocno_bitmap, 0, j, bi) { @@ -2191,6 +2186,9 @@ ALLOCNO_COLOR_DATA (a)->first_thread_allocno = ALLOCNO_COLOR_DATA (a)->next_thread_allocno = a; ALLOCNO_COLOR_DATA (a)->thread_freq = ALLOCNO_FREQ (a); + ALLOCNO_COLOR_DATA (a)->hard_reg_prefs = 0; + for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = pref->next_pref) + ALLOCNO_COLOR_DATA (a)->hard_reg_prefs += pref->freq; } } @@ -2261,6 +2259,16 @@ ira_allocno_t t2 = ALLOCNO_COLOR_DATA (a2)->first_thread_allocno; int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2); + /* Push allocnos with minimal hard_reg_prefs first. */ + pref1 = ALLOCNO_COLOR_DATA (a1)->hard_reg_prefs; + pref2 = ALLOCNO_COLOR_DATA (a2)->hard_reg_prefs; + if ((diff = pref1 - pref2) != 0) + return diff; + /* Push allocnos with minimal conflict_allocno_hard_prefs first. */ + pref1 = ALLOCNO_COLOR_DATA (a1)->conflict_allocno_hard_prefs; + pref2 = ALLOCNO_COLOR_DATA (a2)->conflict_allocno_hard_prefs; + if ((diff = pref1 - pref2) != 0) + return diff; freq1 = ALLOCNO_COLOR_DATA (t1)->thread_freq; freq2 = ALLOCNO_COLOR_DATA (t2)->thread_freq; if ((diff = freq1 - freq2) != 0) @@ -2272,7 +2280,7 @@ /* Push pseudos requiring less hard registers first. It means that we will assign pseudos requiring more hard registers first avoiding creation small holes in free hard register file into - which the pseudos requiring more hard registers can not fit. */ + which the pseudos requiring more hard registers cannot fit. */ if ((diff = (ira_reg_class_max_nregs[cl1][ALLOCNO_MODE (a1)] - ira_reg_class_max_nregs[cl2][ALLOCNO_MODE (a2)])) != 0) return diff; @@ -2286,11 +2294,6 @@ a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num; if ((diff = a2_num - a1_num) != 0) return diff; - /* Push allocnos with minimal conflict_allocno_hard_prefs first. */ - pref1 = ALLOCNO_COLOR_DATA (a1)->conflict_allocno_hard_prefs; - pref2 = ALLOCNO_COLOR_DATA (a2)->conflict_allocno_hard_prefs; - if ((diff = pref1 - pref2) != 0) - return diff; return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1); } @@ -2699,8 +2702,7 @@ reg_class_names[aclass], ira_class_hard_regs_num[aclass], n); print_hard_reg_set (ira_dump_file, data->profitable_hard_regs, false); fprintf (ira_dump_file, ", %snode: ", - hard_reg_set_equal_p (data->profitable_hard_regs, - data->hard_regs_node->hard_regs->set) + data->profitable_hard_regs == data->hard_regs_node->hard_regs->set ? "" : "^"); print_hard_reg_set (ira_dump_file, data->hard_regs_node->hard_regs->set, false); @@ -2829,6 +2831,7 @@ } else gcc_unreachable (); + ira_init_register_move_cost_if_necessary (allocno_mode); cost += cp->freq * ira_register_move_cost[allocno_mode][rclass][rclass]; } return cost; @@ -4388,11 +4391,10 @@ for (i = 0; i < n; i++) { ira_object_t obj = ALLOCNO_OBJECT (a, i); - COPY_HARD_REG_SET (saved[i], OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); - IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), forbidden_regs); + saved[i] = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj); + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= forbidden_regs; if (! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0) - IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), - call_used_reg_set); + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= ira_need_caller_save_regs (a); } ALLOCNO_ASSIGNED_P (a) = false; aclass = ALLOCNO_CLASS (a); @@ -4411,9 +4413,7 @@ ? ALLOCNO_CLASS_COST (a) : ALLOCNO_HARD_REG_COSTS (a)[ira_class_hard_reg_index [aclass][hard_regno]])); - if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0 - && ira_hard_reg_set_intersection_p (hard_regno, ALLOCNO_MODE (a), - call_used_reg_set)) + if (ira_need_caller_save_p (a, hard_regno)) { ira_assert (flag_caller_saves); caller_save_needed = 1; @@ -4435,7 +4435,7 @@ for (i = 0; i < n; i++) { ira_object_t obj = ALLOCNO_OBJECT (a, i); - COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), saved[i]); + OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) = saved[i]; } return reg_renumber[regno] >= 0; } @@ -4520,9 +4520,9 @@ for (i = 0; i < num; i++) { regno = spilled_pseudo_regs[i]; - COPY_HARD_REG_SET (forbidden_regs, bad_spill_regs); - IOR_HARD_REG_SET (forbidden_regs, pseudo_forbidden_regs[regno]); - IOR_HARD_REG_SET (forbidden_regs, pseudo_previous_regs[regno]); + forbidden_regs = (bad_spill_regs + | pseudo_forbidden_regs[regno] + | pseudo_previous_regs[regno]); gcc_assert (reg_renumber[regno] < 0); a = ira_regno_allocno_map[regno]; ira_mark_allocation_change (regno); @@ -4558,7 +4558,7 @@ ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno]; rtx x; bitmap_iterator bi; - struct ira_spilled_reg_stack_slot *slot = NULL; + class ira_spilled_reg_stack_slot *slot = NULL; ira_assert (! ira_use_lra_p); @@ -4670,7 +4670,7 @@ void ira_mark_new_stack_slot (rtx x, int regno, poly_uint64 total_size) { - struct ira_spilled_reg_stack_slot *slot; + class ira_spilled_reg_stack_slot *slot; int slot_num; ira_allocno_t allocno; @@ -4700,16 +4700,16 @@ given IN and OUT for INSN. Return also number points (through EXCESS_PRESSURE_LIVE_LENGTH) where the pseudo-register lives and the register pressure is high, number of references of the - pseudo-registers (through NREFS), number of callee-clobbered - hard-registers occupied by the pseudo-registers (through - CALL_USED_COUNT), and the first hard regno occupied by the + pseudo-registers (through NREFS), the number of psuedo registers + whose allocated register wouldn't need saving in the prologue + (through CALL_USED_COUNT), and the first hard regno occupied by the pseudo-registers (through FIRST_HARD_REGNO). */ static int calculate_spill_cost (int *regnos, rtx in, rtx out, rtx_insn *insn, int *excess_pressure_live_length, int *nrefs, int *call_used_count, int *first_hard_regno) { - int i, cost, regno, hard_regno, j, count, saved_cost, nregs; + int i, cost, regno, hard_regno, count, saved_cost; bool in_p, out_p; int length; ira_allocno_t a; @@ -4726,11 +4726,8 @@ a = ira_regno_allocno_map[regno]; length += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a) / ALLOCNO_NUM_OBJECTS (a); cost += ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a); - nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (a)); - for (j = 0; j < nregs; j++) - if (! TEST_HARD_REG_BIT (call_used_reg_set, hard_regno + j)) - break; - if (j == nregs) + if (in_hard_reg_set_p (crtl->abi->full_reg_clobbers (), + ALLOCNO_MODE (a), hard_regno)) count++; in_p = in && REG_P (in) && (int) REGNO (in) == hard_regno; out_p = out && REG_P (out) && (int) REGNO (out) == hard_regno; @@ -4852,7 +4849,8 @@ static void fast_allocation (void) { - int i, j, k, num, class_size, hard_regno; + int i, j, k, num, class_size, hard_regno, best_hard_regno, cost, min_cost; + int *costs; #ifdef STACK_REGS bool no_stack_reg_p; #endif @@ -4886,11 +4884,10 @@ for (l = 0; l < nr; l++) { ira_object_t obj = ALLOCNO_OBJECT (a, l); - IOR_HARD_REG_SET (conflict_hard_regs, - OBJECT_CONFLICT_HARD_REGS (obj)); + conflict_hard_regs |= OBJECT_CONFLICT_HARD_REGS (obj); for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next) for (j = r->start; j <= r->finish; j++) - IOR_HARD_REG_SET (conflict_hard_regs, used_hard_regs[j]); + conflict_hard_regs |= used_hard_regs[j]; } aclass = ALLOCNO_CLASS (a); ALLOCNO_ASSIGNED_P (a) = true; @@ -4903,6 +4900,9 @@ no_stack_reg_p = ALLOCNO_NO_STACK_REG_P (a); #endif class_size = ira_class_hard_regs_num[aclass]; + costs = ALLOCNO_HARD_REG_COSTS (a); + min_cost = INT_MAX; + best_hard_regno = -1; for (j = 0; j < class_size; j++) { hard_regno = ira_class_hard_regs[aclass][j]; @@ -4915,16 +4915,27 @@ || (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[aclass][mode], hard_regno))) continue; - ALLOCNO_HARD_REGNO (a) = hard_regno; - for (l = 0; l < nr; l++) + if (costs == NULL) + { + best_hard_regno = hard_regno; + break; + } + cost = costs[j]; + if (min_cost > cost) { - ira_object_t obj = ALLOCNO_OBJECT (a, l); - for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next) - for (k = r->start; k <= r->finish; k++) - IOR_HARD_REG_SET (used_hard_regs[k], - ira_reg_mode_hard_regset[hard_regno][mode]); + min_cost = cost; + best_hard_regno = hard_regno; } - break; + } + if (best_hard_regno < 0) + continue; + ALLOCNO_HARD_REGNO (a) = hard_regno = best_hard_regno; + for (l = 0; l < nr; l++) + { + ira_object_t obj = ALLOCNO_OBJECT (a, l); + for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next) + for (k = r->start; k <= r->finish; k++) + used_hard_regs[k] |= ira_reg_mode_hard_regset[hard_regno][mode]; } } ira_free (sorted_allocnos);