diff gcc/ira-conflicts.c @ 63:b7f97abdc517 gcc-4.6-20100522

update gcc from gcc-4.5.0 to gcc-4.6
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Mon, 24 May 2010 12:47:05 +0900
parents 77e2b8dfacca
children f6334be47118
line wrap: on
line diff
--- a/gcc/ira-conflicts.c	Fri Feb 12 23:41:23 2010 +0900
+++ b/gcc/ira-conflicts.c	Mon May 24 12:47:05 2010 +0900
@@ -1,5 +1,5 @@
 /* IRA conflict builder.
-   Copyright (C) 2006, 2007, 2008, 2009
+   Copyright (C) 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
 
@@ -302,21 +302,6 @@
   return dup;
 }
 
-/* Return the operand which should be, in any case, the same as
-   operand with number OP_NUM.  If USE_COMMUT_OP_P is TRUE, the
-   function makes temporarily commutative operand exchange before
-   this.  */
-static rtx
-get_dup (int op_num, bool use_commut_op_p)
-{
-  int n = get_dup_num (op_num, use_commut_op_p);
-
-  if (n < 0)
-    return NULL_RTX;
-  else
-    return recog_data.operand[n];
-}
-
 /* Check that X is REG or SUBREG of REG.  */
 #define REG_SUBREG_P(x)							\
    (REG_P (x) || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))))
@@ -432,12 +417,12 @@
   return true;
 }
 
-/* Process all of the output registers of the current insn and
-   the input register REG (its operand number OP_NUM) which dies in the
-   insn as if there were a move insn between them with frequency
-   FREQ.  */
+/* Process all of the output registers of the current insn which are
+   not bound (BOUND_P) and the input register REG (its operand number
+   OP_NUM) which dies in the insn as if there were a move insn between
+   them with frequency FREQ.  */
 static void
-process_reg_shuffles (rtx reg, int op_num, int freq)
+process_reg_shuffles (rtx reg, int op_num, int freq, bool *bound_p)
 {
   int i;
   rtx another_reg;
@@ -448,7 +433,8 @@
       another_reg = recog_data.operand[i];
 
       if (!REG_SUBREG_P (another_reg) || op_num == i
-	  || recog_data.operand_type[i] != OP_OUT)
+	  || recog_data.operand_type[i] != OP_OUT
+	  || bound_p[i])
 	continue;
 
       process_regs_for_copy (reg, another_reg, false, NULL_RTX, freq);
@@ -463,9 +449,9 @@
 {
   rtx set, operand, dup;
   const char *str;
-  bool commut_p, bound_p;
-  int i, j, freq;
-
+  bool commut_p, bound_p[MAX_RECOG_OPERANDS];
+  int i, j, n, freq;
+  
   freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
   if (freq == 0)
     freq = 1;
@@ -476,38 +462,51 @@
 			REG_P (SET_SRC (set))
 			? SET_SRC (set)
 			: SUBREG_REG (SET_SRC (set))) != NULL_RTX)
-    process_regs_for_copy (SET_DEST (set), SET_SRC (set), false, insn, freq);
-  else
+    {
+      process_regs_for_copy (SET_DEST (set), SET_SRC (set), false, insn, freq);
+      return;
+    }
+  /* Fast check of possibility of constraint or shuffle copies.  If
+     there are no dead registers, there will be no such copies.  */
+  if (! find_reg_note (insn, REG_DEAD, NULL_RTX))
+    return;
+  extract_insn (insn);
+  for (i = 0; i < recog_data.n_operands; i++)
+    bound_p[i] = false;
+  for (i = 0; i < recog_data.n_operands; i++)
     {
-      extract_insn (insn);
-      for (i = 0; i < recog_data.n_operands; i++)
-	{
-	  operand = recog_data.operand[i];
-	  if (REG_SUBREG_P (operand)
-	      && find_reg_note (insn, REG_DEAD,
-				REG_P (operand)
-				? operand : SUBREG_REG (operand)) != NULL_RTX)
-	    {
-	      str = recog_data.constraints[i];
-	      while (*str == ' ' || *str == '\t')
-		str++;
-	      bound_p = false;
-	      for (j = 0, commut_p = false; j < 2; j++, commut_p = true)
-		if ((dup = get_dup (i, commut_p)) != NULL_RTX
-		    && REG_SUBREG_P (dup)
-		    && process_regs_for_copy (operand, dup, true,
-					      NULL_RTX, freq))
-		  bound_p = true;
-	      if (bound_p)
-		continue;
-	      /* If an operand dies, prefer its hard register for the
-		 output operands by decreasing the hard register cost
-		 or creating the corresponding allocno copies.  The
-		 cost will not correspond to a real move insn cost, so
-		 make the frequency smaller.  */
-	      process_reg_shuffles (operand, i, freq < 8 ? 1 : freq / 8);
-	    }
-	}
+      operand = recog_data.operand[i];
+      if (! REG_SUBREG_P (operand))
+	continue;
+      str = recog_data.constraints[i];
+      while (*str == ' ' || *str == '\t')
+	str++;
+      for (j = 0, commut_p = false; j < 2; j++, commut_p = true)
+	if ((n = get_dup_num (i, commut_p)) >= 0)
+	  {
+	    bound_p[n] = true;
+	    dup = recog_data.operand[n];
+	    if (REG_SUBREG_P (dup)
+		&& find_reg_note (insn, REG_DEAD,
+				  REG_P (operand)
+				  ? operand
+				  : SUBREG_REG (operand)) != NULL_RTX)
+	      process_regs_for_copy (operand, dup, true, NULL_RTX, freq);
+	  }
+    }
+  for (i = 0; i < recog_data.n_operands; i++)
+    {
+      operand = recog_data.operand[i];
+      if (REG_SUBREG_P (operand)
+	  && find_reg_note (insn, REG_DEAD,
+			    REG_P (operand)
+			    ? operand : SUBREG_REG (operand)) != NULL_RTX)
+	/* If an operand dies, prefer its hard register for the output
+	   operands by decreasing the hard register cost or creating
+	   the corresponding allocno copies.  The cost will not
+	   correspond to a real move insn cost, so make the frequency
+	   smaller.  */
+	process_reg_shuffles (operand, i, freq < 8 ? 1 : freq / 8, bound_p);
     }
 }
 
