This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Frame pointer adjustment in eliminate_regs_in_insn
- From: Ulrich Weigand <weigand at immd1 dot informatik dot uni-erlangen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: uweigand at de dot ibm dot com, hpenner at de dot ibm dot com
- Date: Tue, 8 Jan 2002 14:21:37 +0100 (MET)
- Subject: [PATCH] Frame pointer adjustment in eliminate_regs_in_insn
Hello,
the routine eliminate_regs_in_insn contains code to recognize
frame pointer adjustments (setting the frame pointer to the
hardware frame pointer plus a constant), and treats this situation
in a special way.
However, the code that recognizes this situation assumes that
the adjustment is done either in a single or in two insns.
Unfortunately, on s390 it can happen (with -O0) that *three*
insns are generated:
(set (temp) (hardware-frame-pointer))
(set (temp) (plus (temp) (constant))
(set (frame-pointer) (temp))
This caused eliminate_regs_in_insn to simply ignore these insns,
leading to incorrect code.
The patch below generalizes the code in eliminate_regs_in_insn to
recognize the three-insn case as well.
OK to apply?
Bye,
Ulrich
2002-01-08 Ulrich Weigand <uweigand@de.ibm.com>
* reload1.c (eliminate_regs_in_insn): Recognize frame pointer
adjustments even if they are implemented by more than two insns.
Index: gcc/reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.318
diff -c -p -r1.318 reload1.c
*** reload1.c 2001/12/29 21:35:01 1.318
--- reload1.c 2002/01/08 12:55:24
*************** eliminate_regs_in_insn (insn, replace)
*** 2932,2969 ****
if (ep->from == FRAME_POINTER_REGNUM
&& ep->to == HARD_FRAME_POINTER_REGNUM)
{
! rtx src = SET_SRC (old_set);
! int offset = 0, ok = 0;
! rtx prev_insn, prev_set;
! if (src == ep->to_rtx)
! offset = 0, ok = 1;
! else if (GET_CODE (src) == PLUS
! && GET_CODE (XEXP (src, 0)) == CONST_INT
! && XEXP (src, 1) == ep->to_rtx)
! offset = INTVAL (XEXP (src, 0)), ok = 1;
! else if (GET_CODE (src) == PLUS
! && GET_CODE (XEXP (src, 1)) == CONST_INT
! && XEXP (src, 0) == ep->to_rtx)
! offset = INTVAL (XEXP (src, 1)), ok = 1;
! else if ((prev_insn = prev_nonnote_insn (insn)) != 0
! && (prev_set = single_set (prev_insn)) != 0
! && rtx_equal_p (SET_DEST (prev_set), src))
{
! src = SET_SRC (prev_set);
! if (src == ep->to_rtx)
! offset = 0, ok = 1;
! else if (GET_CODE (src) == PLUS
! && GET_CODE (XEXP (src, 0)) == CONST_INT
! && XEXP (src, 1) == ep->to_rtx)
! offset = INTVAL (XEXP (src, 0)), ok = 1;
! else if (GET_CODE (src) == PLUS
! && GET_CODE (XEXP (src, 1)) == CONST_INT
! && XEXP (src, 0) == ep->to_rtx)
! offset = INTVAL (XEXP (src, 1)), ok = 1;
}
! if (ok)
{
rtx src
= plus_constant (ep->to_rtx, offset - ep->offset);
--- 2932,2969 ----
if (ep->from == FRAME_POINTER_REGNUM
&& ep->to == HARD_FRAME_POINTER_REGNUM)
{
! rtx base = SET_SRC (old_set);
! rtx base_insn = insn;
! int offset = 0;
! while (base != ep->to_rtx)
{
! rtx prev_insn, prev_set;
!
! if (GET_CODE (base) == PLUS
! && GET_CODE (XEXP (base, 0)) == CONST_INT)
! {
! offset += INTVAL (XEXP (base, 0));
! base = XEXP (base, 1);
! }
! else if (GET_CODE (base) == PLUS
! && GET_CODE (XEXP (base, 1)) == CONST_INT)
! {
! offset += INTVAL (XEXP (base, 1));
! base = XEXP (base, 0);
! }
! else if ((prev_insn = prev_nonnote_insn (base_insn)) != 0
! && (prev_set = single_set (prev_insn)) != 0
! && rtx_equal_p (SET_DEST (prev_set), base))
! {
! base = SET_SRC (prev_set);
! base_insn = prev_insn;
! }
! else
! break;
}
! if (base == ep->to_rtx)
{
rtx src
= plus_constant (ep->to_rtx, offset - ep->offset);
--
Dr. Ulrich Weigand
weigand@informatik.uni-erlangen.de