This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: regmove question
- To: law at cygnus dot com
- Subject: Re: regmove question
- From: Joern Rennecke <amylaar at cygnus dot co dot uk>
- Date: Thu, 2 Sep 1999 20:25:43 +0100 (BST)
- Cc: amylaar at cygnus dot co dot uk, gcc-bugs at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
> I believe that leaving a (now bogus) death node for reg24 on insn 14
> causes regmove to think it can clobber reg24 at insn 24.
Yes, you're right - the RTX_UNCHANGING_P bit in SRC is a red herring,
it's really the RTX_UNCHANGING_P in the other source register that
confuses regmove the most here.
The code that checks if it would be OK thinks that it's all right when
stable_but_for_p returns true. However, although register 24 is
unchanging, it's still a register which would need updating of REG_DEAD /
REG_UNUSED notes. If we wanted to do a full data flow analysis, there
would be no need for the stable_but_for_p call in the first place,
so I think it's best just to punt in this case.
Thu Sep 2 20:08:23 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
* regmove.c (fixup_match_1): Don't move INSN in front of P if
it would end up in the shadow of a live flags regsiter.
(stable_but_for_p): Renamed to:
(stable_and_no_regs_but_for_p). Reject unchanging registers too.
Changed all callers.
Index: regmove.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/regmove.c,v
retrieving revision 1.62
diff -p -r1.62 regmove.c
*** regmove.c 1999/08/31 19:39:06 1.62
--- regmove.c 1999/09/02 18:54:19
*************** static int find_matches PROTO((rtx, stru
*** 63,69 ****
static int fixup_match_1 PROTO((rtx, rtx, rtx, rtx, rtx, int, int, int, FILE *))
;
static int reg_is_remote_constant_p PROTO((rtx, rtx, rtx));
! static int stable_but_for_p PROTO((rtx, rtx, rtx));
static int regclass_compatible_p PROTO((int, int));
static int loop_depth;
--- 63,69 ----
static int fixup_match_1 PROTO((rtx, rtx, rtx, rtx, rtx, int, int, int, FILE *))
;
static int reg_is_remote_constant_p PROTO((rtx, rtx, rtx));
! static int stable_and_no_regs_but_for_p PROTO((rtx, rtx, rtx));
static int regclass_compatible_p PROTO((int, int));
static int loop_depth;
*************** fixup_match_1 (insn, set, src, src_subre
*** 1664,1669 ****
--- 1664,1675 ----
rtx src_note = find_reg_note (insn, REG_DEAD, src), dst_note;
int length, s_length, true_loop_depth;
+ /* If SRC is marked as unchanging, we may not change it.
+ ??? Maybe we could get better code by removing the unchanging bit
+ instead, and changing it back if we don't succeed? */
+ if (RTX_UNCHANGING_P (src))
+ return 0;
+
if (! src_note)
{
/* Look for (set (regX) (op regA constX))
*************** fixup_match_1 (insn, set, src, src_subre
*** 1680,1686 ****
&& XEXP (SET_SRC (set), 0) == src
&& GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
insn_const = INTVAL (XEXP (SET_SRC (set), 1));
! else if (! stable_but_for_p (SET_SRC (set), src, dst))
return 0;
else
/* We might find a src_note while scanning. */
--- 1686,1692 ----
&& XEXP (SET_SRC (set), 0) == src
&& GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
insn_const = INTVAL (XEXP (SET_SRC (set), 1));
! else if (! stable_and_no_regs_but_for_p (SET_SRC (set), src, dst))
return 0;
else
/* We might find a src_note while scanning. */
*************** fixup_match_1 (insn, set, src, src_subre
*** 2092,2101 ****
}
! /* return nonzero if X is stable but for mentioning SRC or mentioning /
! changing DST . If in doubt, presume it is unstable. */
static int
! stable_but_for_p (x, src, dst)
rtx x, src, dst;
{
RTX_CODE code = GET_CODE (x);
--- 2108,2123 ----
}
! /* return nonzero if X is stable and mentions no regsiters but for
! mentioning SRC or mentioning / changing DST . If in doubt, presume
! it is unstable.
! The rationale is that we want to check if we can move an insn easily
! while just paying attention to SRC and DST. A register is considered
! stable if it has the RTX_UNCHANGING_P bit set, but that would still
! leave the burden to update REG_DEAD / REG_UNUSED notes, so we don't
! want any registers but SRC and DST. */
static int
! stable_and_no_regs_but_for_p (x, src, dst)
rtx x, src, dst;
{
RTX_CODE code = GET_CODE (x);
*************** stable_but_for_p (x, src, dst)
*** 2106,2118 ****
int i;
const char *fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
! if (fmt[i] == 'e' && ! stable_but_for_p (XEXP (x, i), src, dst))
return 0;
return 1;
}
case 'o':
! if (x == src || x == dst)
! return 1;
/* fall through */
default:
return ! rtx_unstable_p (x);
--- 2128,2146 ----
int i;
const char *fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
! if (fmt[i] == 'e'
! && ! stable_and_no_regs_but_for_p (XEXP (x, i), src, dst))
return 0;
return 1;
}
case 'o':
! if (code == REG)
! return x == src || x == dst;
! /* If this is a MEM, look inside - there might be a register hidden in
! the address of an unchanging MEM. */
! if (code == MEM
! && ! stable_and_no_regs_but_for_p (XEXP (x, 0), src, dst))
! return 0;
/* fall through */
default:
return ! rtx_unstable_p (x);