Mercurial > hg > CbC > CbC_gcc
diff gcc/lra-assigns.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/lra-assigns.c Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/lra-assigns.c Thu Oct 25 07:37:49 2018 +0900 @@ -1,5 +1,5 @@ /* Assign reload pseudos. - Copyright (C) 2010-2017 Free Software Foundation, Inc. + Copyright (C) 2010-2018 Free Software Foundation, Inc. Contributed by Vladimir Makarov <vmakarov@redhat.com>. This file is part of GCC. @@ -485,7 +485,8 @@ int hr, conflict_hr, nregs; machine_mode biggest_mode; unsigned int k, conflict_regno; - int offset, val, biggest_nregs, nregs_diff; + poly_int64 offset; + int val, biggest_nregs, nregs_diff; enum reg_class rclass; bitmap_iterator bi; bool *rclass_intersect_p; @@ -1147,7 +1148,8 @@ { int p, i, j, n, regno, hard_regno; unsigned int k, conflict_regno; - int val, offset; + poly_int64 offset; + int val; HARD_REG_SET conflict_set; machine_mode mode; lra_live_range_t r; @@ -1337,24 +1339,33 @@ r2 = r2->start_next) { if (live_pseudos_reg_renumber[r2->regno] >= 0 - && rclass_intersect_p[regno_allocno_class_array[r2->regno]]) + && ! sparseset_bit_p (live_range_hard_reg_pseudos, r2->regno) + && rclass_intersect_p[regno_allocno_class_array[r2->regno]] + && ((int) r2->regno < lra_constraint_new_regno_start + || bitmap_bit_p (&lra_inheritance_pseudos, r2->regno) + || bitmap_bit_p (&lra_split_regs, r2->regno) + || bitmap_bit_p (&lra_optional_reload_pseudos, r2->regno) + /* There is no sense to consider another reload + pseudo if it has the same class. */ + || regno_allocno_class_array[r2->regno] != rclass)) sparseset_set_bit (live_range_hard_reg_pseudos, r2->regno); } } } } -/* Assign hard registers to reload pseudos and other pseudos. */ -static void +/* Assign hard registers to reload pseudos and other pseudos. Return + true if we was not able to assign hard registers to all reload + pseudos. */ +static bool assign_by_spills (void) { - int i, n, nfails, iter, regno, hard_regno, cost; + int i, n, nfails, iter, regno, regno2, hard_regno, cost; rtx restore_rtx; - rtx_insn *insn; bitmap_head changed_insns, do_not_assign_nonreload_pseudos; unsigned int u, conflict_regno; bitmap_iterator bi; - bool reload_p; + bool reload_p, fails_p = false; int max_regno = max_reg_num (); for (n = 0, i = lra_constraint_new_regno_start; i < max_regno; i++) @@ -1397,8 +1408,13 @@ hard_regno = spill_for (regno, &all_spilled_pseudos, iter == 1); if (hard_regno < 0) { - if (reload_p) + if (reload_p) { + /* Put unassigned reload pseudo first in the + array. */ + regno2 = sorted_pseudos[nfails]; sorted_pseudos[nfails++] = regno; + sorted_pseudos[i] = regno2; + } } else { @@ -1413,61 +1429,9 @@ bitmap_set_bit (&changed_pseudo_bitmap, regno); } } - if (nfails == 0) - break; - if (iter > 0) + if (nfails == 0 || iter > 0) { - /* We did not assign hard regs to reload pseudos after two iterations. - Either it's an asm and something is wrong with the constraints, or - we have run out of spill registers; error out in either case. */ - bool asm_p = false; - bitmap_head failed_reload_insns; - - bitmap_initialize (&failed_reload_insns, ®_obstack); - for (i = 0; i < nfails; i++) - { - regno = sorted_pseudos[i]; - bitmap_ior_into (&failed_reload_insns, - &lra_reg_info[regno].insn_bitmap); - /* Assign an arbitrary hard register of regno class to - avoid further trouble with this insn. */ - bitmap_clear_bit (&all_spilled_pseudos, regno); - assign_hard_regno - (ira_class_hard_regs[regno_allocno_class_array[regno]][0], - regno); - } - EXECUTE_IF_SET_IN_BITMAP (&failed_reload_insns, 0, u, bi) - { - insn = lra_insn_recog_data[u]->insn; - if (asm_noperands (PATTERN (insn)) >= 0) - { - asm_p = true; - error_for_asm (insn, - "%<asm%> operand has impossible constraints"); - /* Avoid further trouble with this insn. - For asm goto, instead of fixing up all the edges - just clear the template and clear input operands - (asm goto doesn't have any output operands). */ - if (JUMP_P (insn)) - { - rtx asm_op = extract_asm_operands (PATTERN (insn)); - ASM_OPERANDS_TEMPLATE (asm_op) = ggc_strdup (""); - ASM_OPERANDS_INPUT_VEC (asm_op) = rtvec_alloc (0); - ASM_OPERANDS_INPUT_CONSTRAINT_VEC (asm_op) = rtvec_alloc (0); - lra_update_insn_regno_info (insn); - } - else - { - PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx); - lra_set_insn_deleted (insn); - } - } - else if (!asm_p) - { - error ("unable to find a register to spill"); - fatal_insn ("this is the insn:", insn); - } - } + fails_p = nfails != 0; break; } /* This is a very rare event. We can not assign a hard register @@ -1516,7 +1480,8 @@ update_lives (conflict_regno, true); lra_setup_reg_renumber (conflict_regno, -1, false); } - n = nfails; + if (n < nfails) + n = nfails; } improve_inheritance (&changed_pseudo_bitmap); bitmap_clear (&non_reload_pseudos); @@ -1602,9 +1567,9 @@ bitmap_clear (&best_spill_pseudos_bitmap); bitmap_clear (&spill_pseudos_bitmap); bitmap_clear (&insn_conflict_pseudos); + return fails_p; } - /* Entry function to assign hard registers to new reload pseudos starting with LRA_CONSTRAINT_NEW_REGNO_START (by possible spilling of old pseudos) and possibly to the old pseudos. The function adds @@ -1613,9 +1578,10 @@ changed allocation. Return true if we did not spill any non-reload and non-inheritance - pseudos. */ + pseudos. Set up FAILS_P if we failed to assign hard registers to + all reload pseudos. */ bool -lra_assign (void) +lra_assign (bool &fails_p) { int i; unsigned int u; @@ -1659,7 +1625,7 @@ /* Setup insns to process on the next constraint pass. */ bitmap_initialize (&changed_pseudo_bitmap, ®_obstack); init_live_reload_and_inheritance_pseudos (); - assign_by_spills (); + fails_p = assign_by_spills (); finish_live_reload_and_inheritance_pseudos (); bitmap_ior_into (&changed_pseudo_bitmap, &all_spilled_pseudos); no_spills_p = true; @@ -1705,3 +1671,146 @@ return no_spills_p; } +/* Find start and finish insns for reload pseudo REGNO. Return true + if we managed to find the expected insns. Return false, + otherwise. */ +static bool +find_reload_regno_insns (int regno, rtx_insn * &start, rtx_insn * &finish) +{ + unsigned int uid; + bitmap_iterator bi; + int n = 0; + rtx_insn *prev_insn, *next_insn; + rtx_insn *start_insn = NULL, *first_insn = NULL, *second_insn = NULL; + + EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, bi) + { + if (start_insn == NULL) + start_insn = lra_insn_recog_data[uid]->insn; + n++; + } + /* For reload pseudo we should have at most 3 insns referring for it: + input/output reload insns and the original insn. */ + if (n > 3) + return false; + if (n > 1) + { + for (prev_insn = PREV_INSN (start_insn), + next_insn = NEXT_INSN (start_insn); + n != 1 && (prev_insn != NULL || next_insn != NULL); ) + { + if (prev_insn != NULL && first_insn == NULL) + { + if (! bitmap_bit_p (&lra_reg_info[regno].insn_bitmap, + INSN_UID (prev_insn))) + prev_insn = PREV_INSN (prev_insn); + else + { + first_insn = prev_insn; + n--; + } + } + if (next_insn != NULL && second_insn == NULL) + { + if (! bitmap_bit_p (&lra_reg_info[regno].insn_bitmap, + INSN_UID (next_insn))) + next_insn = NEXT_INSN (next_insn); + else + { + second_insn = next_insn; + n--; + } + } + } + if (n > 1) + return false; + } + start = first_insn != NULL ? first_insn : start_insn; + finish = second_insn != NULL ? second_insn : start_insn; + return true; +} + +/* Process reload pseudos which did not get a hard reg, split a hard + reg live range in live range of a reload pseudo, and then return + TRUE. If we did not split a hard reg live range, report an error, + and return FALSE. */ +bool +lra_split_hard_reg_for (void) +{ + int i, regno; + rtx_insn *insn, *first, *last; + unsigned int u; + bitmap_iterator bi; + enum reg_class rclass; + int max_regno = max_reg_num (); + /* We did not assign hard regs to reload pseudos after two + iterations. Either it's an asm and something is wrong with the + constraints, or we have run out of spill registers; error out in + either case. */ + bool asm_p = false; + bitmap_head failed_reload_insns, failed_reload_pseudos; + + if (lra_dump_file != NULL) + fprintf (lra_dump_file, + "\n****** Splitting a hard reg after assignment #%d: ******\n\n", + lra_assignment_iter); + bitmap_initialize (&failed_reload_pseudos, ®_obstack); + for (i = lra_constraint_new_regno_start; i < max_regno; i++) + if (reg_renumber[i] < 0 && lra_reg_info[i].nrefs != 0 + && (rclass = lra_get_allocno_class (i)) != NO_REGS + && ! bitmap_bit_p (&non_reload_pseudos, i)) + { + if (! find_reload_regno_insns (i, first, last)) + continue; + if (spill_hard_reg_in_range (i, rclass, first, last)) + { + bitmap_clear (&failed_reload_pseudos); + return true; + } + bitmap_set_bit (&failed_reload_pseudos, i); + } + bitmap_initialize (&failed_reload_insns, ®_obstack); + EXECUTE_IF_SET_IN_BITMAP (&failed_reload_pseudos, 0, u, bi) + { + regno = u; + bitmap_ior_into (&failed_reload_insns, + &lra_reg_info[regno].insn_bitmap); + lra_setup_reg_renumber + (regno, ira_class_hard_regs[lra_get_allocno_class (regno)][0], false); + } + EXECUTE_IF_SET_IN_BITMAP (&failed_reload_insns, 0, u, bi) + { + insn = lra_insn_recog_data[u]->insn; + if (asm_noperands (PATTERN (insn)) >= 0) + { + asm_p = true; + error_for_asm (insn, + "%<asm%> operand has impossible constraints"); + /* Avoid further trouble with this insn. + For asm goto, instead of fixing up all the edges + just clear the template and clear input operands + (asm goto doesn't have any output operands). */ + if (JUMP_P (insn)) + { + rtx asm_op = extract_asm_operands (PATTERN (insn)); + ASM_OPERANDS_TEMPLATE (asm_op) = ggc_strdup (""); + ASM_OPERANDS_INPUT_VEC (asm_op) = rtvec_alloc (0); + ASM_OPERANDS_INPUT_CONSTRAINT_VEC (asm_op) = rtvec_alloc (0); + lra_update_insn_regno_info (insn); + } + else + { + PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx); + lra_set_insn_deleted (insn); + } + } + else if (!asm_p) + { + error ("unable to find a register to spill"); + fatal_insn ("this is the insn:", insn); + } + } + bitmap_clear (&failed_reload_pseudos); + bitmap_clear (&failed_reload_insns); + return false; +}