[PATCH] Re: REG_DEAD/REG_EQUIV problem.
Alan Modra
alan@linuxcare.com.au
Thu Feb 1 01:47:00 GMT 2001
On Thu, 1 Feb 2001, Alan Modra wrote:
> (insn 17 15 21 (set (reg/v:DI 69)
> (mem/u:DI (lo_sum:DI (reg:DI 70)
> (unspec:DI[
> (symbol_ref/v/f:DI ("*L$C0001"))
> ] 0)) 0)) 83 {*pa.md:2368} (insn_list 15 (nil))
> (expr_list:REG_EQUIV (mem/u:DI (lo_sum:DI (reg:DI 70)
> (unspec:DI[
> (symbol_ref/v/f:DI ("*L$C0001"))
> ] 0)) 0)
> (expr_list:REG_DEAD (reg:DI 70)
> (nil))))
Whee, maybe I'll be a gcc hacker one day.
This fixes the problem for me. I've no idea whether it's the ideal
solution - it may well be possible and desirable to prevent these
conflicting notes being issued.
gcc/ChangeLog
* rtlanal.c (reg_death_note_p): New function.
(reg_mentioned_dies): New function.
* rtl.h (reg_mentioned_dies): Declare.
* reload1.c (reload): Don't set reg_equiv_memory_loc for an insn
that references memory via a reg that dies.
Alan Modra
--
Linuxcare. Support for the Revolution.
Index: gcc/reload1.c
===================================================================
RCS file: /home/cvs/parisc/gcc/gcc/reload1.c,v
retrieving revision 1.1.1.4.2.4
diff -u -p -r1.1.1.4.2.4 reload1.c
--- reload1.c 2001/01/29 14:15:52 1.1.1.4.2.4
+++ reload1.c 2001/02/01 09:28:30
@@ -784,6 +784,14 @@ reload (first, global)
{
if (GET_CODE (x) == MEM)
{
+ rtx death = find_reg_note (insn, REG_DEAD, NULL_RTX);
+ if (death)
+ {
+ /* Make sure the MEM doesn't use a reigster
+ that dies in this insn. */
+ if (reg_mentioned_dies (x, death))
+ continue;
+ }
/* If the operand is a PLUS, the MEM may be shared,
so make sure we have an unshared copy here. */
if (GET_CODE (XEXP (x, 0)) == PLUS)
Index: gcc/rtl.h
===================================================================
RCS file: /home/cvs/parisc/gcc/gcc/rtl.h,v
retrieving revision 1.1.1.4.2.2
diff -u -p -r1.1.1.4.2.2 rtl.h
--- rtl.h 2001/01/22 15:55:41 1.1.1.4.2.2
+++ rtl.h 2001/02/01 09:28:40
@@ -1403,6 +1403,7 @@ extern rtx replace_regs PARAMS ((rtx,
extern int computed_jump_p PARAMS ((rtx));
typedef int (*rtx_function) PARAMS ((rtx *, void *));
extern int for_each_rtx PARAMS ((rtx *, rtx_function, void *));
+extern int reg_mentioned_dies PARAMS ((rtx, rtx));
extern rtx regno_use_in PARAMS ((unsigned int, rtx));
extern int auto_inc_p PARAMS ((rtx));
extern void remove_node_from_expr_list PARAMS ((rtx, rtx *));
Index: gcc/rtlanal.c
===================================================================
RCS file: /home/cvs/parisc/gcc/gcc/rtlanal.c,v
retrieving revision 1.1.1.4.2.2
diff -u -p -r1.1.1.4.2.2 rtlanal.c
--- rtlanal.c 2001/01/22 15:55:41 1.1.1.4.2.2
+++ rtlanal.c 2001/02/01 09:28:46
@@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA. */
static void set_of_1 PARAMS ((rtx, rtx, void *));
static void insn_dependent_p_1 PARAMS ((rtx, rtx, void *));
+static int reg_death_note_p PARAMS ((rtx *, void *));
/* Forward declarations */
static int computed_jump_p_1 PARAMS ((rtx));
@@ -2326,6 +2327,34 @@ for_each_rtx (x, f, data)
}
return 0;
+}
+
+/* Predicate function for reg_mentioned_dies. */
+
+static int
+reg_death_note_p (reg, notes)
+ rtx *reg;
+ void *notes;
+{
+ rtx link;
+
+ if (GET_CODE (*reg) != REG)
+ return 0;
+
+ for (link = (rtx) notes; link; link = XEXP (link, 1))
+ if (REG_NOTE_KIND (link) == REG_DEAD && *reg == XEXP (link, 0))
+ return 1;
+ return 0;
+}
+
+/* Return 1 if any register found in INSN has a REG_DEAD note in NOTES. */
+
+int
+reg_mentioned_dies (insn, notes)
+ rtx insn;
+ rtx notes;
+{
+ return for_each_rtx (&insn, reg_death_note_p, notes);
}
/* Searches X for any reference to REGNO, returning the rtx of the
More information about the Gcc-bugs
mailing list