From: Jeff Law Date: Fri, 28 May 2010 22:19:22 +0000 (-0600) Subject: ira.c (ira_bad_reload_regno, [...]): New functions. X-Git-Tag: upstream/12.2.0~92791 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0896cc668adddc0be62f009679e1e7236ecec0e6;p=platform%2Fupstream%2Fgcc.git ira.c (ira_bad_reload_regno, [...]): New functions. * ira.c (ira_bad_reload_regno, ira_build_reload_regno_1): New functions. * ira.h (ira_bad_reload_regno): Declare * reload1.c (allocate_reload_reg): Use ira_bad_reload_regno. From-SVN: r160001 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3027edb..7bf2568 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2010-05-28 Jeff Law + * ira.c (ira_bad_reload_regno, ira_build_reload_regno_1): New + functions. + * ira.h (ira_bad_reload_regno): Declare + * reload1.c (allocate_reload_reg): Use ira_bad_reload_regno. + * ira-color.c (update_curr_costs): Free updated hard reg costs. (ira_reassign_conflict_allocnos): Remove bogus asserts. (allocno_reload_assign): Likewise. diff --git a/gcc/ira.c b/gcc/ira.c index 10be6da..84d7bc1 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -1374,6 +1374,46 @@ setup_prohibited_mode_move_regs (void) +/* Return nonzero if REGNO is a particularly bad choice for reloading X. */ +static bool +ira_bad_reload_regno_1 (int regno, rtx x) +{ + int x_regno; + ira_allocno_t a; + enum reg_class pref; + + /* We only deal with pseudo regs. */ + if (! x || GET_CODE (x) != REG) + return false; + + x_regno = REGNO (x); + if (x_regno < FIRST_PSEUDO_REGISTER) + return false; + + /* If the pseudo prefers REGNO explicitly, then do not consider + REGNO a bad spill choice. */ + pref = reg_preferred_class (x_regno); + if (reg_class_size[pref] == 1) + return !TEST_HARD_REG_BIT (reg_class_contents[pref], regno); + + /* If the pseudo conflicts with REGNO, then we consider REGNO a + poor choice for a reload regno. */ + a = ira_regno_allocno_map[x_regno]; + if (TEST_HARD_REG_BIT (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), regno)) + return true; + + return false; +} + +/* Return nonzero if REGNO is a particularly bad choice for reloading + IN or OUT. */ +bool +ira_bad_reload_regno (int regno, rtx in, rtx out) +{ + return (ira_bad_reload_regno_1 (regno, in) + || ira_bad_reload_regno_1 (regno, out)); +} + /* Function specific hard registers that can not be used for the register allocation. */ HARD_REG_SET ira_no_alloc_regs; diff --git a/gcc/ira.h b/gcc/ira.h index 9688f74..8c9734b 100644 --- a/gcc/ira.h +++ b/gcc/ira.h @@ -86,4 +86,5 @@ extern bool ira_reassign_pseudos (int *, int, HARD_REG_SET, HARD_REG_SET *, extern rtx ira_reuse_stack_slot (int, unsigned int, unsigned int); extern void ira_mark_new_stack_slot (rtx, int, unsigned int); extern bool ira_better_spill_reload_regno_p (int *, int *, rtx, rtx, rtx); +extern bool ira_bad_reload_regno (int, rtx, rtx); diff --git a/gcc/reload1.c b/gcc/reload1.c index 85880f8..f385fbb 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -5793,15 +5793,17 @@ allocate_reload_reg (struct insn_chain *chain ATTRIBUTE_UNUSED, int r, take any reg in the right class and not in use. If we want a consecutive group, here is where we look for it. - We use two passes so we can first look for reload regs to + We use three passes so we can first look for reload regs to reuse, which are already in use for other reloads in this insn, - and only then use additional registers. + and only then use additional registers which are not "bad", then + finally any register. + I think that maximizing reuse is needed to make sure we don't run out of reload regs. Suppose we have three reloads, and reloads A and B can share regs. These need two regs. Suppose A and B are given different regs. That leaves none for C. */ - for (pass = 0; pass < 2; pass++) + for (pass = 0; pass < 3; pass++) { /* I is the index in spill_regs. We advance it round-robin between insns to use all spill regs @@ -5841,6 +5843,13 @@ allocate_reload_reg (struct insn_chain *chain ATTRIBUTE_UNUSED, int r, regnum)))) { int nr = hard_regno_nregs[regnum][rld[r].mode]; + + /* During the second pass we want to avoid reload registers + which are "bad" for this reload. */ + if (pass == 1 + && ira_bad_reload_regno (regnum, rld[r].in, rld[r].out)) + continue; + /* Avoid the problem where spilling a GENERAL_OR_FP_REG (on 68000) got us two FP regs. If NR is 1, we would reject both of them. */ @@ -5871,7 +5880,7 @@ allocate_reload_reg (struct insn_chain *chain ATTRIBUTE_UNUSED, int r, } } - /* If we found something on pass 1, omit pass 2. */ + /* If we found something on the current pass, omit later passes. */ if (count < n_spills) break; }