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]
Other format: [Raw text]

reload.c (find_valid_class): Test inner mode as well


This was choosing classes which were not valid for the inner mode.
Tested on i686-pc-linux-gnu.

2004-12-06  DJ Delorie  <dj@redhat.com>

	* reload.c (find_valid_class): Fix logic to test inner mode as well.
	(push_reload): Pass inner mode.

 
Index: reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.259
diff -p -U3 -r1.259 reload.c
--- reload.c	23 Nov 2004 19:55:16 -0000	1.259
+++ reload.c	6 Dec 2004 21:36:46 -0000
@@ -240,7 +240,8 @@ static int push_secondary_reload (int, r
 				  enum machine_mode, enum reload_type,
 				  enum insn_code *);
 #endif
-static enum reg_class find_valid_class (enum machine_mode, int, unsigned int);
+static enum reg_class find_valid_class (enum machine_mode, enum machine_mode,
+					int, unsigned int);
 static int reload_inner_reg_of_subreg (rtx, enum machine_mode, int);
 static void push_replacement (rtx *, int, enum machine_mode);
 static void dup_replacements (rtx *, rtx *);
@@ -659,12 +660,15 @@ clear_secondary_mem (void)
 }
 #endif /* SECONDARY_MEMORY_NEEDED */
 
-/* Find the largest class for which every register number plus N is valid in
-   M1 (if in range) and is cheap to move into REGNO.
-   Abort if no such class exists.  */
+
+/* Find the largest class which has at least one register valid in
+   mode INNER, and which for every such register, that register number
+   plus N is also valid in OUTER (if in range) and is cheap to move
+   into REGNO.  Abort if no such class exists.  */
 
 static enum reg_class
-find_valid_class (enum machine_mode m1 ATTRIBUTE_UNUSED, int n,
+find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED,
+		  enum machine_mode inner ATTRIBUTE_UNUSED, int n,
 		  unsigned int dest_regno ATTRIBUTE_UNUSED)
 {
   int best_cost = -1;
@@ -678,15 +682,22 @@ find_valid_class (enum machine_mode m1 A
   for (class = 1; class < N_REG_CLASSES; class++)
     {
       int bad = 0;
-      for (regno = 0; regno < FIRST_PSEUDO_REGISTER && ! bad; regno++)
-	if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
-	    && TEST_HARD_REG_BIT (reg_class_contents[class], regno + n)
-	    && ! HARD_REGNO_MODE_OK (regno + n, m1))
-	  bad = 1;
+      int good = 0;
+      for (regno = 0; regno < FIRST_PSEUDO_REGISTER - n && ! bad; regno++)
+	if (TEST_HARD_REG_BIT (reg_class_contents[class], regno))
+	  {
+	    if (HARD_REGNO_MODE_OK (regno, inner))
+	      {
+		good = 1;
+		if (! TEST_HARD_REG_BIT (reg_class_contents[class], regno + n)
+		    || ! HARD_REGNO_MODE_OK (regno + n, outer))
+		  bad = 1;
+	      }
+	  }
 
-      if (bad)
+      if (bad || !good)
 	continue;
-      cost = REGISTER_MOVE_COST (m1, class, dest_class);
+      cost = REGISTER_MOVE_COST (outer, class, dest_class);
 
       if ((reg_class_size[class] > best_size
 	   && (best_cost < 0 || best_cost >= cost))
@@ -694,7 +705,7 @@ find_valid_class (enum machine_mode m1 A
 	{
 	  best_class = class;
 	  best_size = reg_class_size[class];
-	  best_cost = REGISTER_MOVE_COST (m1, class, dest_class);
+	  best_cost = REGISTER_MOVE_COST (outer, class, dest_class);
 	}
     }
 
@@ -1083,7 +1094,7 @@ push_reload (rtx in, rtx out, rtx *inloc
 
       if (REG_P (SUBREG_REG (in)))
 	in_class
-	  = find_valid_class (inmode,
+	  = find_valid_class (inmode, GET_MODE (SUBREG_REG (in)),
 			      subreg_regno_offset (REGNO (SUBREG_REG (in)),
 						   GET_MODE (SUBREG_REG (in)),
 						   SUBREG_BYTE (in),
@@ -1180,7 +1191,7 @@ push_reload (rtx in, rtx out, rtx *inloc
       dont_remove_subreg = 1;
       push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
 		   &SUBREG_REG (out),
-		   find_valid_class (outmode,
+		   find_valid_class (outmode, GET_MODE (SUBREG_REG (out)),
 				     subreg_regno_offset (REGNO (SUBREG_REG (out)),
 							  GET_MODE (SUBREG_REG (out)),
 							  SUBREG_BYTE (out),


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