diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2012-09-19 15:38:16 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2012-09-19 15:38:16 +0000 |
commit | 17fff17b06f8a9fe4aad1e117cce060be0c6ef61 (patch) | |
tree | 517a7be095a7ea671516cbc69701962ee2aface4 /gcc/reload1.c | |
parent | 5b156feaf87dac1a14203b280f19c1d645994211 (diff) | |
download | gcc-17fff17b06f8a9fe4aad1e117cce060be0c6ef61.zip gcc-17fff17b06f8a9fe4aad1e117cce060be0c6ef61.tar.gz gcc-17fff17b06f8a9fe4aad1e117cce060be0c6ef61.tar.bz2 |
re PR rtl-optimization/54290 (wrong code at -O2 with large offset)
PR rtl-optimization/54290
* reload1.c (choose_reload_regs): Also take into account secondary MEMs
to remove address replacements for inherited reloads.
(replaced_subreg): Move around.
From-SVN: r191484
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r-- | gcc/reload1.c | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c index 1bcdfad..4487ea8 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -6352,6 +6352,20 @@ choose_reload_regs_init (struct insn_chain *chain, rtx *save_reload_reg_rtx) rld[i].when_needed, rld[i].mode); } +#ifdef SECONDARY_MEMORY_NEEDED +/* If X is not a subreg, return it unmodified. If it is a subreg, + look up whether we made a replacement for the SUBREG_REG. Return + either the replacement or the SUBREG_REG. */ + +static rtx +replaced_subreg (rtx x) +{ + if (GET_CODE (x) == SUBREG) + return find_replacement (&SUBREG_REG (x)); + return x; +} +#endif + /* Assign hard reg targets for the pseudo-registers we must reload into hard regs for this insn. Also output the instructions to copy them in and out of the hard regs. @@ -6942,7 +6956,7 @@ choose_reload_regs (struct insn_chain *chain) for (j = 0; j < n_reloads; j++) { int r = reload_order[j]; - rtx check_reg; + rtx check_reg, tem; if (reload_inherited[r] && rld[r].reg_rtx) check_reg = rld[r].reg_rtx; else if (reload_override_in[r] @@ -6974,10 +6988,26 @@ choose_reload_regs (struct insn_chain *chain) If we succeeded removing some reload and we are doing a preliminary pass just to remove such reloads, make another pass, since the removal of one reload might allow us to inherit another one. */ - else if (rld[r].in + else if (pass + && rld[r].in + && rld[r].out != rld[r].in + && remove_address_replacements (rld[r].in)) + pass = 2; +#ifdef SECONDARY_MEMORY_NEEDED + /* If we needed a memory location for the reload, we also have to + remove its related reloads. */ + else if (pass + && rld[r].in && rld[r].out != rld[r].in - && remove_address_replacements (rld[r].in) && pass) + && (tem = replaced_subreg (rld[r].in), REG_P (tem)) + && REGNO (tem) < FIRST_PSEUDO_REGISTER + && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (tem)), + rld[r].rclass, rld[r].inmode) + && remove_address_replacements + (get_secondary_mem (tem, rld[r].inmode, rld[r].opnum, + rld[r].when_needed))) pass = 2; +#endif } } @@ -8458,20 +8488,6 @@ emit_insn_if_valid_for_reload (rtx insn) return NULL; } -#ifdef SECONDARY_MEMORY_NEEDED -/* If X is not a subreg, return it unmodified. If it is a subreg, - look up whether we made a replacement for the SUBREG_REG. Return - either the replacement or the SUBREG_REG. */ - -static rtx -replaced_subreg (rtx x) -{ - if (GET_CODE (x) == SUBREG) - return find_replacement (&SUBREG_REG (x)); - return x; -} -#endif - /* Emit code to perform a reload from IN (which may be a reload register) to OUT (which may also be a reload register). IN or OUT is from operand OPNUM with reload type TYPE. |