This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: REG_INC notes going AWOL during reload
- To: law at cygnus dot com
- Subject: Re: REG_INC notes going AWOL during reload
- From: Michael Hayes <m dot hayes at elec dot canterbury dot ac dot nz>
- Date: Sun, 21 Feb 1999 12:41:29 +1300 (NZDT)
- Cc: Michael Hayes <m dot hayes at elec dot canterbury dot ac dot nz>, egcs-patches at cygnus dot com
- References: <"14030.35768.368.145312"@ongaonga.elec.canterbury.ac.nz><4691.919542420@hurl.cygnus.com>
Jeffrey A Law writes:
> More correctly, I think we need to move the REG_INC note to the insn which
> has the address side effect.
>
> Alternately we could strip away all the REG_INC notes and rebuild them.
The latter seems easier to implement. Here's a patch to do that.
Could someone with access to a machine with autoincrement addressing
modes please perform a bootstrap test with this patch?
Michael.
Sun Feb 21 12:32:48 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
* reload1.c (reload): Strip REG_INC notes.
* flow.c (auto_inc_p): New function.
(mark_set_1): Remove call to invalidate_mems_from_autoinc.
(mark_used_regs): Restore REG_INC notes if reload_completed.
Move calls to invalidate_mems_from_autoinc until after REG_INC
notes restored.
Index: reload1.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/reload1.c,v
retrieving revision 1.129
diff -c -3 -p -r1.129 reload1.c
*** reload1.c 1999/02/10 09:13:41 1.129
--- reload1.c 1999/02/20 23:31:28
*************** reload (first, global, dumpfile)
*** 1124,1134 ****
which are only valid during and after reload. */
reload_completed = 1;
! /* Make a pass over all the insns and delete all USEs which we inserted
! only to tag a REG_EQUAL note on them. Remove all REG_DEAD and REG_UNUSED
! notes. Delete all CLOBBER insns and simplify (subreg (reg)) operands.
! Also remove all REG_RETVAL and REG_LIBCALL notes since they are no longer
! useful or accurate. */
for (insn = first; insn; insn = NEXT_INSN (insn))
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
--- 1124,1135 ----
which are only valid during and after reload. */
reload_completed = 1;
! /* Make a pass over all the insns and delete all USEs which we
! inserted only to tag a REG_EQUAL note on them. Remove all
! REG_INC, REG_DEAD, and REG_UNUSED notes. Delete all CLOBBER
! insns and simplify (subreg (reg)) operands. Also remove all
! REG_RETVAL and REG_LIBCALL notes since they are no longer useful
! or accurate. */
for (insn = first; insn; insn = NEXT_INSN (insn))
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
*************** reload (first, global, dumpfile)
*** 1150,1155 ****
--- 1151,1157 ----
{
if (REG_NOTE_KIND (*pnote) == REG_DEAD
|| REG_NOTE_KIND (*pnote) == REG_UNUSED
+ || REG_NOTE_KIND (*pnote) == REG_INC
|| REG_NOTE_KIND (*pnote) == REG_RETVAL
|| REG_NOTE_KIND (*pnote) == REG_LIBCALL)
*pnote = XEXP (*pnote, 1);
Index: flow.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/flow.c,v
retrieving revision 1.99
diff -c -3 -p -r1.99 flow.c
*** flow.c 1999/01/27 01:42:19 1.99
--- flow.c 1999/02/20 23:31:30
*************** static void mark_set_regs PROTO((regset
*** 278,283 ****
--- 278,284 ----
static void mark_set_1 PROTO((regset, regset, rtx,
rtx, regset));
#ifdef AUTO_INC_DEC
+ static int auto_inc_p PROTO((rtx));
static void find_auto_inc PROTO((regset, rtx, rtx));
static int try_pre_increment_1 PROTO((rtx));
static int try_pre_increment PROTO((rtx, rtx, HOST_WIDE_INT));
*************** mark_set_1 (needed, dead, x, insn, signi
*** 2362,2373 ****
}
}
- /* If the memory reference had embedded side effects (autoincrement
- address modes. Then we may need to kill some entries on the
- memory set list. */
- if (insn && GET_CODE (reg) == MEM)
- invalidate_mems_from_autoinc (insn);
-
if (GET_CODE (reg) == MEM && ! side_effects_p (reg)
/* There are no REG_INC notes for SP, so we can't assume we'll see
everything that invalidates it. To be safe, don't eliminate any
--- 2363,2368 ----
*************** mark_set_1 (needed, dead, x, insn, signi
*** 2531,2536 ****
--- 2526,2556 ----
#ifdef AUTO_INC_DEC
+ /* Return 1 if X is a MEM with an autoincrement side effect
+ and the register is not the stack pointer. */
+ static int
+ auto_inc_p (x)
+ rtx x;
+ {
+ if (GET_CODE (x) != MEM)
+ abort ();
+ x = XEXP (x, 0);
+ switch (GET_CODE (x))
+ {
+ case PRE_INC:
+ case POST_INC:
+ case PRE_DEC:
+ case POST_DEC:
+
+ /* There are no REG_INC notes for SP. */
+ if (XEXP (x, 0) != stack_pointer_rtx)
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+ }
+
/* X is a MEM found in INSN. See if we can convert it into an auto-increment
reference. */
*************** mark_used_regs (needed, live, x, final,
*** 2790,2802 ****
}
}
- /* If the memory reference had embedded side effects (autoincrement
- address modes. Then we may need to kill some entries on the
- memory set list. */
- if (insn)
- invalidate_mems_from_autoinc (insn);
-
#ifdef AUTO_INC_DEC
if (final)
find_auto_inc (needed, x, insn);
#endif
--- 2810,2830 ----
}
}
#ifdef AUTO_INC_DEC
+ if (auto_inc_p (x))
+ {
+ /* Restore REG_INC notes stripped by reload. */
+ if (! final && reload_completed)
+ REG_NOTES (insn)
+ = gen_rtx (EXPR_LIST, REG_INC, XEXP (XEXP (x, 0), 0),
+ REG_NOTES (insn));
+
+ /* If the memory reference had embedded side effects
+ (autoincrement address modes. Then we may need to kill
+ some entries on the memory set list. */
+ invalidate_mems_from_autoinc (insn);
+ }
+
if (final)
find_auto_inc (needed, x, insn);
#endif
*************** mark_used_regs (needed, live, x, final,
*** 2978,2983 ****
--- 3006,3025 ----
if (GET_CODE (testreg) == MEM)
{
#ifdef AUTO_INC_DEC
+ if (auto_inc_p (testreg))
+ {
+ /* Restore REG_INC notes stripped by reload. */
+ if (! final && reload_completed)
+ REG_NOTES (insn)
+ = gen_rtx (EXPR_LIST, REG_INC, XEXP (XEXP (testreg, 0), 0),
+ REG_NOTES (insn));
+
+ /* If the memory reference had embedded side effects
+ (autoincrement address modes. Then we may need to kill
+ some entries on the memory set list. */
+ invalidate_mems_from_autoinc (insn);
+ }
+
if (final)
find_auto_inc (needed, testreg, insn);
#endif