This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
dead stores bugfix
- To: egcs-patches at cygnus dot com
- Subject: dead stores bugfix
- From: Jeffrey A Law <law at cygnus dot com>
- Date: Wed, 20 Jan 1999 02:57:57 -0700
- Reply-To: law at cygnus dot com
Ho hum. Flow and beyond have to deal with autoinc addresses, when when
performing dead store elimination kills any stores we're tracking that
use the autoinc'd register for an address.
This should fix the PA bootstrap problem reported this afternoon.
* flow.c (invalidate_from_autoinc): New function.
(mark_set_1, mark_used_regs): Use it.
Index: flow.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/flow.c,v
retrieving revision 1.97
diff -c -3 -p -r1.97 flow.c
*** flow.c 1999/01/19 09:39:37 1.97
--- flow.c 1999/01/20 09:59:05
*************** static void count_reg_sets_1 PROTO ((rt
*** 295,300 ****
--- 295,301 ----
static void count_reg_sets PROTO ((rtx));
static void count_reg_references PROTO ((rtx));
static void notice_stack_pointer_modification PROTO ((rtx, rtx));
+ static void invalidate_mems_from_autoinc PROTO ((rtx));
/* Find basic blocks of the current function.
F is the first insn of the function and NREGS the number of register numbers
*************** regno_clobbered_at_setjmp (regno)
*** 2225,2230 ****
--- 2226,2264 ----
&& 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);
+ }
+ }
+ }
+ }
+
/* Process the registers that are set within X.
Their bits are set to 1 in the regset DEAD,
because they are dead prior to this insn.
*************** mark_set_1 (needed, dead, x, insn, signi
*** 2327,2333 ****
temp = XEXP (temp, 1);
}
}
!
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
--- 2361,2373 ----
temp = XEXP (temp, 1);
}
}
!
! /* 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
*************** mark_used_regs (needed, live, x, final,
*** 2749,2754 ****
--- 2789,2800 ----
temp = XEXP (temp, 1);
}
}
+
+ /* 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)