From patchwork Tue Sep 18 22:17:52 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Fix PR rtl-optimization/54290 From: Eric Botcazou X-Patchwork-Id: 184862 Message-Id: <19544660.rkmkao6voe@polaris> To: Ulrich Weigand Cc: gcc-patches@gcc.gnu.org, bernds@codesourcery.com Date: Wed, 19 Sep 2012 00:17:52 +0200 > In any case, the change in the condition you noticed was introduced by a > recent patch by Bernd: > http://gcc.gnu.org/ml/gcc-patches/2012-08/msg00171.html > > It seems that we ought to use a similar test to what Bernd introduced in > gen_reload, that is, use the "replaced_subreg" routine on rld[r].in, check > whether the result is a hard register and use its REGNO_REG_CLASS. OK, thanks to both. Revised version attached, OK for mainline after testing? 2012-09-18 Eric Botcazou 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. Index: reload1.c =================================================================== --- reload1.c (revision 191365) +++ reload1.c (working copy) @@ -6352,6 +6352,20 @@ choose_reload_regs_init (struct insn_cha 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 *c 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 *c 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.