This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

inc_for_reload awkwardness


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]