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]

Re: PR 34998: Tracking of subreg liveness in global.c and ra-conflict.c


Kenneth Zadeck <zadeck@naturalbridge.com> writes:
> It looks like iant gave you approval subject to one of the ra
> maintainers saying ok, so check it in.

Thanks.  I added the subreg_lowpart check and retested as before.
Here's what I checked in.

(Looking again, we probably handled subreg_lowparts correctly without
the check, since df-scan.c adds a full-register DF_REF_READ_WRITE use
for them.  That's not an argument in favour of the original patch;
the new one is more obviously correct.  I just thought it might set
minds at rest in case about the strength of the original testing.)

Richard


gcc/
	PR rtl-optimization/34998
	* global.c (build_insn_chain): Treat non-subreg_lowpart
	SUBREGs of pseudos as clobbering all the words covered by the
	SUBREG, not just all the bytes.
	* ra-conflict.c (clear_reg_in_live): Likewise.  Take the
	original df_ref rather than an extract parameter.
	(global_conflicts): Update call accordingly.

Index: gcc/global.c
===================================================================
--- gcc/global.c	2008-01-29 10:32:52.000000000 +0000
+++ gcc/global.c	2008-01-29 21:05:12.000000000 +0000
@@ -1501,6 +1501,17 @@ build_insn_chain (void)
 						  live_subregs, 
 						  live_subregs_used,
 						  regno, reg);
+
+			    if (!DF_REF_FLAGS_IS_SET
+				(def, DF_REF_STRICT_LOWER_PART))
+			      {
+				/* Expand the range to cover entire words.
+				   Bytes added here are "don't care".  */
+				start = start / UNITS_PER_WORD * UNITS_PER_WORD;
+				last = ((last + UNITS_PER_WORD - 1)
+					/ UNITS_PER_WORD * UNITS_PER_WORD);
+			      }
+
 			    /* Ignore the paradoxical bits.  */
 			    if ((int)last > live_subregs_used[regno])
 			      last = live_subregs_used[regno];
Index: gcc/ra-conflict.c
===================================================================
--- gcc/ra-conflict.c	2008-01-29 10:32:52.000000000 +0000
+++ gcc/ra-conflict.c	2008-01-29 21:10:39.000000000 +0000
@@ -441,16 +441,14 @@ ra_init_live_subregs (bool init_value, 
 
 
 /* Set REG to be not live in the sets ALLOCNOS_LIVE, LIVE_SUBREGS,
-   HARD_REGS_LIVE.  If EXTRACT is false, assume that the entire reg is
-   set not live even if REG is a subreg.  */
+   HARD_REGS_LIVE.  DEF is the definition of the register.  */
 
 inline static void
 clear_reg_in_live (sparseset allocnos_live,
 		   sbitmap *live_subregs, 
 		   int *live_subregs_used,
 		   HARD_REG_SET *hard_regs_live, 
-		   rtx reg,
-		   bool extract)
+		   rtx reg, struct df_ref *def)
 {
   unsigned int regno = (GET_CODE (reg) == SUBREG) 
     ? REGNO (SUBREG_REG (reg)): REGNO (reg);
@@ -458,8 +456,8 @@ clear_reg_in_live (sparseset allocnos_li
 
   if (allocnum >= 0)
     {
-      if ((GET_CODE (reg) == SUBREG) && !extract)
-
+      if (GET_CODE (reg) == SUBREG
+	  && !DF_REF_FLAGS_IS_SET (def, DF_REF_EXTRACT))
 	{
 	  unsigned int start = SUBREG_BYTE (reg);
 	  unsigned int last = start + GET_MODE_SIZE (GET_MODE (reg));
@@ -467,6 +465,15 @@ clear_reg_in_live (sparseset allocnos_li
 	  ra_init_live_subregs (sparseset_bit_p (allocnos_live, allocnum), 
 				live_subregs, live_subregs_used, allocnum, reg);
 
+	  if (!DF_REF_FLAGS_IS_SET (def, DF_REF_STRICT_LOWER_PART))
+	    {
+	      /* Expand the range to cover entire words.
+		 Bytes added here are "don't care".  */
+	      start = start / UNITS_PER_WORD * UNITS_PER_WORD;
+	      last = ((last + UNITS_PER_WORD - 1)
+		      / UNITS_PER_WORD * UNITS_PER_WORD);
+	    }
+
 	  /* Ignore the paradoxical bits.  */
 	  if ((int)last > live_subregs_used[allocnum])
 	    last = live_subregs_used[allocnum];
@@ -503,7 +510,8 @@ clear_reg_in_live (sparseset allocnos_li
   if (! fixed_regs[regno])
     {
       unsigned int start = regno;
-      if ((GET_CODE (reg) == SUBREG) && !extract)
+      if (GET_CODE (reg) == SUBREG
+	  && !DF_REF_FLAGS_IS_SET (def, DF_REF_EXTRACT))
 	{
 	  unsigned int last;
 	  start += SUBREG_BYTE (reg);
@@ -890,8 +898,7 @@ global_conflicts (void)
 		  rtx reg = DF_REF_REG (def);
 
 		  clear_reg_in_live (allocnos_live, live_subregs, live_subregs_used,
-				     &hard_regs_live, reg,
-				     DF_REF_FLAGS_IS_SET (def, DF_REF_EXTRACT));
+				     &hard_regs_live, reg, def);
 		  if (dump_file)
 		    dump_ref (dump_file, "  clearing def", "\n", 
 			      reg, DF_REF_REGNO (def), live_subregs, live_subregs_used);


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