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]

[ira] patch fixing boostrap failure on ppc64


Hi, this patch mostly solves bootstrap failure and gcc testsuite
failures on ppc64 after recent changes on IRA branch.

I've missed handling other RTL ops modifying registers in latest
patch for better placement of saves/restores registers.  Therefore ppc
which has increment/decrement ops was broken.  Here, the patch solving
the problem.

The patch was bootstrapped on x86_64 and ppc64.

2008-06-03 Vladimir Makarov <vmakarov@redhat.com>

	* caller-saves.c (mark_referenced_regs): Add new parameter.
	Process increments/decrements.
	(set_regs): Rename to modified_regs.
	(calculate_local_save_info, save_call_clobbered_regs): Pass the
	new parameter value to mark_referenced_regs.

	* ira-costs.c (find_allocno_class_costs): Always use important
	classes.

	* reload1.c (reload): Clear changed_allocation_pseudos at the end
	of reload.
	

Index: caller-save.c
===================================================================
--- caller-save.c	(revision 136340)
+++ caller-save.c	(working copy)
@@ -97,8 +97,8 @@ static int n_regs_saved;
 /* Computed by mark_referenced_regs, all regs referenced in a given
    insn.  */
 static HARD_REG_SET referenced_regs;
-/* Computed by mark_referenced_regs, all regs set in a given insn.  */
-static HARD_REG_SET set_regs;
+/* Computed by mark_referenced_regs, all regs modified in a given insn.  */
+static HARD_REG_SET modified_regs;
 
 
 static int reg_save_code (int, enum machine_mode);
