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]

[PATCH, middle-end]: members of global_regs[] are also members of fixed_regs[]


Hello!

It was brought to my attention that members of global_regs[] array are always* members of fixed_regs[] array, so there is no need to check both arrays with "fixed_regs[N] || global_regs[N]".

Attached patch is the result of code grep for the above logic and fixes a couple of places through the code.
The patch also includes a fix for thinko w.r.t. i386 string instructions and global regs. We should check fixed_regs[] here too, so we could handle stringop expansion for i.e. -ffixed-edi compile flags in addition to global regs definitions. Oh, and fixes off-by-one error when adjusting regparm value due to hard regs usage.


The patch was bootstrapped and regresion tested on x86_64 {,-m32}. The patch needs approval of its (trivial) middle-end part.

2007-12-08 Uros Bizjak <ubizjak@gmail.com>

* cse.c (FIXED_REGNO_P): Do not check global_regs array, registers
that are members of global_regs are also members of fixed_regs array.
* regrename.c (regrename_optimize): Ditto.
* config/i386/i386.c (ix86_function_regparm): Ditto. Use REGPARM_MAX
to check that no regparm hard register is taken by a fixed register
variable. Check up to and including DI_REG when adjusting regparm
value due to fixed regs usage.
(rep_prefix_usable): Check fixed_regs array, not global_regs array for
available hard registers.
(ix86_expand_strlen): Ditto.
* config/i386/i386.md (strmov): Ditto.
(cmpstrnsi): Ditto.


*) regclass.c, line 631 and 923.

Uros.
Index: regrename.c
===================================================================
--- regrename.c	(revision 130706)
+++ regrename.c	(working copy)
@@ -241,7 +241,7 @@ regrename_optimize (void)
 	    }
 #endif
 
-	  if (fixed_regs[reg] || global_regs[reg]
+	  if (fixed_regs[reg]
 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
 	      || (frame_pointer_needed && reg == HARD_FRAME_POINTER_REGNUM)
 #else
@@ -282,7 +282,6 @@ regrename_optimize (void)
 	      for (i = nregs - 1; i >= 0; --i)
 	        if (TEST_HARD_REG_BIT (this_unavailable, new_reg + i)
 		    || fixed_regs[new_reg + i]
-		    || global_regs[new_reg + i]
 		    /* Can't use regs which aren't saved by the prologue.  */
 		    || (! df_regs_ever_live_p (new_reg + i)
 			&& ! call_used_regs[new_reg + i])
@@ -1234,7 +1233,7 @@ copy_value (rtx dest, rtx src, struct va
   /* Do not propagate copies to fixed or global registers, patterns
      can be relying to see particular fixed register or users can
      expect the chosen global register in asm.  */
-  if (fixed_regs[dr] || global_regs[dr])
+  if (fixed_regs[dr])
     return;
 
   /* If SRC and DEST overlap, don't record anything.  */
Index: cse.c
===================================================================
--- cse.c	(revision 130706)
+++ cse.c	(working copy)
@@ -462,8 +462,9 @@ struct table_elt
    non-fixed hard regs.
    A reg wins if it is either the frame pointer or designated as fixed.  */
 #define FIXED_REGNO_P(N)  \
-  ((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM \
-   || fixed_regs[N] || global_regs[N])
+  ((N) == FRAME_POINTER_REGNUM			\
+   || (N) == HARD_FRAME_POINTER_REGNUM		\
+   || fixed_regs[N])
 
 /* Compute cost of X, as stored in the `cost' field of a table_elt.  Fixed
    hard registers and pointers into the frame are the cheapest with a cost
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 130706)
+++ config/i386/i386.md	(working copy)
@@ -18714,7 +18714,7 @@
 
   /* Can't use this if the user has appropriated esi or edi.  */
   if ((TARGET_SINGLE_STRINGOP || optimize_size)
-      && !(global_regs[SI_REG] || global_regs[DI_REG]))
+      && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
     {
       emit_insn (gen_strmov_singleop (operands[0], operands[1],
 				      operands[2], operands[3],
@@ -19200,7 +19200,7 @@
   rtx addr1, addr2, out, outlow, count, countreg, align;
 
   /* Can't use this if the user has appropriated esi or edi.  */
-  if (global_regs[SI_REG] || global_regs[DI_REG])
+  if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
     FAIL;
 
   out = operands[0];
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 130706)
+++ config/i386/i386.c	(working copy)
@@ -3203,9 +3203,9 @@ ix86_function_regparm (const_tree type, 
 	  struct function *f;
 
 	  /* Make sure no regparm register is taken by a
-	     fixed register or global register variable.  */
-	  for (local_regparm = 0; local_regparm < 3; local_regparm++)
-	    if (global_regs[local_regparm] || fixed_regs[local_regparm])
+	     fixed register variable.  */
+	  for (local_regparm = 0; local_regparm < REGPARM_MAX; local_regparm++)
+	    if (fixed_regs[local_regparm])
 	      break;
 
 	  /* We can't use regparm(3) for nested functions as these use
@@ -3227,13 +3227,14 @@ ix86_function_regparm (const_tree type, 
 					TYPE_ATTRIBUTES (TREE_TYPE (decl)))))
 	    local_regparm = 2;
 
-	  /* Each global register variable or fixed register usage
-	     increases register pressure, so less registers should be
-	     used for argument passing.  This functionality can be
-	     overriden by explicit regparm value.  */
-	  for (regno = 0; regno < 6; regno++)
-	    if (global_regs[regno] || fixed_regs[regno])
+	  /* Each fixed register usage increases register pressure,
+	     so less registers should be used for argument passing.
+	     This functionality can be overriden by an explicit
+	     regparm value.  */
+	  for (regno = 0; regno <= DI_REG; regno++)
+	    if (fixed_regs[regno])
 	      globals++;
+
 	  local_regparm
 	    = globals < local_regparm ? local_regparm - globals : 0;
 
@@ -15108,8 +15109,9 @@ decide_alg (HOST_WIDE_INT count, HOST_WI
      additionally, memset wants eax and memcpy wants esi.  Don't
      consider such algorithms if the user has appropriated those
      registers for their own purposes.	*/
-  bool rep_prefix_usable = !(global_regs[CX_REG] || global_regs[DI_REG]
-                             || (memset ? global_regs[AX_REG] : global_regs[SI_REG]));
+  bool rep_prefix_usable = !(fixed_regs[CX_REG] || fixed_regs[DI_REG]
+                             || (memset
+				 ? fixed_regs[AX_REG] : fixed_regs[SI_REG]));
 
 #define ALG_USABLE_P(alg) (rep_prefix_usable			\
 			   || (alg != rep_prefix_1_byte		\
@@ -16084,7 +16086,7 @@ ix86_expand_strlen (rtx out, rtx src, rt
       rtx unspec;
 
       /* Can't use this if the user has appropriated eax, ecx, or edi.  */
-      if (global_regs[AX_REG] || global_regs[CX_REG] || global_regs[DI_REG])
+      if (fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
         return false;
 
       scratch2 = gen_reg_rtx (Pmode);

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