This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Avoid redundant add in dreferencing local objects on i386
- To: Richard Henderson <rth at cygnus dot com>
- Subject: Re: Avoid redundant add in dreferencing local objects on i386
- From: Bernd Schmidt <bernds at balti dot cygnus dot co dot uk>
- Date: Mon, 6 Mar 2000 12:52:35 +0000 (GMT)
- cc: Jan Hubicka <hubicka at atrey dot karlin dot mff dot cuni dot cz>, egcs-patches at egcs dot cygnus dot com
On Mon, 28 Feb 2000, Richard Henderson wrote:
> On Mon, Feb 28, 2000 at 02:48:12PM +0100, Jan Hubicka wrote:
> > * i386.md: New peep2s to avoid redundant add in frame pointer
> > dereferencing.
>
> I'd rather fix this in reload. It's been annoying me since
> Bernd reorganized elimination.
Like this?
Bernd
* reload1.c (eliminate_regs_in_insn): Handle additions of eliminable
register and a constant specially.
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/reload1.c,v
retrieving revision 1.202
diff -c -p -r1.202 reload1.c
*** reload1.c 2000/03/03 14:20:28 1.202
--- reload1.c 2000/03/06 12:49:39
*************** eliminate_regs_in_insn (insn, replace)
*** 2903,2943 ****
val = 1;
goto done;
}
! /* Check for (set (reg) (plus (reg from) (offset))) where the offset
! in the insn is the negative of the offset in FROM. Substitute
! (set (reg) (reg to)) for the insn and change its code.
!
! We have to do this here, rather than in eliminate_regs, so that we can
! change the insn code. */
!
! if (GET_CODE (SET_SRC (old_set)) == PLUS
! && GET_CODE (XEXP (SET_SRC (old_set), 0)) == REG
! && GET_CODE (XEXP (SET_SRC (old_set), 1)) == CONST_INT)
! for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS];
! ep++)
! if (ep->from_rtx == XEXP (SET_SRC (old_set), 0)
! && ep->can_eliminate)
! {
! /* We must stop at the first elimination that will be used.
! If this one would replace the PLUS with a REG, do it
! now. Otherwise, quit the loop and let eliminate_regs
! do its normal replacement. */
! if (ep->offset == - INTVAL (XEXP (SET_SRC (old_set), 1)))
! {
! /* We assume here that we don't need a PARALLEL of
! any CLOBBERs for this assignment. There's not
! much we can do if we do need it. */
! PATTERN (insn) = gen_rtx_SET (VOIDmode,
! SET_DEST (old_set),
! ep->to_rtx);
! INSN_CODE (insn) = -1;
! val = 1;
! goto done;
! }
! break;
! }
}
/* Determine the effects of this insn on elimination offsets. */
--- 2903,2959 ----
val = 1;
goto done;
}
+ }
! /* We allow one special case which happens to work on all machines we
! currently support: a single set with the source being a PLUS of an
! eliminable register and a constant. */
! if (old_set
! && GET_CODE (SET_SRC (old_set)) == PLUS
! && GET_CODE (XEXP (SET_SRC (old_set), 0)) == REG
! && GET_CODE (XEXP (SET_SRC (old_set), 1)) == CONST_INT
! && REGNO (XEXP (SET_SRC (old_set), 0)) < FIRST_PSEUDO_REGISTER)
! {
! rtx reg = XEXP (SET_SRC (old_set), 0);
! int offset = INTVAL (XEXP (SET_SRC (old_set), 1));
! for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
! if (ep->from_rtx == reg && ep->can_eliminate)
! {
! offset += ep->offset;
!
! if (offset == 0)
! {
! /* We assume here that we don't need a PARALLEL of
! any CLOBBERs for this assignment. There's not
! much we can do if we do need it. */
! PATTERN (insn) = gen_rtx_SET (VOIDmode,
! SET_DEST (old_set),
! ep->to_rtx);
! INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
! if (INSN_CODE (insn) < 0)
! abort ();
! }
! else
! {
! new_body = old_body;
! if (! replace)
! {
! new_body = copy_insn (old_body);
! if (REG_NOTES (insn))
! REG_NOTES (insn) = copy_insn_1 (REG_NOTES (insn));
! }
! PATTERN (insn) = new_body;
! old_set = single_set (insn);
!
! XEXP (SET_SRC (old_set), 0) = ep->to_rtx;
! XEXP (SET_SRC (old_set), 1) = GEN_INT (offset);
! }
! val = 1;
! /* This can't have an effect on elimination offsets, so skip right
! to the end. */
! goto done;
! }
}
/* Determine the effects of this insn on elimination offsets. */