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]

RFA: version 2 patch to fix PR37514


The following patch solves a latent reload bug (in reload inheritance) triggered by IRA. It is a second version (less pessimistic in reload inheritance optimization) of the patch

The problem is described on

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37514


The patch invalidates reg_last_reload_reg set in previous insns for INC/DEC if reg_last_reload_reg set is not set for the current insn for some reasons (e.g. the hard register is used in other insn reloads besides reload for INC/DEC).


The patch was tested on SH (with -m4 -ml -O3 -fomit-frame-pointer) and successfully bootstrapped on itanium (another port using INC/DEC heavily).


Ok to commit?


2008-11-25 Vladimir Makarov <vmakarov@redhat.com>

   PR rtl-optimization/37514
   * reload1.c (reload_as_needed): Invalidate reg_last_reload
   from previous insns.


Index: reload1.c
===================================================================
--- reload1.c	(revision 142061)
+++ reload1.c	(working copy)
@@ -4164,6 +4164,7 @@ reload_as_needed (int live_known)
       rtx prev = 0;
       rtx insn = chain->insn;
       rtx old_next = NEXT_INSN (insn);
+      rtx old_prev = PREV_INSN (insn);
 
       /* If we pass a label, copy the offsets from the label information
 	 into the current offsets of each elimination.  */
@@ -4388,6 +4389,33 @@ reload_as_needed (int live_known)
 		      SET_REGNO_REG_SET (&reg_has_output_reload,
 					 REGNO (XEXP (in_reg, 0)));
 		    }
+		  else if ((code == PRE_INC || code == PRE_DEC
+			    || code == POST_INC || code == POST_DEC))
+		    {
+		      int in_hard_regno;
+		      int in_regno = REGNO (XEXP (in_reg, 0));
+
+		      if (reg_last_reload_reg[in_regno] != NULL_RTX)
+			{
+			  in_hard_regno = REGNO (reg_last_reload_reg[in_regno]);
+			  gcc_assert (TEST_HARD_REG_BIT (reg_reloaded_valid,
+							 in_hard_regno));
+			  for (x = old_prev ? NEXT_INSN (old_prev) : insn;
+			       x != old_next;
+			       x = NEXT_INSN (x))
+			    if (x == reg_reloaded_insn[in_hard_regno])
+			      break;
+			  /* If for some reasons, we didn't set up
+			     reg_last_reload_reg in this insn,
+			     invalidate inheritance from previous
+			     insns for the incremented/decremented
+			     register.  Such registers will be not in
+			     reg_has_output_reload.  */
+			  if (x == old_next)
+			    forget_old_reloads_1 (XEXP (in_reg, 0),
+						  NULL_RTX, NULL);
+			}
+		    }
 		}
 	    }
 	  /* If a pseudo that got a hard register is auto-incremented,

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