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: [RFC] Fix PR rtl-optimization/33732


> I'm not sure what the best approach to fixing this is.  Should we disregard
> notes referencing former pseudo-registers that have been assigned more than
> one hard register, between global alloc and reload?
>
> 	    && (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
>
> 		|| hard_regno_nregs [XEXP (note, 0)] == 1)
>
> Would this pessimize much in practice?

Unsurprisingly this doesn't have any effect for a bootstrap of the compiler on 
x86-64 and changes 4 reloads for a bootstrap on x86 (1 slight overall win, 2 
slight losses and 1 net loss because of a cascading effect) related to 64-bit 
mult and div operations.  The pessimization is very likely mitigated by the 
lower-subreg pass and the new ra-conflict.c code.

Other suggestions still welcome.


	* reload.c (push_reload): Check that the REG_DEAD note was referring
	to a hardreg or to a pseudo that has been assigned exactly one hardreg
	before considering it in order to select the reload register.
	(combine_reloads): Likewise.
	(find_dummy_reload): Likewise.


-- 
Eric Botcazou
Index: reload.c
===================================================================
--- reload.c	(revision 129844)
+++ reload.c	(working copy)
@@ -1518,11 +1518,11 @@ push_reload (rtx in, rtx out, rtx *inloc
 	    && REG_P (XEXP (note, 0))
 	    && (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
 	    && reg_mentioned_p (XEXP (note, 0), in)
-	    /* Check that we don't use a hardreg for an uninitialized
-	       pseudo.  See also find_dummy_reload().  */
+	    /* Check that a former pseudo is valid; see find_dummy_reload.  */
 	    && (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
-		|| ! bitmap_bit_p (DF_LIVE_OUT (ENTRY_BLOCK_PTR),
-				   ORIGINAL_REGNO (XEXP (note, 0))))
+		|| (!bitmap_bit_p (DF_LIVE_OUT (ENTRY_BLOCK_PTR),
+				   ORIGINAL_REGNO (XEXP (note, 0)))
+		    && hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))] == 1))
 	    && ! refers_to_regno_for_reload_p (regno,
 					       end_hard_regno (rel_mode,
 							       regno),
@@ -1678,7 +1678,7 @@ remove_address_replacements (rtx in_rtx)
 static void
 combine_reloads (void)
 {
-  int i;
+  int i, regno;
   int output_reload = -1;
   int secondary_out = -1;
   rtx note;
@@ -1825,34 +1825,32 @@ combine_reloads (void)
   for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
     if (REG_NOTE_KIND (note) == REG_DEAD
 	&& REG_P (XEXP (note, 0))
-	&& ! reg_overlap_mentioned_for_reload_p (XEXP (note, 0),
-						 rld[output_reload].out)
-	&& REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
-	&& HARD_REGNO_MODE_OK (REGNO (XEXP (note, 0)), rld[output_reload].outmode)
+	&& !reg_overlap_mentioned_for_reload_p (XEXP (note, 0),
+						rld[output_reload].out)
+	&& (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
+	&& HARD_REGNO_MODE_OK (regno, rld[output_reload].outmode)
 	&& TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].class],
-			      REGNO (XEXP (note, 0)))
-	&& (hard_regno_nregs[REGNO (XEXP (note, 0))][rld[output_reload].outmode]
-	    <= hard_regno_nregs[REGNO (XEXP (note, 0))][GET_MODE (XEXP (note, 0))])
+			      regno)
+	&& (hard_regno_nregs[regno][rld[output_reload].outmode]
+	    <= hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))])
 	/* Ensure that a secondary or tertiary reload for this output
 	   won't want this register.  */
 	&& ((secondary_out = rld[output_reload].secondary_out_reload) == -1
-	    || (! (TEST_HARD_REG_BIT
-		   (reg_class_contents[(int) rld[secondary_out].class],
-		    REGNO (XEXP (note, 0))))
+	    || (!(TEST_HARD_REG_BIT
+		  (reg_class_contents[(int) rld[secondary_out].class], regno))
 		&& ((secondary_out = rld[secondary_out].secondary_out_reload) == -1
-		    ||  ! (TEST_HARD_REG_BIT
-			   (reg_class_contents[(int) rld[secondary_out].class],
-			    REGNO (XEXP (note, 0)))))))
-	&& ! fixed_regs[REGNO (XEXP (note, 0))]
-	/* Check that we don't use a hardreg for an uninitialized
-	   pseudo.  See also find_dummy_reload().  */
+		    || !(TEST_HARD_REG_BIT
+			 (reg_class_contents[(int) rld[secondary_out].class],
+			  regno)))))
+	&& !fixed_regs[regno]
+	/* Check that a former pseudo is valid; see find_dummy_reload.  */
 	&& (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
-	    || ! bitmap_bit_p (DF_LR_OUT (ENTRY_BLOCK_PTR),
-			       ORIGINAL_REGNO (XEXP (note, 0)))))
+	    || (!bitmap_bit_p (DF_LR_OUT (ENTRY_BLOCK_PTR),
+			       ORIGINAL_REGNO (XEXP (note, 0)))
+		&& hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))] == 1)))
       {
 	rld[output_reload].reg_rtx
-	  = gen_rtx_REG (rld[output_reload].outmode,
-			 REGNO (XEXP (note, 0)));
+	  = gen_rtx_REG (rld[output_reload].outmode, regno);
 	return;
       }
 }
@@ -1992,16 +1990,24 @@ find_dummy_reload (rtx real_in, rtx real
 				has a real mode.  */
 			     (GET_MODE (out) != VOIDmode
 			      ? GET_MODE (out) : outmode))
-        /* But only do all this if we can be sure, that this input
-           operand doesn't correspond with an uninitialized pseudoreg.
-           global can assign some hardreg to it, which is the same as
-	   a different pseudo also currently live (as it can ignore the
-	   conflict).  So we never must introduce writes to such hardregs,
-	   as they would clobber the other live pseudo using the same.
-	   See also PR20973.  */
       && (ORIGINAL_REGNO (in) < FIRST_PSEUDO_REGISTER
-          || ! bitmap_bit_p (DF_LIVE_OUT (ENTRY_BLOCK_PTR),
-			     ORIGINAL_REGNO (in))))
+	  /* However only do this if we can be sure that this input
+	     operand doesn't correspond with an uninitialized pseudo.
+	     global can assign some hardreg to it that is the same as
+	     the one assigned to a different, also live pseudo (as it
+	     can ignore the conflict).  We must never introduce writes
+	     to such hardregs, as they would clobber the other live
+	     pseudo.  See PR 20973.  */
+          || (!bitmap_bit_p (DF_LIVE_OUT (ENTRY_BLOCK_PTR),
+			     ORIGINAL_REGNO (in))
+	      /* Similarly, only do this if we can be sure that the death
+		 note is still valid.  global can assign some hardreg to
+		 the pseudo referenced in the note and simultaneously a
+		 subword of this hardreg to a different, also live pseudo,
+		 because only another subword of the hardreg is actually
+		 used in the insn.  This cannot happen if the pseudo has
+		 been assigned exactly one hardreg.  See PR 33732.  */
+	      && hard_regno_nregs[REGNO (in)][GET_MODE (in)] == 1)))
     {
       unsigned int regno = REGNO (in) + in_offset;
       unsigned int nwords = hard_regno_nregs[regno][inmode];

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