[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