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: Tue, 23 Feb 1999 11:16:13 +1300 (NZDT)
- Cc: Michael Hayes <m dot hayes at elec dot canterbury dot ac dot nz>, egcs-patches at cygnus dot com
- References: <"14031.18328.331705.587308"@ongaonga.elec.canterbury.ac.nz><8927.919672143@hurl.cygnus.com>
Jeffrey A Law writes:
> mark_used_regs can be called multiple times for the same insn, which could
> lead to multiple REG_INC notes added to the instruction.
> Which can lead to multiple calls to propagate block for each block. Then
> propagate_block calls mark_used_regs, which causes us to add the REG_INC
> note more than once to the same insn.
Yes, I forgot about this. I think you meant multiple REG_INC notes
per register in the insn.
> Seems to me we could deal handle adding the REG_INC notes in the same
> loop that we remove them in reload. ie, first we strip any REG_INC notes
> off the insn.
>
> Then we search the insn for any autoinc expressions and if we find one,
> we add the appropriate notes.
Yes, this is probably a better approach although it is yet another pass.
> Handling it in reload is also a little cleaner -- as far as the rest of
> the compiler is concerned reload kept the REG_INC notes accurate.
In the interim, here's a patch to flow.c so that it is not dependent
upon the accuracy of the REG_INC notes. This fixes the dead store bug.
Michael.
Tue Feb 23 11:07:27 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
* flow.c (auto_inc_p): New function.
(invalidate_mems_from_autoinc): Change argument from an insn
to a mem rtx. Use this instead of scanning insn notes for
a REG_INC note. All callers changed.
(mark_set_1): Move call to invalidate_mems_from_autoinc into
mark_used_regs.
(mark_used_regs): Only call invalidate_mems_from_autoinc if
auto_inc_p true.
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/22 22:05:33
*************** 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));
*************** regno_clobbered_at_setjmp (regno)
*** 2226,2261 ****
&& REGNO_REG_SET_P (regs_live_at_setjmp, regno));
}
! /* INSN references memory, possibly using autoincrement addressing modes.
Find any entries on the mem_set_list that need to be invalidated due
to an address change. */
static void
! invalidate_mems_from_autoinc (insn)
! rtx insn;
{
! rtx note = REG_NOTES (insn);
! for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
{
! if (REG_NOTE_KIND (note) == REG_INC)
! {
! rtx temp = mem_set_list;
! rtx prev = NULL_RTX;
!
! while (temp)
! {
! if (reg_overlap_mentioned_p (XEXP (note, 0), XEXP (temp, 0)))
! {
! /* Splice temp out of list. */
! if (prev)
! XEXP (prev, 1) = XEXP (temp, 1);
! else
! mem_set_list = XEXP (temp, 1);
! }
! else
! prev = temp;
! temp = XEXP (temp, 1);
! }
}
}
}
--- 2227,2256 ----
&& REGNO_REG_SET_P (regs_live_at_setjmp, regno));
}
! /* X references memory using autoincrement addressing modes.
Find any entries on the mem_set_list that need to be invalidated due
to an address change. */
static void
! invalidate_mems_from_autoinc (x)
! rtx x;
{
! rtx temp = mem_set_list;
! rtx prev = NULL_RTX;
! rtx reg = XEXP (XEXP (x, 0), 0);
!
! while (temp)
{
! if (reg_overlap_mentioned_p (reg, XEXP (temp, 0)))
! {
! /* Splice temp out of list. */
! if (prev)
! XEXP (prev, 1) = XEXP (temp, 1);
! else
! mem_set_list = XEXP (temp, 1);
}
+ else
+ prev = temp;
+ temp = XEXP (temp, 1);
}
}
*************** 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
--- 2357,2362 ----
*************** mark_set_1 (needed, dead, x, insn, signi
*** 2531,2536 ****
--- 2520,2550 ----
#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
--- 2804,2818 ----
}
}
#ifdef AUTO_INC_DEC
+ if (auto_inc_p (x))
+ {
+ /* 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 (x);
+ }
+
if (final)
find_auto_inc (needed, x, insn);
#endif
*************** mark_used_regs (needed, live, x, final,
*** 2978,2983 ****
--- 2994,3007 ----
if (GET_CODE (testreg) == MEM)
{
#ifdef AUTO_INC_DEC
+ if (auto_inc_p (testreg))
+ {
+ /* 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