@@ -685,6 +684,59 @@
   putc ('\n', file);
 }
 
+static void
+print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
+{
+  HARD_REG_SET conflicting_hard_regs;
+  ira_allocno_t conflict_a;
+  ira_allocno_conflict_iterator aci;
+  basic_block bb;
+
+  if (reg_p)
+    fprintf (file, ";; r%d", ALLOCNO_REGNO (a));
+  else
+    {
+      fprintf (file, ";; a%d(r%d,", ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
+      if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
+        fprintf (file, "b%d", bb->index);
+      else
+        fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num);
+      putc (')', file);
+    }
+  fputs (" conflicts:", file);
+  if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) != NULL)
+    FOR_EACH_ALLOCNO_CONFLICT (a, conflict_a, aci)
+      {
+        if (reg_p)
+          fprintf (file, " r%d,", ALLOCNO_REGNO (conflict_a));
+        else
+          {
+	    fprintf (file, " a%d(r%d,", ALLOCNO_NUM (conflict_a),
+		     ALLOCNO_REGNO (conflict_a));
+	    if ((bb = ALLOCNO_LOOP_TREE_NODE (conflict_a)->bb) != NULL)
+	      fprintf (file, "b%d)", bb->index);
+	    else
+	      fprintf (file, "l%d)",
+		       ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop->num);
+	  }
+      }
+  COPY_HARD_REG_SET (conflicting_hard_regs,
+		     ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
+  AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
+  AND_HARD_REG_SET (conflicting_hard_regs,
+		    reg_class_contents[ALLOCNO_COVER_CLASS (a)]);
+  print_hard_reg_set (file, "\n;;     total conflict hard regs:",
+		      conflicting_hard_regs);
+  COPY_HARD_REG_SET (conflicting_hard_regs,
+		     ALLOCNO_CONFLICT_HARD_REGS (a));
+  AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
+  AND_HARD_REG_SET (conflicting_hard_regs,
+		    reg_class_contents[ALLOCNO_COVER_CLASS (a)]);
+  print_hard_reg_set (file, ";;     conflict hard regs:",
+		      conflicting_hard_regs);
+  putc ('\n', file);
+}
+
 /* Print information about allocno or only regno (if REG_P) conflicts
    to FILE.  */
 static void
@@ -692,58 +744,9 @@
 {
   ira_allocno_t a;
   ira_allocno_iterator ai;
-  HARD_REG_SET conflicting_hard_regs;
 
   FOR_EACH_ALLOCNO (a, ai)
-    {
-      ira_allocno_t conflict_a;
-      ira_allocno_conflict_iterator aci;
-      basic_block bb;
-
-      if (reg_p)
-	fprintf (file, ";; r%d", ALLOCNO_REGNO (a));
-      else
-	{
-	  fprintf (file, ";; a%d(r%d,", ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
-	  if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
-	    fprintf (file, "b%d", bb->index);
-	  else
-	    fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num);
-	  putc (')', file);
-	}
-      fputs (" conflicts:", file);
-      if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) != NULL)
-	FOR_EACH_ALLOCNO_CONFLICT (a, conflict_a, aci)
-	  {
-	    if (reg_p)
-	      fprintf (file, " r%d,", ALLOCNO_REGNO (conflict_a));
-	    else
-	      {
-		fprintf (file, " a%d(r%d,", ALLOCNO_NUM (conflict_a),
-			 ALLOCNO_REGNO (conflict_a));
-		if ((bb = ALLOCNO_LOOP_TREE_NODE (conflict_a)->bb) != NULL)
-		  fprintf (file, "b%d)", bb->index);
-		else
-		  fprintf (file, "l%d)",
-			   ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop->num);
-	      }
-	  }
-      COPY_HARD_REG_SET (conflicting_hard_regs,
-			 ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
-      AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
-      AND_HARD_REG_SET (conflicting_hard_regs,
-			reg_class_contents[ALLOCNO_COVER_CLASS (a)]);
-      print_hard_reg_set (file, "\n;;     total conflict hard regs:",
-			  conflicting_hard_regs);
-      COPY_HARD_REG_SET (conflicting_hard_regs,
-			 ALLOCNO_CONFLICT_HARD_REGS (a));
-      AND_COMPL_HARD_REG_SET (conflicting_hard_regs, ira_no_alloc_regs);
-      AND_HARD_REG_SET (conflicting_hard_regs,
-			reg_class_contents[ALLOCNO_COVER_CLASS (a)]);
-      print_hard_reg_set (file, ";;     conflict hard regs:",
-			  conflicting_hard_regs);
-    }
-  putc ('\n', file);
+    print_allocno_conflicts (file, reg_p, a);
 }
 
 /* Print information about allocno or only regno (if REG_P) conflicts