diff options
author | krebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-01-10 16:46:26 +0000 |
---|---|---|
committer | krebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-01-10 16:46:26 +0000 |
commit | cd6659e35b84844107b596f98d8c18a654e82966 (patch) | |
tree | c912dd79c520074e69014d7ec858c8c2b20c84cf /gcc/reload.c | |
parent | 6d6adc8244cb54e2f54cca3dee7b30ac78d41800 (diff) | |
download | gcc-cd6659e35b84844107b596f98d8c18a654e82966.tar.gz |
2008-01-10 Andreas Krebbel <krebbel1@de.ibm.com>
PR middle-end/34641
* reload.c (push_reload): Add assertions. All constants from
reg_equiv_constant should have been used for replacing the respective
pseudo earlier.
(find_reloads_address): Invoke find_reloads_address_part for
constant taken from the reg_equiv_constant array.
2008-01-10 Andreas Krebbel <krebbel1@de.ibm.com>
PR middle-end/34641
* g++.dg/torture/pr34641.C: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@131445 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reload.c')
-rw-r--r-- | gcc/reload.c | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/gcc/reload.c b/gcc/reload.c index 8f84546fbb2..5a0da1d5989 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -922,29 +922,33 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc, if (outmode == VOIDmode && out != 0) outmode = GET_MODE (out); - /* If IN is a pseudo register everywhere-equivalent to a constant, and - it is not in a hard register, reload straight from the constant, - since we want to get rid of such pseudo registers. - Often this is done earlier, but not always in find_reloads_address. */ + /* If find_reloads and friends until now missed to replace a pseudo + with a constant of reg_equiv_constant something went wrong + beforehand. + Note that it can't simply be done here if we missed it earlier + since the constant might need to be pushed into the literal pool + and the resulting memref would probably need further + reloading. */ if (in != 0 && REG_P (in)) { int regno = REGNO (in); - if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0 - && reg_equiv_constant[regno] != 0) - in = reg_equiv_constant[regno]; + gcc_assert (regno < FIRST_PSEUDO_REGISTER + || reg_renumber[regno] >= 0 + || reg_equiv_constant[regno] == NULL_RTX); } - /* Likewise for OUT. Of course, OUT will never be equivalent to - an actual constant, but it might be equivalent to a memory location - (in the case of a parameter). */ + /* reg_equiv_constant only contains constants which are obviously + not appropriate as destination. So if we would need to replace + the destination pseudo with a constant we are in real + trouble. */ if (out != 0 && REG_P (out)) { int regno = REGNO (out); - if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0 - && reg_equiv_constant[regno] != 0) - out = reg_equiv_constant[regno]; + gcc_assert (regno < FIRST_PSEUDO_REGISTER + || reg_renumber[regno] >= 0 + || reg_equiv_constant[regno] == NULL_RTX); } /* If we have a read-write operand with an address side-effect, @@ -4772,15 +4776,12 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad, { regno = REGNO (ad); - /* If the register is equivalent to an invariant expression, substitute - the invariant, and eliminate any eliminable register references. */ - tem = reg_equiv_constant[regno]; - if (tem != 0 - && (tem = eliminate_regs (tem, mode, insn)) - && strict_memory_address_p (mode, tem)) + if (reg_equiv_constant[regno] != 0) { - *loc = ad = tem; - return 0; + find_reloads_address_part (reg_equiv_constant[regno], loc, + base_reg_class (mode, MEM, SCRATCH), + GET_MODE (ad), opnum, type, ind_levels); + return 1; } tem = reg_equiv_memory_loc[regno]; |