This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
inc_for_reload awkwardness
- To: gcc-bugs at gcc dot gnu dot org
- Subject: inc_for_reload awkwardness
- From: Toshiyasu Morita <tm at netcom dot com>
- Date: Fri, 16 Jun 2000 20:43:21 -0700 (PDT)
version: CVS
host: i386-linux
target: sh-elf
I'm noticing GCC generate lots of icky code like this:
3393:./layer3.i **** struct newhuff *h = ht+gr_info->table_select[i];
8816 1750 0E52 mov.l @(56,r0),r2 <- here
8819 1752 1C10 mov.l r1,@(48,r0)
8822 1754 0472 add #4,r2 <- here
8823 1756 90D1 mov.l .L771,r1
8824 1758 2E10 mov.l r2,@(56,r0)
8825 175a FC72 add #-4,r2 <- here
3394:./layer3.i ****
3395:./layer3.i **** for(;lp;lp--,mc--) {
8828 175c 0C57 mov.l @(48,r0),r7
8831 175e 266D mov.l @r2+,r13 <- here
8834 1760 7827 tst r7,r7
8837 1762 084D shll2 r13
8838 1764 DC3D add r13,r13
8841 1766 028F bf.s .L668
8842 1768 1C3D add r1,r13
8843 176a E8A0 bra .L813
8844 176c 40E0 mov #64,r0
The previous code is fairly pessimal, and I see it generated at least 13 times in
the ISO MPEG layer 3 audio decoder.
Preferably we'd want the following sequence:
mov.l @(56,r0),r2
mov.l @r2+,r13
mov.l r2,@(56,r0)
...which is two insns shorter.
The culprit appears to be a combination of emit_input_reload_insns and
inc_for_reload. I see the following code:
/* Auto-increment addresses must be reloaded in a special way. */
if (rl->out && ! rl->out_reg)
{
/* We are not going to bother supporting the case where a
incremented register can't be copied directly from
OLDEQUIV since this seems highly unlikely. */
if (rl->secondary_in_reload >= 0)
abort ();
if (reload_inherited[j])
oldequiv = reloadreg;
old = XEXP (rl->in_reg, 0);
if (optimize && GET_CODE (oldequiv) == REG
&& REGNO (oldequiv) < FIRST_PSEUDO_REGISTER
&& spill_reg_store[REGNO (oldequiv)]
&& GET_CODE (old) == REG
&& (dead_or_set_p (insn,
spill_reg_stored_to[REGNO (oldequiv)])
|| rtx_equal_p (spill_reg_stored_to[REGNO (oldequiv)],
old)))
delete_output_reload (insn, j, REGNO (oldequiv));
/* Prevent normal processing of this reload. */
special = 1;
/* Output a special code sequence for this case. */
new_spill_reg_store[REGNO (reloadreg)]
= inc_for_reload (reloadreg, oldequiv, rl->out,
rl->inc);
...
static rtx
inc_for_reload (reloadreg, in, value, inc_amount)
rtx reloadreg;
rtx in, value;
int inc_amount;
{
...
/* If couldn't do the increment directly, must increment in RELOADREG.
The way we do this depends on whether this is pre- or post-increment.
For pre-increment, copy INCLOC to the reload register, increment it
there, then save back. */
if (! post)
{
if (in != reloadreg)
emit_insn (gen_move_insn (reloadreg, real_in));
emit_insn (gen_add2_insn (reloadreg, inc));
store = emit_insn (gen_move_insn (incloc, reloadreg));
}
else
{
/* Postincrement.
Because this might be a jump insn or a compare, and because RELOADREG
may not be available after the insn in an input reload, we must do
the incrementation before the insn being reloaded for.
We have already copied IN to RELOADREG. Increment the copy in
RELOADREG, save that back, then decrement RELOADREG so it has
the original value. */
emit_insn (gen_add2_insn (reloadreg, inc));
store = emit_insn (gen_move_insn (incloc, reloadreg));
emit_insn (gen_add2_insn (reloadreg, GEN_INT (-inc_amount)));
}
...
}
This seems excessively harsh because a straight post-inc load from memory
doesn't require the extra code sequence.
Shouldn't delete_output_reload/inc_for_reload only be called if the insn requires
it, e.g. JUMP_INSN, CALL_INSN, COMPARE, or REGNO(SET_DEST(insn)) ==
REGNO (XEXP (SET_SRC (insn), 0))?
Or am I missing something?
Toshi