@@ -135,7 +135,7 @@ static void set_hard_reg_saved (HARD_REG
 
 static void mark_set_regs (rtx, const_rtx, void *);
 static void add_stored_regs (rtx, const_rtx, void *);
-static void mark_referenced_regs (rtx);
+static void mark_referenced_regs (rtx, int);
 static int insert_save (struct insn_chain *, int, int, HARD_REG_SET *,
 			enum machine_mode *, int *);
 static int insert_restore (struct insn_chain *, int, int, int,
@@ -884,11 +884,11 @@ calculate_local_save_info (void)
       if (INSN_P (insn))
 	{
 	  CLEAR_HARD_REG_SET (referenced_regs);
-	  CLEAR_HARD_REG_SET (set_regs);
-	  mark_referenced_regs (PATTERN (insn));
+	  CLEAR_HARD_REG_SET (modified_regs);
+	  mark_referenced_regs (PATTERN (insn), FALSE);
 	  AND_COMPL_HARD_REG_SET (restore_gen, referenced_regs);
 	  IOR_HARD_REG_SET (restore_kill, referenced_regs);
-	  IOR_HARD_REG_SET (save_kill, set_regs);
+	  IOR_HARD_REG_SET (save_kill, modified_regs);
 
 	  if (code == CALL_INSN && find_reg_note (insn, REG_NORETURN, NULL))
 	    {
@@ -1679,8 +1679,8 @@ save_call_clobbered_regs (void)
 	      else
 		{
 		  CLEAR_HARD_REG_SET (referenced_regs);
-		  CLEAR_HARD_REG_SET (set_regs);
-		  mark_referenced_regs (PATTERN (insn));
+		  CLEAR_HARD_REG_SET (modified_regs);
+		  mark_referenced_regs (PATTERN (insn), FALSE);
 		  AND_HARD_REG_SET (referenced_regs, hard_regs_saved);
 		}
 
@@ -1874,11 +1874,11 @@ save_call_clobbered_regs (void)
 	  bb_info = BB_INFO_BY_INDEX (chain->block);
 	  
 	  CLEAR_HARD_REG_SET (referenced_regs);
-	  CLEAR_HARD_REG_SET (set_regs);
-	  mark_referenced_regs (PATTERN (insn));
-	  AND_HARD_REG_SET (set_regs, hard_regs_to_save);
+	  CLEAR_HARD_REG_SET (modified_regs);
+	  mark_referenced_regs (PATTERN (insn), FALSE);
+	  AND_HARD_REG_SET (modified_regs, hard_regs_to_save);
 	  AND_COMPL_HARD_REG_SET (saved, referenced_regs);
-	  AND_COMPL_HARD_REG_SET (saved, set_regs);
+	  AND_COMPL_HARD_REG_SET (saved, modified_regs);
 	  
 	  if (chain->is_caller_save_insn)
 	    {
@@ -1892,7 +1892,7 @@ save_call_clobbered_regs (void)
 		 the insn if so.  */
 	      
 	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
-		if (TEST_HARD_REG_BIT (set_regs, regno))
+		if (TEST_HARD_REG_BIT (modified_regs, regno))
 		  {
 		    unsigned int before = regno;
 		    
@@ -2176,79 +2176,84 @@ add_stored_regs (rtx reg, const_rtx sett
     SET_REGNO_REG_SET ((regset) data, i);
 }
 
-
-/* Walk X and record all referenced registers in REFERENCED_REG.  */
+/* Walk X and record all referenced registers in REFERENCED_REG and
+   modified registers in MODIFIED_REGS.  */
 static void
-mark_referenced_regs (rtx x)
+mark_referenced_regs (rtx x, int set_p)
 {
-  enum rtx_code code = GET_CODE (x);
+  enum rtx_code code;
   const char *fmt;
   int i, j;
-  rtx dest;
-
-  if (code == SET)
-    mark_referenced_regs (SET_SRC (x));
-  if (code == SET || code == CLOBBER)
-    {
-      dest = x = SET_DEST (x);
-      while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SUBREG
-	     || GET_CODE (dest) == ZERO_EXTRACT)
-	dest = XEXP (dest, 0);
-      if (GET_CODE (dest) == REG)
-	{
-	  int regno = REGNO (dest);
-	  int hardregno = (regno < FIRST_PSEUDO_REGISTER ? regno
-			   : reg_renumber[regno]);
-	  
-	  if (hardregno >= 0)
-	    add_to_hard_reg_set (&set_regs, GET_MODE (dest), hardregno);
-	}
-      code = GET_CODE (x);
-      if ((code == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
-	  || code == PC || code == CC0
-	  || (code == SUBREG && REG_P (SUBREG_REG (x))
-	      && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER
-	      /* If we're setting only part of a multi-word register,
-		 we shall mark it as referenced, because the words
-		 that are not being set should be restored.  */
-	      && ((GET_MODE_SIZE (GET_MODE (x))
-		   >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
-		  || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))
-		      <= UNITS_PER_WORD))))
-	return;
-    }
-  if (code == MEM || code == SUBREG)
+  int stop_p;
+  
+  for (stop_p = FALSE; !stop_p; )
     {
-      x = XEXP (x, 0);
+      while (GET_CODE (x) == STRICT_LOW_PART || GET_CODE (x) == ZERO_EXTRACT)
+	x = XEXP (x, 0);
       code = GET_CODE (x);
-    }
-
-  if (code == REG)
-    {
-      int regno = REGNO (x);
-      int hardregno = (regno < FIRST_PSEUDO_REGISTER ? regno
-		       : reg_renumber[regno]);
-
-      if (hardregno >= 0)
-	add_to_hard_reg_set (&referenced_regs, GET_MODE (x), hardregno);
-      /* If this is a pseudo that did not get a hard register, scan its
-	 memory location, since it might involve the use of another
-	 register, which might be saved.  */
-      else if (reg_equiv_mem[regno] != 0)
-	mark_referenced_regs (XEXP (reg_equiv_mem[regno], 0));
-      else if (reg_equiv_address[regno] != 0)
-	mark_referenced_regs (reg_equiv_address[regno]);
-      return;
-    }
-
-  fmt = GET_RTX_FORMAT (code);
-  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-    {
-      if (fmt[i] == 'e')
-	mark_referenced_regs (XEXP (x, i));
-      else if (fmt[i] == 'E')
-	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-	  mark_referenced_regs (XVECEXP (x, i, j));
+      switch (code)
+	{
+	case SET:
+	  gcc_assert (!set_p);
+	  mark_referenced_regs (SET_DEST (x), TRUE);
+	  x = SET_SRC (x);
+	  break;
+	case CLOBBER:
+	  mark_referenced_regs (SET_DEST (x), TRUE);
+	  return;
+	case PRE_INC:
+	case POST_INC:
+	case PRE_DEC:
+	case POST_DEC:
+	  gcc_assert (!set_p);
+	  x = XEXP (x, 0);
+	  mark_referenced_regs (x, TRUE);
+	  break;
+	case PRE_MODIFY:
+	case POST_MODIFY:
+	  set_p = FALSE;
+	  mark_referenced_regs (XEXP (x, 0), FALSE);
+	  mark_referenced_regs (XEXP (x, 0), TRUE);
+	  x = XEXP (x, 1);
+	  mark_referenced_regs (x, FALSE);
+	  break;
+	case SUBREG:
+	  x = SUBREG_REG (x);
+	  break;
+	case REG:
+	  {
+	    int regno = REGNO (x);
+	    int hardregno = (regno < FIRST_PSEUDO_REGISTER ? regno
+			     : reg_renumber[regno]);
+	    
+	    if (hardregno >= 0)
+	      {
+		if (set_p)
+		  add_to_hard_reg_set (&modified_regs, GET_MODE (x), hardregno);
+		add_to_hard_reg_set (&referenced_regs, GET_MODE (x), hardregno);
+	      }
+	    /* If this is a pseudo that did not get a hard register, scan
+	       its memory location, since it might involve the use of
+	       another register, which might be saved.  */
+	    else if (reg_equiv_mem[regno] != 0)
+	      mark_referenced_regs (XEXP (reg_equiv_mem[regno], 0), set_p);
+	    else if (reg_equiv_address[regno] != 0)
+	      mark_referenced_regs (reg_equiv_address[regno], set_p);
+	    return;
+	  }
+	default:
+	  fmt = GET_RTX_FORMAT (code);
+	  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+	    {
+	      if (fmt[i] == 'e')
+		mark_referenced_regs (XEXP (x, i), FALSE);
+	      else if (fmt[i] == 'E')
+		for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+		  mark_referenced_regs (XVECEXP (x, i, j), FALSE);
+	    }
+	  stop_p = TRUE;
+	  break;
+	}
     }
 }
 
Index: ira-costs.c
===================================================================
--- ira-costs.c	(revision 136340)
+++ ira-costs.c	(working copy)
@@ -1121,34 +1121,17 @@ find_allocno_class_costs (void)
       if (internal_flag_ira_verbose > 0 && ira_dump_file)
 	fprintf (ira_dump_file, "\nPass %i for finding allocno costs\n\n",
 		 pass);
-      if (optimize)
+      /* We could use only cover classes.  Unfortunately it does not
+	 work well for some targets where some subclass of cover class
+	 is costly and wrong cover class is chosen.  */
+      for (cost_classes_num = 0;
+	   cost_classes_num < important_classes_num;
+	   cost_classes_num++)
 	{
-	  /* We could use only cover classes on the 1st iteration.
-	     Unfortunately it does not work well for some targets where
-	     some subclass of cover class is costly and wrong cover class
-	     is chosen on the first iteration and it can not be fixed on
-	     the 2nd iteration.  */
-	  for (cost_classes_num = 0;
-	       cost_classes_num < important_classes_num;
-	       cost_classes_num++)
-	    {
-	      cost_classes[cost_classes_num]
-		= important_classes[cost_classes_num];
-	      cost_class_nums[cost_classes[cost_classes_num]]
-		= cost_classes_num;
-	    }
-	}
-      else
-	{
-	  for (cost_classes_num = 0;
-	       cost_classes_num < reg_class_cover_size;
-	       cost_classes_num++)
-	    {
-	      cost_classes[cost_classes_num]
-		= reg_class_cover[cost_classes_num];
-	      cost_class_nums[cost_classes[cost_classes_num]]
-		= cost_classes_num;
-	    }
+	  cost_classes[cost_classes_num]
+	    = important_classes[cost_classes_num];
+	  cost_class_nums[cost_classes[cost_classes_num]]
+	    = cost_classes_num;
 	}
       struct_costs_size
 	= sizeof (struct costs) + sizeof (int) * (cost_classes_num - 1);
Index: reload1.c
===================================================================
--- reload1.c	(revision 136340)
+++ reload1.c	(working copy)
@@ -1193,6 +1193,7 @@ reload (rtx first, int global)
      regs.  */
  failed:
 
+  CLEAR_REG_SET (&changed_allocation_pseudos);
   CLEAR_REG_SET (&spilled_pseudos);
   reload_in_progress = 0;
 

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