This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: choose_reload_regs V2.0


On Tue, 29 Aug 2000, Alan Goluban wrote:

[snip lots of problem description]

Disclaimer: I can't read mips assembly.

>    * reload1.c (choose_reload_regs): Test for clobbering inherited reload
> 	registers.

I don't think this test should be needed.  If it's a clobbered operand, we
should have appropriate earlyclobber information.  If there's a hard
register that's explicitly clobbered in the insn, we have other mechanisms
to prevent using it for inheritance.  (Although, now that I think of it,
that may have been broken in 2.95.2.  Can you reproduce your problems with
current mainline CVS?  This could be why the second testcase is failing.)

I think this problem is simply a case of a missing earlyclobber in mips.md.
Could someone who is familiar with that machine description look at the first
of the two patches below?

>       if (equiv != 0 && regno_clobbered_p (regno, insn))
> 
> This checks for clobbering only the first hard register (high part of the
> constant). In this case, it is $2 on MIPS and %o0 on SPARC. Low part of the
> constant is in $3 on MIPS and %o1 on SPARC, and those registers are clobbered
> by the respective asm statement. So there is a problem.

That looks like it could indeed be a problem.  I'd prefer to fix it by
adding a mode argument to regno_clobbered_p, as in the second patch below.


Bernd

Patch #1:
	* mips.md (adddi3_internal_1): Make operand 3 an earlyclobber.

--- gcc-2.95.2/gcc/config/mips/mips.md~	Tue Sep  5 17:28:42 2000
+++ gcc-2.95.2/gcc/config/mips/mips.md	Tue Sep  5 17:29:49 2000
@@ -702,7 +702,7 @@
   [(set (match_operand:DI 0 "register_operand" "=d,&d")
 	(plus:DI (match_operand:DI 1 "register_operand" "0,d")
 		 (match_operand:DI 2 "register_operand" "d,d")))
-   (clobber (match_operand:SI 3 "register_operand" "=d,d"))]
+   (clobber (match_operand:SI 3 "register_operand" "=&d,&d"))]
   "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16"
   "*
 {

Patch #2:
	* reload.c (regno_clobbered_p): Accept new arg, MODE, and use it
	to handle multiword modes correctly.  All callers and the declaration
	changed.

diff -du gcc-2.95.2/gcc/reload.c new/gcc/reload.c
--- gcc-2.95.2/gcc/reload.c	Wed Jul 14 23:29:48 1999
+++ new/gcc/reload.c	Tue Sep  5 17:30:56 2000
@@ -4666,7 +4666,7 @@
 
       else if (regno < FIRST_PSEUDO_REGISTER
 	       && REGNO_MODE_OK_FOR_BASE_P (regno, mode)
-	       && ! regno_clobbered_p (regno, this_insn))
+	       && ! regno_clobbered_p (regno, this_insn, mode))
 	return 0;
 
       /* If we do not have one of the cases above, we must do the reload.  */
@@ -5500,7 +5500,7 @@
 	   in this insn, reload it into some other register to be safe.
 	   The CLOBBER is supposed to make the register unavailable
 	   from before this insn to after it.  */
-	if (regno_clobbered_p (regno, this_insn))
+	if (regno_clobbered_p (regno, this_insn, GET_MODE (x)))
 	  {
 	    push_reload (x, NULL_RTX, loc, NULL_PTR,
 			 (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
@@ -6610,16 +6610,24 @@
   return 0;
 }
 
-/* Return 1 if register REGNO is the subject of a clobber in insn INSN.  */
+/* Return 1 if register REGNO is the subject of a clobber in insn INSN.  
+   MODE is the mode of the register.  */
 
 int
-regno_clobbered_p (regno, insn)
+regno_clobbered_p (regno, insn, mode)
      int regno;
      rtx insn;
+     enum machine_mode mode;
 {
+  int nregs = HARD_REGNO_NREGS (regno, mode);
+  int endregno = regno + nregs;
   if (GET_CODE (PATTERN (insn)) == CLOBBER
       && GET_CODE (XEXP (PATTERN (insn), 0)) == REG)
-    return REGNO (XEXP (PATTERN (insn), 0)) == regno;
+    {
+      int test = REGNO (XEXP (PATTERN (insn), 0));
+
+      return regno >= test && test < endregno;
+    }
 
   if (GET_CODE (PATTERN (insn)) == PARALLEL)
     {
@@ -6628,9 +6636,13 @@
       for (; i >= 0; i--)
 	{
 	  rtx elt = XVECEXP (PATTERN (insn), 0, i);
-	  if (GET_CODE (elt) == CLOBBER && GET_CODE (XEXP (elt, 0)) == REG
-	      && REGNO (XEXP (elt, 0)) == regno)
-	    return 1;
+	  if (GET_CODE (elt) == CLOBBER && GET_CODE (XEXP (elt, 0)) == REG)
+	    {
+	      int test = REGNO (XEXP (elt, 0));
+	      
+	      if (regno >= test && test < endregno)
+		return 1;
+	    }
 	}
     }
 
diff -du gcc-2.95.2/gcc/reload.h new/gcc/reload.h
--- gcc-2.95.2/gcc/reload.h	Wed Dec 16 20:57:55 1998
+++ new/gcc/reload.h	Tue Sep  5 17:30:56 2000
@@ -296,7 +296,7 @@
 				 int, enum machine_mode));
 
 /* Return 1 if register REGNO is the subject of a clobber in insn INSN.  */
-extern int regno_clobbered_p PROTO((int, rtx));
+extern int regno_clobbered_p PROTO((int, rtx, enum machine_mode));
 
 /* Functions in reload1.c:  */
 
diff -du gcc-2.95.2/gcc/reload1.c new/gcc/reload1.c
--- gcc-2.95.2/gcc/reload1.c	Wed Jul  7 02:05:39 1999
+++ new/gcc/reload1.c	Tue Sep  5 17:30:56 2000
@@ -6097,7 +6100,7 @@
 		 In particular, we then can't use EQUIV for a
 		 RELOAD_FOR_OUTPUT_ADDRESS reload.  */
 
-	      if (equiv != 0 && regno_clobbered_p (regno, insn))
+	      if (equiv != 0 && regno_clobbered_p (regno, insn, reload_mode[r]))
 		{
 		  switch (reload_when_needed[r])
 		    {
@@ -7280,7 +7283,7 @@
 		  || !(set = single_set (insn))
 		  || rtx_equal_p (old, SET_DEST (set))
 		  || !reg_mentioned_p (old, SET_SRC (set))
-		  || !regno_clobbered_p (REGNO (old), insn))
+		  || !regno_clobbered_p (REGNO (old), insn, reload_mode[j]))
 		gen_reload (old, reloadreg, reload_opnum[j],
 			    reload_when_needed[j]);
 	    }



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]